1use acir::{
15 AcirField,
16 brillig::{BitSize, IntegerBitSize, MemoryAddress},
17};
18
19use crate::assert_usize;
20
21pub const MEMORY_ADDRESSING_BIT_SIZE: IntegerBitSize = IntegerBitSize::U32;
25
26pub const STACK_POINTER_ADDRESS: MemoryAddress = MemoryAddress::Direct(0);
30
31pub const FREE_MEMORY_POINTER_ADDRESS: MemoryAddress = MemoryAddress::Direct(1);
38
39pub mod offsets {
43 pub const ARRAY_META_COUNT: u32 = 1;
45 pub const ARRAY_ITEMS: u32 = 1;
46
47 pub const VECTOR_META_COUNT: u32 = 3;
49 pub const VECTOR_SIZE: u32 = 1;
50 pub const VECTOR_CAPACITY: u32 = 2;
51 pub const VECTOR_ITEMS: u32 = 3;
52}
53
54pub(crate) struct ArrayAddress(MemoryAddress);
59
60impl ArrayAddress {
61 pub(crate) fn items_start(&self) -> MemoryAddress {
63 self.0.offset(offsets::ARRAY_ITEMS)
64 }
65}
66
67impl From<MemoryAddress> for ArrayAddress {
68 fn from(value: MemoryAddress) -> Self {
69 Self(value)
70 }
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
79pub enum MemoryValue<F> {
80 Field(F),
81 U1(bool),
82 U8(u8),
83 U16(u16),
84 U32(u32),
85 U64(u64),
86 U128(u128),
87}
88
89#[derive(Debug, thiserror::Error)]
91pub enum MemoryTypeError {
92 #[error(
94 "Bit size for value {value_bit_size} does not match the expected bit size {expected_bit_size}"
95 )]
96 MismatchedBitSize { value_bit_size: u32, expected_bit_size: u32 },
97 #[error("Value is not an integer")]
100 NotAnInteger,
101}
102
103impl<F: std::fmt::Display> MemoryValue<F> {
104 pub fn new_field(value: F) -> Self {
106 MemoryValue::Field(value)
107 }
108
109 pub fn new_integer(value: u128, bit_size: IntegerBitSize) -> Self {
111 match bit_size {
112 IntegerBitSize::U1 => MemoryValue::U1(match value {
113 0 => false,
114 1 => true,
115 _ => panic!("{value} is out of 1 bit range"),
116 }),
117 IntegerBitSize::U8 => {
118 MemoryValue::U8(value.try_into().expect("{value} is out of 8 bits range"))
119 }
120 IntegerBitSize::U16 => {
121 MemoryValue::U16(value.try_into().expect("{value} is out of 16 bits range"))
122 }
123 IntegerBitSize::U32 => {
124 MemoryValue::U32(value.try_into().expect("{value} is out of 32 bits range"))
125 }
126 IntegerBitSize::U64 => {
127 MemoryValue::U64(value.try_into().expect("{value} is out of 64 bits range"))
128 }
129 IntegerBitSize::U128 => MemoryValue::U128(value),
130 }
131 }
132
133 pub fn bit_size(&self) -> BitSize {
134 match self {
135 MemoryValue::Field(_) => BitSize::Field,
136 MemoryValue::U1(_) => BitSize::Integer(IntegerBitSize::U1),
137 MemoryValue::U8(_) => BitSize::Integer(IntegerBitSize::U8),
138 MemoryValue::U16(_) => BitSize::Integer(IntegerBitSize::U16),
139 MemoryValue::U32(_) => BitSize::Integer(IntegerBitSize::U32),
140 MemoryValue::U64(_) => BitSize::Integer(IntegerBitSize::U64),
141 MemoryValue::U128(_) => BitSize::Integer(IntegerBitSize::U128),
142 }
143 }
144
145 pub fn to_u32(&self) -> u32 {
149 match self {
150 MemoryValue::U32(value) => *value,
151 other => panic!("value is not typed as Brillig usize: {other}"),
152 }
153 }
154}
155
156impl<F: AcirField> MemoryValue<F> {
157 pub fn new_from_field(value: F, bit_size: BitSize) -> Self {
161 if let BitSize::Integer(bit_size) = bit_size {
162 MemoryValue::new_integer(value.to_u128(), bit_size)
163 } else {
164 MemoryValue::new_field(value)
165 }
166 }
167
168 pub fn new_checked(value: F, bit_size: BitSize) -> Option<Self> {
171 if let BitSize::Integer(bit_size) = bit_size
172 && value.num_bits() > bit_size.into()
173 {
174 return None;
175 }
176
177 Some(MemoryValue::new_from_field(value, bit_size))
178 }
179
180 pub fn to_field(&self) -> F {
182 match self {
183 MemoryValue::Field(value) => *value,
184 MemoryValue::U1(value) => F::from(*value),
185 MemoryValue::U8(value) => F::from(u128::from(*value)),
186 MemoryValue::U16(value) => F::from(u128::from(*value)),
187 MemoryValue::U32(value) => F::from(u128::from(*value)),
188 MemoryValue::U64(value) => F::from(u128::from(*value)),
189 MemoryValue::U128(value) => F::from(*value),
190 }
191 }
192
193 pub fn to_u128(&self) -> Result<u128, MemoryTypeError> {
195 match self {
196 MemoryValue::Field(..) => Err(MemoryTypeError::NotAnInteger),
197 MemoryValue::U1(value) => Ok(u128::from(*value)),
198 MemoryValue::U8(value) => Ok(u128::from(*value)),
199 MemoryValue::U16(value) => Ok(u128::from(*value)),
200 MemoryValue::U32(value) => Ok(u128::from(*value)),
201 MemoryValue::U64(value) => Ok(u128::from(*value)),
202 MemoryValue::U128(value) => Ok(*value),
203 }
204 }
205
206 pub fn expect_field(self) -> Result<F, MemoryTypeError> {
208 if let MemoryValue::Field(field) = self {
209 Ok(field)
210 } else {
211 Err(MemoryTypeError::MismatchedBitSize {
212 value_bit_size: self.bit_size().to_u32::<F>(),
213 expected_bit_size: F::max_num_bits(),
214 })
215 }
216 }
217 pub(crate) fn expect_u1(self) -> Result<bool, MemoryTypeError> {
218 if let MemoryValue::U1(value) = self {
219 Ok(value)
220 } else {
221 Err(MemoryTypeError::MismatchedBitSize {
222 value_bit_size: self.bit_size().to_u32::<F>(),
223 expected_bit_size: 1,
224 })
225 }
226 }
227
228 pub(crate) fn expect_u8(self) -> Result<u8, MemoryTypeError> {
229 if let MemoryValue::U8(value) = self {
230 Ok(value)
231 } else {
232 Err(MemoryTypeError::MismatchedBitSize {
233 value_bit_size: self.bit_size().to_u32::<F>(),
234 expected_bit_size: 8,
235 })
236 }
237 }
238
239 pub(crate) fn expect_u16(self) -> Result<u16, MemoryTypeError> {
240 if let MemoryValue::U16(value) = self {
241 Ok(value)
242 } else {
243 Err(MemoryTypeError::MismatchedBitSize {
244 value_bit_size: self.bit_size().to_u32::<F>(),
245 expected_bit_size: 16,
246 })
247 }
248 }
249
250 pub(crate) fn expect_u32(self) -> Result<u32, MemoryTypeError> {
251 if let MemoryValue::U32(value) = self {
252 Ok(value)
253 } else {
254 Err(MemoryTypeError::MismatchedBitSize {
255 value_bit_size: self.bit_size().to_u32::<F>(),
256 expected_bit_size: 32,
257 })
258 }
259 }
260
261 pub(crate) fn expect_u64(self) -> Result<u64, MemoryTypeError> {
262 if let MemoryValue::U64(value) = self {
263 Ok(value)
264 } else {
265 Err(MemoryTypeError::MismatchedBitSize {
266 value_bit_size: self.bit_size().to_u32::<F>(),
267 expected_bit_size: 64,
268 })
269 }
270 }
271
272 pub(crate) fn expect_u128(self) -> Result<u128, MemoryTypeError> {
273 if let MemoryValue::U128(value) = self {
274 Ok(value)
275 } else {
276 Err(MemoryTypeError::MismatchedBitSize {
277 value_bit_size: self.bit_size().to_u32::<F>(),
278 expected_bit_size: 128,
279 })
280 }
281 }
282}
283
284impl<F: std::fmt::Display> std::fmt::Display for MemoryValue<F> {
285 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
286 match self {
287 MemoryValue::Field(value) => write!(f, "{value}: field"),
288 MemoryValue::U1(value) => write!(f, "{value}: u1"),
289 MemoryValue::U8(value) => write!(f, "{value}: u8"),
290 MemoryValue::U16(value) => write!(f, "{value}: u16"),
291 MemoryValue::U32(value) => write!(f, "{value}: u32"),
292 MemoryValue::U64(value) => write!(f, "{value}: u64"),
293 MemoryValue::U128(value) => write!(f, "{value}: u128"),
294 }
295 }
296}
297
298impl<F: AcirField> Default for MemoryValue<F> {
299 fn default() -> Self {
300 MemoryValue::new_field(F::zero())
301 }
302}
303
304impl<F: AcirField> From<bool> for MemoryValue<F> {
305 fn from(value: bool) -> Self {
306 MemoryValue::U1(value)
307 }
308}
309
310impl<F: AcirField> From<u8> for MemoryValue<F> {
311 fn from(value: u8) -> Self {
312 MemoryValue::U8(value)
313 }
314}
315
316impl<F: AcirField> From<u32> for MemoryValue<F> {
317 fn from(value: u32) -> Self {
318 MemoryValue::U32(value)
319 }
320}
321
322impl<F: AcirField> From<u64> for MemoryValue<F> {
323 fn from(value: u64) -> Self {
324 MemoryValue::U64(value)
325 }
326}
327
328impl<F: AcirField> From<u128> for MemoryValue<F> {
329 fn from(value: u128) -> Self {
330 MemoryValue::U128(value)
331 }
332}
333
334impl<F: AcirField> TryFrom<MemoryValue<F>> for bool {
335 type Error = MemoryTypeError;
336
337 fn try_from(memory_value: MemoryValue<F>) -> Result<Self, Self::Error> {
338 memory_value.expect_u1()
339 }
340}
341
342impl<F: AcirField> TryFrom<MemoryValue<F>> for u8 {
343 type Error = MemoryTypeError;
344
345 fn try_from(memory_value: MemoryValue<F>) -> Result<Self, Self::Error> {
346 memory_value.expect_u8()
347 }
348}
349
350impl<F: AcirField> TryFrom<MemoryValue<F>> for u32 {
351 type Error = MemoryTypeError;
352
353 fn try_from(memory_value: MemoryValue<F>) -> Result<Self, Self::Error> {
354 memory_value.expect_u32()
355 }
356}
357
358impl<F: AcirField> TryFrom<MemoryValue<F>> for u64 {
359 type Error = MemoryTypeError;
360
361 fn try_from(memory_value: MemoryValue<F>) -> Result<Self, Self::Error> {
362 memory_value.expect_u64()
363 }
364}
365
366impl<F: AcirField> TryFrom<MemoryValue<F>> for u128 {
367 type Error = MemoryTypeError;
368
369 fn try_from(memory_value: MemoryValue<F>) -> Result<Self, Self::Error> {
370 memory_value.expect_u128()
371 }
372}
373#[derive(Debug, Clone, PartialEq, Eq)]
387pub struct Memory<F> {
388 inner: Vec<MemoryValue<F>>,
390 stack_pointer: u32,
399}
400
401impl<F> Default for Memory<F> {
402 fn default() -> Self {
403 Self { inner: Vec::new(), stack_pointer: STACK_POINTER_ADDRESS.to_u32() }
404 }
405}
406
407impl<F: AcirField> Memory<F> {
408 fn resolve(&self, address: MemoryAddress) -> u32 {
414 match address {
415 MemoryAddress::Direct(address) => address,
416 MemoryAddress::Relative(offset) => {
417 self.stack_pointer.checked_add(offset).expect("stack pointer offset overflow")
418 }
419 }
420 }
421
422 pub fn read(&self, address: MemoryAddress) -> MemoryValue<F> {
426 let resolved_addr = assert_usize(self.resolve(address));
427 self.inner.get(resolved_addr).copied().unwrap_or_default()
428 }
429
430 pub fn read_ref(&self, ptr: MemoryAddress) -> MemoryAddress {
433 MemoryAddress::direct(self.read(ptr).to_u32())
434 }
435
436 pub fn write_ref(&mut self, ptr: MemoryAddress, address: MemoryAddress) {
438 self.write(ptr, MemoryValue::from(address.to_u32()));
439 }
440
441 pub fn read_slice(&self, address: MemoryAddress, len: usize) -> &[MemoryValue<F>] {
445 if len == 0 {
449 return &[];
450 }
451 let resolved_addr = assert_usize(self.resolve(address));
452 &self.inner[resolved_addr..(resolved_addr + len)]
453 }
454
455 pub fn write(&mut self, address: MemoryAddress, value: MemoryValue<F>) {
457 let resolved_addr = assert_usize(self.resolve(address));
458 self.resize_to_fit(resolved_addr + 1);
459 self.inner[resolved_addr] = value;
460 if address == STACK_POINTER_ADDRESS
461 && let MemoryValue::U32(sp) = value
462 {
463 self.stack_pointer = sp;
464 }
465 }
466
467 const MAX_MEMORY_SIZE: usize = i32::MAX as usize;
476
477 fn resize_to_fit(&mut self, size: usize) {
483 assert!(
484 size <= Self::MAX_MEMORY_SIZE,
485 "Memory address space exceeded: requested {size} slots, maximum is {} (i32::MAX)",
486 Self::MAX_MEMORY_SIZE
487 );
488 let new_size = std::cmp::max(self.inner.len(), size);
490 self.inner.resize(new_size, MemoryValue::default());
492 }
493
494 pub fn write_slice(&mut self, address: MemoryAddress, values: &[MemoryValue<F>]) {
496 let resolved_addr = assert_usize(self.resolve(address));
497 let end_addr = resolved_addr + values.len();
498 self.resize_to_fit(end_addr);
499 self.inner[resolved_addr..end_addr].copy_from_slice(values);
500 if address == STACK_POINTER_ADDRESS
501 && let Some(MemoryValue::U32(sp)) = values.first()
502 {
503 self.stack_pointer = *sp;
504 }
505 }
506
507 pub fn values(&self) -> &[MemoryValue<F>] {
509 &self.inner
510 }
511}
512
513#[cfg(test)]
514mod tests {
515 use super::*;
516 use acir::FieldElement;
517 use test_case::test_case;
518
519 #[test]
520 fn direct_write_and_read() {
521 let mut memory = Memory::<FieldElement>::default();
522 let addr = MemoryAddress::direct(5);
523
524 memory.write(addr, MemoryValue::U32(42));
525 assert_eq!(memory.read(addr).to_u128().unwrap(), 42);
526 }
527
528 #[test]
529 fn relative_write_and_read() {
530 let mut memory = Memory::<FieldElement>::default();
531 memory.write(MemoryAddress::direct(0), MemoryValue::U32(10));
533
534 let addr = MemoryAddress::Relative(5);
535 memory.write(addr, MemoryValue::U32(42));
536 assert_eq!(memory.read(addr).to_u128().unwrap(), 42);
537
538 let resolved_addr = memory.resolve(addr);
539 assert_eq!(resolved_addr, 15);
542 assert_eq!(memory.values()[assert_usize(resolved_addr)].to_u128().unwrap(), 42);
543 }
544
545 #[test]
546 fn memory_growth() {
547 let mut memory = Memory::<FieldElement>::default();
548 let addr = MemoryAddress::direct(10);
549
550 memory.write(addr, MemoryValue::U32(123));
551
552 let mut expected = vec![MemoryValue::default(); 10];
553 expected.push(MemoryValue::U32(123));
554
555 assert_eq!(memory.values(), &expected);
556 }
557
558 #[test]
559 fn resize_to_fit_grows_memory() {
560 let mut memory = Memory::<FieldElement>::default();
561 memory.resize_to_fit(15);
562
563 assert_eq!(memory.values().len(), 15);
564 assert!(memory.values().iter().all(|v| *v == MemoryValue::default()));
565 }
566
567 #[test]
568 fn write_and_read_slice() {
569 let mut memory = Memory::<FieldElement>::default();
570 let values: Vec<_> = (1..=5).map(MemoryValue::U32).collect();
572
573 memory.write_slice(MemoryAddress::direct(2), &values);
575 assert_eq!(
576 memory
577 .read_slice(MemoryAddress::direct(2), 3)
578 .iter()
579 .map(|v| v.to_u128().unwrap())
580 .collect::<Vec<_>>(),
581 vec![1, 2, 3]
582 );
583 assert_eq!(
584 memory
585 .read_slice(MemoryAddress::direct(5), 2)
586 .iter()
587 .map(|v| v.to_u128().unwrap())
588 .collect::<Vec<_>>(),
589 vec![4, 5]
590 );
591 let zero_field = FieldElement::zero();
592 assert_eq!(
593 memory
594 .read_slice(MemoryAddress::direct(0), 2)
595 .iter()
596 .map(|v| v.to_field())
597 .collect::<Vec<_>>(),
598 vec![zero_field, zero_field]
599 );
600 assert_eq!(
601 memory
602 .read_slice(MemoryAddress::direct(2), 5)
603 .iter()
604 .map(|v| v.to_u128().unwrap())
605 .collect::<Vec<_>>(),
606 vec![1, 2, 3, 4, 5]
607 );
608 }
609
610 #[test]
611 fn read_ref_returns_expected_address_and_reads_slice() {
612 let mut memory = Memory::<FieldElement>::default();
613
614 let heap_start = MemoryAddress::direct(10);
616 let values: Vec<_> = (1..=3).map(MemoryValue::U32).collect();
618 memory.write_slice(heap_start, &values);
619
620 let array_pointer = MemoryAddress::direct(1);
621 memory.write(array_pointer, MemoryValue::U32(10));
623
624 let array_start = memory.read_ref(array_pointer);
626 assert_eq!(array_start, MemoryAddress::direct(10));
627
628 let got_slice = memory.read_slice(array_start, 3);
630 assert_eq!(got_slice, values);
631 }
632
633 #[test]
634 fn zero_length_slice() {
635 let memory = Memory::<FieldElement>::default();
636 assert_eq!(memory.read_slice(MemoryAddress::direct(20), 0), &[]);
637 }
638
639 #[test]
640 fn read_from_non_existent_memory() {
641 let memory = Memory::<FieldElement>::default();
642 let result = memory.read(MemoryAddress::direct(20));
643 assert!(result.to_field().is_zero());
645 }
646
647 #[test]
648 #[should_panic(expected = "range end index 30 out of range for slice of length 0")]
649 fn read_vector_from_non_existent_memory() {
650 let memory = Memory::<FieldElement>::default();
651 let _ = memory.read_slice(MemoryAddress::direct(20), 10);
652 }
653
654 #[test]
655 #[should_panic(expected = "Memory address space exceeded")]
656 fn resize_to_fit_panics_when_exceeding_max_memory_size() {
657 let mut memory = Memory::<FieldElement>::default();
658 memory.resize_to_fit(Memory::<FieldElement>::MAX_MEMORY_SIZE + 1);
660 }
661
662 #[test_case(IntegerBitSize::U1, 2)]
663 #[test_case(IntegerBitSize::U8, 256)]
664 #[test_case(IntegerBitSize::U16, u128::from(u16::MAX) + 1)]
665 #[test_case(IntegerBitSize::U32, u128::from(u32::MAX) + 1)]
666 #[test_case(IntegerBitSize::U64, u128::from(u64::MAX) + 1)]
667 #[should_panic(expected = "range")]
668 fn memory_value_new_integer_out_of_range(bit_size: IntegerBitSize, value: u128) {
669 let _ = MemoryValue::<FieldElement>::new_integer(value, bit_size);
670 }
671
672 #[test]
673 #[should_panic = "stack pointer offset overflow"]
674 fn memory_resolve_overflow() {
675 let mut memory = Memory::<FieldElement>::default();
676 memory.write(STACK_POINTER_ADDRESS, MemoryValue::from(u32::MAX - 10));
677 let addr = MemoryAddress::relative(20);
678 let _wrap = memory.resolve(addr);
679 }
680}