Replace dyn Stack objects with static type parameters

This commit is contained in:
Peter McEvoy 2023-03-14 17:59:52 -04:00
parent 133a478bdc
commit 25e9798572
7 changed files with 29 additions and 29 deletions

View File

@ -144,7 +144,7 @@ impl DirectAtom {
Atom { direct: self } Atom { direct: self }
} }
pub fn as_ubig(self, _stack: &mut dyn Stack) -> UBig { pub fn as_ubig<S: Stack>(self, _stack: &mut S) -> UBig {
UBig::from(self.0) UBig::from(self.0)
} }
@ -362,7 +362,7 @@ impl IndirectAtom {
BitSlice::from_slice(self.as_slice()) BitSlice::from_slice(self.as_slice())
} }
pub fn as_ubig(&self, stack: &mut dyn Stack) -> UBig { pub fn as_ubig<S: Stack>(&self, stack: &mut S) -> UBig {
UBig::from_le_bytes_stack(stack, self.as_bytes()) UBig::from_le_bytes_stack(stack, self.as_bytes())
} }
@ -629,7 +629,7 @@ impl Atom {
} }
} }
pub fn as_ubig(self, stack: &mut dyn Stack) -> UBig { pub fn as_ubig<S: Stack>(self, stack: &mut S) -> UBig {
if self.is_indirect() { if self.is_indirect() {
unsafe { self.indirect.as_ubig(stack) } unsafe { self.indirect.as_ubig(stack) }
} else { } else {

View File

@ -531,7 +531,7 @@ impl UBig {
// given at least 2 words of extra capacity. However, this supports UBigs which have already // given at least 2 words of extra capacity. However, this supports UBigs which have already
// been expanded through other operations. // been expanded through other operations.
#[inline] #[inline]
pub fn add_stack(stack: &mut dyn Stack, lhs: UBig, rhs: UBig) -> UBig { pub fn add_stack<S: Stack>(stack: &mut S, lhs: UBig, rhs: UBig) -> UBig {
match (lhs.into_repr(), rhs.into_repr()) { match (lhs.into_repr(), rhs.into_repr()) {
(Small(word0), Small(word1)) => UBig::add_word_stack(stack, word0, word1), (Small(word0), Small(word1)) => UBig::add_word_stack(stack, word0, word1),
(Small(word0), Large(buffer1)) => UBig::add_large_word_stack(stack, buffer1, word0), (Small(word0), Large(buffer1)) => UBig::add_large_word_stack(stack, buffer1, word0),
@ -548,7 +548,7 @@ impl UBig {
/// Add two `Word`s. /// Add two `Word`s.
#[inline] #[inline]
fn add_word_stack(stack: &mut dyn Stack, a: Word, b: Word) -> UBig { fn add_word_stack<S: Stack>(stack: &mut S, a: Word, b: Word) -> UBig {
let (res, overflow) = a.overflowing_add(b); let (res, overflow) = a.overflowing_add(b);
if overflow { if overflow {
let mut buffer = Buffer::allocate_stack(stack, 2); let mut buffer = Buffer::allocate_stack(stack, 2);
@ -561,7 +561,7 @@ impl UBig {
} }
/// Add a large number to a `Word`. /// Add a large number to a `Word`.
fn add_large_word_stack(stack: &mut dyn Stack, mut buffer: Buffer, rhs: Word) -> UBig { fn add_large_word_stack<S: Stack>(stack: &mut S, mut buffer: Buffer, rhs: Word) -> UBig {
debug_assert!(buffer.len() >= 2); debug_assert!(buffer.len() >= 2);
if add::add_word_in_place(&mut buffer, rhs) { if add::add_word_in_place(&mut buffer, rhs) {
buffer.push_may_reallocate_stack(stack, 1); buffer.push_may_reallocate_stack(stack, 1);
@ -570,7 +570,7 @@ impl UBig {
} }
/// Add two large numbers. /// Add two large numbers.
fn add_large_stack(stack: &mut dyn Stack, mut buffer: Buffer, rhs: &[Word]) -> UBig { fn add_large_stack<S: Stack>(stack: &mut S, mut buffer: Buffer, rhs: &[Word]) -> UBig {
let n = buffer.len().min(rhs.len()); let n = buffer.len().min(rhs.len());
let overflow = add::add_same_len_in_place(&mut buffer[..n], &rhs[..n]); let overflow = add::add_same_len_in_place(&mut buffer[..n], &rhs[..n]);
if rhs.len() > n { if rhs.len() > n {
@ -622,7 +622,7 @@ impl UBig {
// Subtraction is always in-place // Subtraction is always in-place
#[inline] #[inline]
pub fn sub_stack(_stack: &mut dyn Stack, lhs: UBig, rhs: UBig) -> UBig { pub fn sub_stack<S: Stack>(_stack: &mut S, lhs: UBig, rhs: UBig) -> UBig {
lhs - rhs lhs - rhs
} }

View File

@ -21,7 +21,7 @@ use core::{
pub(crate) struct Buffer(ManuallyDrop<Vec<Word>>); pub(crate) struct Buffer(ManuallyDrop<Vec<Word>>);
impl Buffer { impl Buffer {
pub(crate) fn allocate_stack(stack: &mut dyn Stack, num_words: usize) -> Buffer { pub(crate) fn allocate_stack<S: Stack>(stack: &mut S, num_words: usize) -> Buffer {
if num_words > Buffer::MAX_CAPACITY { if num_words > Buffer::MAX_CAPACITY {
UBig::panic_number_too_large(); UBig::panic_number_too_large();
} }
@ -44,7 +44,7 @@ impl Buffer {
))) )))
} }
pub(crate) fn ensure_capacity_stack(&mut self, stack: &mut dyn Stack, num_words: usize) { pub(crate) fn ensure_capacity_stack<S: Stack>(&mut self, stack: &mut S, num_words: usize) {
if num_words > self.capacity() { if num_words > self.capacity() {
self.reallocate_stack(stack, num_words); self.reallocate_stack(stack, num_words);
} }
@ -69,7 +69,7 @@ impl Buffer {
// } // }
} }
fn reallocate_stack(&mut self, stack: &mut dyn Stack, num_words: usize) { fn reallocate_stack<S: Stack>(&mut self, stack: &mut S, num_words: usize) {
assert!(num_words >= self.len()); assert!(num_words >= self.len());
let mut new_buffer = Buffer::allocate_stack(stack, num_words); let mut new_buffer = Buffer::allocate_stack(stack, num_words);
new_buffer.clone_from(self); new_buffer.clone_from(self);
@ -106,7 +106,7 @@ impl Buffer {
} }
#[inline] #[inline]
pub(crate) fn push_may_reallocate_stack(&mut self, stack: &mut dyn Stack, word: Word) { pub(crate) fn push_may_reallocate_stack<S: Stack>(&mut self, stack: &mut S, word: Word) {
self.ensure_capacity_stack(stack, self.len() + 1); self.ensure_capacity_stack(stack, self.len() + 1);
self.push(word); self.push(word);
} }

View File

@ -31,7 +31,7 @@ impl Default for IBig {
impl UBig { impl UBig {
#[inline] #[inline]
pub fn from_le_bytes_stack(stack: &mut dyn Stack, bytes: &[u8]) -> UBig { pub fn from_le_bytes_stack<S: Stack>(stack: &mut S, bytes: &[u8]) -> UBig {
if bytes.len() <= WORD_BYTES { if bytes.len() <= WORD_BYTES {
// fast path // fast path
UBig::from_word(primitive::word_from_le_bytes_partial(bytes)) UBig::from_word(primitive::word_from_le_bytes_partial(bytes))
@ -40,7 +40,7 @@ impl UBig {
} }
} }
fn from_le_bytes_large_stack(stack: &mut dyn Stack, bytes: &[u8]) -> UBig { fn from_le_bytes_large_stack<S: Stack>(stack: &mut S, bytes: &[u8]) -> UBig {
debug_assert!(bytes.len() > WORD_BYTES); debug_assert!(bytes.len() > WORD_BYTES);
let mut buffer = Buffer::allocate_stack(stack, (bytes.len() - 1) / WORD_BYTES + 1); let mut buffer = Buffer::allocate_stack(stack, (bytes.len() - 1) / WORD_BYTES + 1);
let mut chunks = bytes.chunks_exact(WORD_BYTES); let mut chunks = bytes.chunks_exact(WORD_BYTES);
@ -552,7 +552,7 @@ impl TryFrom<&IBig> for UBig {
impl UBig { impl UBig {
#[inline] #[inline]
pub(crate) fn from_unsigned_stack<T>(stack: &mut dyn Stack, x: T) -> UBig pub(crate) fn from_unsigned_stack<S: Stack, T>(stack: &mut S, x: T) -> UBig
where where
T: PrimitiveUnsigned, T: PrimitiveUnsigned,
{ {

View File

@ -1279,7 +1279,7 @@ impl_div_ibig_signed!(isize);
impl UBig { impl UBig {
#[inline] #[inline]
pub fn div_stack(stack: &mut dyn Stack, lhs: UBig, rhs: UBig) -> UBig { pub fn div_stack<S: Stack>(stack: &mut S, lhs: UBig, rhs: UBig) -> UBig {
match (lhs.into_repr(), rhs.into_repr()) { match (lhs.into_repr(), rhs.into_repr()) {
(Small(word0), Small(word1)) => UBig::div_word(word0, word1), (Small(word0), Small(word1)) => UBig::div_word(word0, word1),
(Small(_), Large(_)) => UBig::from_word(0), (Small(_), Large(_)) => UBig::from_word(0),
@ -1295,7 +1295,7 @@ impl UBig {
} }
#[inline] #[inline]
pub fn rem_stack(stack: &mut dyn Stack, lhs: UBig, rhs: UBig) -> UBig { pub fn rem_stack<S: Stack>(stack: &mut S, lhs: UBig, rhs: UBig) -> UBig {
match (lhs.into_repr(), rhs.into_repr()) { match (lhs.into_repr(), rhs.into_repr()) {
(Small(word0), Small(word1)) => UBig::rem_word(word0, word1), (Small(word0), Small(word1)) => UBig::rem_word(word0, word1),
(Small(word0), Large(_)) => UBig::from_word(word0), (Small(word0), Large(_)) => UBig::from_word(word0),
@ -1311,7 +1311,7 @@ impl UBig {
} }
#[inline] #[inline]
pub fn div_rem_stack(stack: &mut dyn Stack, lhs: UBig, rhs: UBig) -> (UBig, UBig) { pub fn div_rem_stack<S: Stack>(stack: &mut S, lhs: UBig, rhs: UBig) -> (UBig, UBig) {
match (lhs.into_repr(), rhs.into_repr()) { match (lhs.into_repr(), rhs.into_repr()) {
(Small(word0), Small(word1)) => UBig::div_rem_word(word0, word1), (Small(word0), Small(word1)) => UBig::div_rem_word(word0, word1),
(Small(word0), Large(_)) => (UBig::from_word(0), UBig::from_word(word0)), (Small(word0), Large(_)) => (UBig::from_word(0), UBig::from_word(word0)),
@ -1327,14 +1327,14 @@ impl UBig {
} }
/// `lhs / rhs` /// `lhs / rhs`
fn div_large_stack(stack: &mut dyn Stack, mut lhs: Buffer, mut rhs: Buffer) -> UBig { fn div_large_stack<S: Stack>(stack: &mut S, mut lhs: Buffer, mut rhs: Buffer) -> UBig {
let _shift = UBig::div_rem_in_lhs_stack(stack, &mut lhs, &mut rhs); let _shift = UBig::div_rem_in_lhs_stack(stack, &mut lhs, &mut rhs);
lhs.erase_front(rhs.len()); lhs.erase_front(rhs.len());
lhs.into() lhs.into()
} }
/// `lhs % rhs` /// `lhs % rhs`
fn rem_large_stack(stack: &mut dyn Stack, mut lhs: Buffer, mut rhs: Buffer) -> UBig { fn rem_large_stack<S: Stack>(stack: &mut S, mut lhs: Buffer, mut rhs: Buffer) -> UBig {
let shift = UBig::div_rem_in_lhs_stack(stack, &mut lhs, &mut rhs); let shift = UBig::div_rem_in_lhs_stack(stack, &mut lhs, &mut rhs);
let n = rhs.len(); let n = rhs.len();
rhs.copy_from_slice(&lhs[..n]); rhs.copy_from_slice(&lhs[..n]);
@ -1344,8 +1344,8 @@ impl UBig {
} }
/// `(lhs / rhs, lhs % rhs)` /// `(lhs / rhs, lhs % rhs)`
fn div_rem_large_stack( fn div_rem_large_stack<S: Stack>(
stack: &mut dyn Stack, stack: &mut S,
mut lhs: Buffer, mut lhs: Buffer,
mut rhs: Buffer, mut rhs: Buffer,
) -> (UBig, UBig) { ) -> (UBig, UBig) {
@ -1361,7 +1361,7 @@ impl UBig {
/// lhs = (lhs / rhs, lhs % rhs) /// lhs = (lhs / rhs, lhs % rhs)
/// ///
/// Returns shift. /// Returns shift.
fn div_rem_in_lhs_stack(stack: &mut dyn Stack, lhs: &mut Buffer, rhs: &mut Buffer) -> u32 { fn div_rem_in_lhs_stack<S: Stack>(stack: &mut S, lhs: &mut Buffer, rhs: &mut Buffer) -> u32 {
let (shift, fast_div_rhs_top) = div::normalize_large(rhs); let (shift, fast_div_rhs_top) = div::normalize_large(rhs);
let lhs_carry = shift::shl_in_place(lhs, shift); let lhs_carry = shift::shl_in_place(lhs, shift);
if lhs_carry != 0 { if lhs_carry != 0 {

View File

@ -9,7 +9,7 @@ pub(crate) struct MemoryAllocation {
start: *mut u8, start: *mut u8,
} }
pub trait Stack { pub trait Stack: Sized {
unsafe fn alloc_layout(&mut self, layout: Layout) -> *mut u64; unsafe fn alloc_layout(&mut self, layout: Layout) -> *mut u64;
} }
@ -24,7 +24,7 @@ pub(crate) struct Memory<'a> {
} }
impl MemoryAllocation { impl MemoryAllocation {
pub(crate) fn new_stack(stack: &mut dyn Stack, layout: Layout) -> MemoryAllocation { pub(crate) fn new_stack<S: Stack>(stack: &mut S, layout: Layout) -> MemoryAllocation {
let start = if layout.size() == 0 { let start = if layout.size() == 0 {
// We should use layout.dangling(), but that is unstable. // We should use layout.dangling(), but that is unstable.
layout.align() as *mut u8 layout.align() as *mut u8

View File

@ -300,7 +300,7 @@ impl_mul_ibig_primitive!(isize);
impl UBig { impl UBig {
#[inline] #[inline]
pub fn mul_stack(stack: &mut dyn Stack, lhs: UBig, rhs: UBig) -> UBig { pub fn mul_stack<S: Stack>(stack: &mut S, lhs: UBig, rhs: UBig) -> UBig {
match (lhs.into_repr(), rhs.into_repr()) { match (lhs.into_repr(), rhs.into_repr()) {
(Small(word0), Small(word1)) => UBig::mul_word_stack(stack, word0, word1), (Small(word0), Small(word1)) => UBig::mul_word_stack(stack, word0, word1),
(Small(word0), Large(buffer1)) => UBig::mul_large_word_stack(stack, buffer1, word0), (Small(word0), Large(buffer1)) => UBig::mul_large_word_stack(stack, buffer1, word0),
@ -310,11 +310,11 @@ impl UBig {
} }
#[inline] #[inline]
fn mul_word_stack(stack: &mut dyn Stack, a: Word, b: Word) -> UBig { fn mul_word_stack<S: Stack>(stack: &mut S, a: Word, b: Word) -> UBig {
UBig::from_unsigned_stack(stack, extend_word(a) * extend_word(b)) UBig::from_unsigned_stack(stack, extend_word(a) * extend_word(b))
} }
fn mul_large_word_stack(stack: &mut dyn Stack, mut buffer: Buffer, a: Word) -> UBig { fn mul_large_word_stack<S: Stack>(stack: &mut S, mut buffer: Buffer, a: Word) -> UBig {
match a { match a {
0 => UBig::from_word(0), 0 => UBig::from_word(0),
1 => buffer.into(), 1 => buffer.into(),
@ -328,7 +328,7 @@ impl UBig {
} }
} }
pub fn mul_large_stack(stack: &mut dyn Stack, lhs: &[Word], rhs: &[Word]) -> UBig { pub fn mul_large_stack<S: Stack>(stack: &mut S, lhs: &[Word], rhs: &[Word]) -> UBig {
debug_assert!(lhs.len() >= 2 && rhs.len() >= 2); debug_assert!(lhs.len() >= 2 && rhs.len() >= 2);
// This may be 1 too large. // This may be 1 too large.