diff --git a/.aztec-sync-commit b/.aztec-sync-commit index a9f74612f46..c82e80ca7e5 100644 --- a/.aztec-sync-commit +++ b/.aztec-sync-commit @@ -1 +1 @@ -05cc59fd28b4d0ee89343106e538c0db0e70f52f +ae863471fed30ea3382aea8223d7ddf8e9eef4ee diff --git a/acvm-repo/acir/codegen/acir.cpp b/acvm-repo/acir/codegen/acir.cpp index 0ccf7e4639d..ef5baf076a0 100644 --- a/acvm-repo/acir/codegen/acir.cpp +++ b/acvm-repo/acir/codegen/acir.cpp @@ -610,8 +610,8 @@ namespace Program { struct CalldataCopy { Program::MemoryAddress destination_address; - uint64_t size; - uint64_t offset; + Program::MemoryAddress size_address; + Program::MemoryAddress offset_address; friend bool operator==(const CalldataCopy&, const CalldataCopy&); std::vector bincodeSerialize() const; @@ -5278,8 +5278,8 @@ namespace Program { inline bool operator==(const BrilligOpcode::CalldataCopy &lhs, const BrilligOpcode::CalldataCopy &rhs) { if (!(lhs.destination_address == rhs.destination_address)) { return false; } - if (!(lhs.size == rhs.size)) { return false; } - if (!(lhs.offset == rhs.offset)) { return false; } + if (!(lhs.size_address == rhs.size_address)) { return false; } + if (!(lhs.offset_address == rhs.offset_address)) { return false; } return true; } @@ -5304,8 +5304,8 @@ template <> template void serde::Serializable::serialize(const Program::BrilligOpcode::CalldataCopy &obj, Serializer &serializer) { serde::Serializable::serialize(obj.destination_address, serializer); - serde::Serializable::serialize(obj.size, serializer); - serde::Serializable::serialize(obj.offset, serializer); + serde::Serializable::serialize(obj.size_address, serializer); + serde::Serializable::serialize(obj.offset_address, serializer); } template <> @@ -5313,8 +5313,8 @@ template Program::BrilligOpcode::CalldataCopy serde::Deserializable::deserialize(Deserializer &deserializer) { Program::BrilligOpcode::CalldataCopy obj; obj.destination_address = serde::Deserializable::deserialize(deserializer); - obj.size = serde::Deserializable::deserialize(deserializer); - obj.offset = serde::Deserializable::deserialize(deserializer); + obj.size_address = serde::Deserializable::deserialize(deserializer); + obj.offset_address = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs index 7bed57e22a0..838886a03ce 100644 --- a/acvm-repo/acir/tests/test_program_serialization.rs +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -164,10 +164,20 @@ fn simple_brillig_foreign_call() { let brillig_bytecode = BrilligBytecode { bytecode: vec![ + brillig::Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(1_usize), + }, + brillig::Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0_usize), + }, brillig::Opcode::CalldataCopy { destination_address: MemoryAddress(0), - size: 1, - offset: 0, + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, brillig::Opcode::ForeignCall { function: "invert".into(), @@ -204,11 +214,12 @@ fn simple_brillig_foreign_call() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 80, 49, 10, 192, 32, 12, 52, 45, 45, 133, 110, 190, - 68, 127, 224, 103, 28, 92, 28, 68, 124, 191, 130, 9, 4, 137, 46, 122, 16, 46, 119, 7, 33, - 9, 168, 142, 175, 21, 96, 255, 32, 147, 230, 32, 207, 33, 155, 61, 88, 56, 55, 203, 240, - 125, 175, 177, 1, 110, 170, 197, 101, 55, 242, 43, 100, 132, 159, 229, 33, 22, 159, 242, - 234, 87, 51, 45, 121, 90, 200, 42, 48, 209, 35, 111, 164, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 49, 10, 128, 48, 12, 108, 196, 138, 224, 230, + 75, 226, 15, 252, 140, 131, 139, 131, 136, 239, 111, 161, 9, 28, 165, 205, 210, 28, 132, + 36, 119, 16, 114, 9, 133, 130, 53, 7, 73, 29, 37, 107, 143, 80, 238, 148, 204, 99, 56, 200, + 111, 22, 227, 190, 83, 93, 16, 146, 193, 112, 22, 225, 34, 168, 205, 142, 174, 241, 218, + 206, 179, 121, 49, 188, 109, 57, 84, 191, 159, 255, 122, 63, 235, 199, 189, 190, 197, 237, + 13, 45, 1, 20, 245, 146, 30, 92, 2, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -230,20 +241,40 @@ fn complex_brillig_foreign_call() { let brillig_bytecode = BrilligBytecode { bytecode: vec![ + brillig::Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(3_usize), + }, + brillig::Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0_usize), + }, brillig::Opcode::CalldataCopy { destination_address: MemoryAddress(32), - size: 3, - offset: 0, + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, brillig::Opcode::Const { destination: MemoryAddress(0), value: FieldElement::from(32_usize), bit_size: BitSize::Integer(IntegerBitSize::U32), }, + brillig::Opcode::Const { + destination: MemoryAddress(3), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(1_usize), + }, + brillig::Opcode::Const { + destination: MemoryAddress(4), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(3_usize), + }, brillig::Opcode::CalldataCopy { destination_address: MemoryAddress(1), - size: 1, - offset: 3, + size_address: MemoryAddress(3), + offset_address: MemoryAddress(4), }, // Oracles are named 'foreign calls' in brillig brillig::Opcode::ForeignCall { @@ -307,15 +338,17 @@ fn complex_brillig_foreign_call() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 84, 75, 10, 132, 48, 12, 77, 90, 199, 17, 102, 55, - 39, 24, 152, 57, 64, 199, 19, 120, 23, 113, 167, 232, 210, 227, 107, 49, 98, 124, 22, 92, - 88, 65, 31, 148, 244, 147, 207, 75, 66, 202, 52, 33, 27, 23, 203, 254, 33, 210, 136, 244, - 247, 150, 214, 152, 117, 11, 145, 238, 24, 254, 28, 207, 151, 59, 139, 163, 185, 1, 71, - 123, 2, 71, 82, 253, 191, 96, 191, 99, 246, 37, 106, 253, 108, 96, 126, 18, 154, 230, 43, - 149, 243, 83, 100, 134, 133, 246, 70, 134, 182, 131, 183, 2, 78, 172, 247, 250, 1, 71, 132, - 17, 196, 46, 137, 150, 105, 238, 82, 197, 133, 33, 254, 75, 101, 89, 182, 77, 87, 87, 189, - 5, 85, 164, 251, 85, 251, 31, 188, 51, 216, 161, 173, 134, 254, 192, 66, 186, 28, 208, 219, - 243, 253, 166, 165, 196, 115, 217, 7, 253, 216, 100, 109, 69, 5, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 81, 14, 194, 48, 8, 133, 118, 206, 26, 255, 60, + 129, 137, 30, 160, 211, 11, 120, 23, 227, 159, 70, 63, 61, 190, 146, 209, 140, 177, 46, + 251, 24, 77, 182, 151, 44, 116, 45, 16, 120, 64, 139, 208, 34, 252, 63, 228, 245, 134, 165, + 99, 73, 251, 30, 250, 72, 186, 55, 150, 113, 30, 26, 180, 243, 21, 75, 197, 232, 86, 16, + 163, 47, 16, 35, 136, 250, 47, 176, 222, 150, 117, 49, 229, 207, 103, 230, 167, 130, 118, + 190, 106, 254, 223, 178, 12, 154, 104, 50, 114, 48, 28, 188, 30, 82, 247, 236, 180, 23, 62, + 171, 236, 178, 185, 202, 27, 194, 216, 119, 36, 54, 142, 35, 185, 149, 203, 233, 18, 131, + 34, 220, 48, 167, 38, 176, 191, 18, 181, 168, 5, 63, 178, 179, 8, 123, 232, 186, 234, 254, + 126, 125, 158, 143, 175, 87, 148, 74, 51, 194, 73, 172, 207, 234, 28, 149, 157, 182, 149, + 144, 15, 70, 78, 23, 51, 122, 83, 190, 15, 208, 181, 70, 122, 152, 126, 56, 83, 244, 10, + 181, 6, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/acvm-repo/acvm/tests/solver.rs b/acvm-repo/acvm/tests/solver.rs index 2a06e07f092..cd25ed6197b 100644 --- a/acvm-repo/acvm/tests/solver.rs +++ b/acvm-repo/acvm/tests/solver.rs @@ -1,6 +1,7 @@ use std::collections::{BTreeMap, HashSet}; use std::sync::Arc; +use acir::brillig::{BitSize, IntegerBitSize}; use acir::{ acir_field::GenericFieldElement, brillig::{BinaryFieldOp, HeapArray, MemoryAddress, Opcode as BrilligOpcode, ValueOrArray}, @@ -122,10 +123,20 @@ fn inversion_brillig_oracle_equivalence() { let brillig_bytecode = BrilligBytecode { bytecode: vec![ + BrilligOpcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(2u64), + }, + BrilligOpcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, BrilligOpcode::CalldataCopy { destination_address: MemoryAddress(0), - size: 2, - offset: 0, + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, equal_opcode, // Oracles are named 'foreign calls' in brillig @@ -258,10 +269,20 @@ fn double_inversion_brillig_oracle() { let brillig_bytecode = BrilligBytecode { bytecode: vec![ + BrilligOpcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(3u64), + }, + BrilligOpcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, BrilligOpcode::CalldataCopy { destination_address: MemoryAddress(0), - size: 3, - offset: 0, + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, equal_opcode, // Oracles are named 'foreign calls' in brillig @@ -366,12 +387,21 @@ fn oracle_dependent_execution() { let brillig_bytecode = BrilligBytecode { bytecode: vec![ + BrilligOpcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(3u64), + }, + BrilligOpcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, BrilligOpcode::CalldataCopy { destination_address: MemoryAddress(0), - size: 3, - offset: 0, - }, - // Oracles are named 'foreign calls' in brillig + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), + }, // Oracles are named 'foreign calls' in brillig BrilligOpcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(1))], @@ -498,10 +528,20 @@ fn brillig_oracle_predicate() { let brillig_bytecode = BrilligBytecode { bytecode: vec![ + BrilligOpcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(2u64), + }, + BrilligOpcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, BrilligOpcode::CalldataCopy { destination_address: MemoryAddress(0), - size: 2, - offset: 0, + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, equal_opcode, // Oracles are named 'foreign calls' in brillig @@ -607,8 +647,11 @@ fn unsatisfied_opcode_resolved_brillig() { let w_y = Witness(5); let w_result = Witness(6); - let calldata_copy_opcode = - BrilligOpcode::CalldataCopy { destination_address: MemoryAddress(0), size: 2, offset: 0 }; + let calldata_copy_opcode = BrilligOpcode::CalldataCopy { + destination_address: MemoryAddress(0), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), + }; let equal_opcode = BrilligOpcode::BinaryFieldOp { op: BinaryFieldOp::Equals, @@ -627,7 +670,23 @@ fn unsatisfied_opcode_resolved_brillig() { let stop_opcode = BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 0 }; let brillig_bytecode = BrilligBytecode { - bytecode: vec![calldata_copy_opcode, equal_opcode, jmp_if_opcode, trap_opcode, stop_opcode], + bytecode: vec![ + BrilligOpcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(2u64), + }, + BrilligOpcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, + calldata_copy_opcode, + equal_opcode, + jmp_if_opcode, + trap_opcode, + stop_opcode, + ], }; let opcode_a = Expression { @@ -679,7 +738,7 @@ fn unsatisfied_opcode_resolved_brillig() { ACVMStatus::Failure(OpcodeResolutionError::BrilligFunctionFailed { function_id: BrilligFunctionId(0), payload: None, - call_stack: vec![OpcodeLocation::Brillig { acir_index: 0, brillig_index: 3 }] + call_stack: vec![OpcodeLocation::Brillig { acir_index: 0, brillig_index: 5 }] }), "The first opcode is not satisfiable, expected an error indicating this" ); diff --git a/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts b/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts index 53597ece157..ba26e3d139a 100644 --- a/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts +++ b/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts @@ -2,13 +2,14 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `complex_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 84, 75, 10, 132, 48, 12, 77, 90, 199, 17, 102, 55, 39, 24, 152, 57, 64, 199, - 19, 120, 23, 113, 167, 232, 210, 227, 107, 49, 98, 124, 22, 92, 88, 65, 31, 148, 244, 147, 207, 75, 66, 202, 52, 33, - 27, 23, 203, 254, 33, 210, 136, 244, 247, 150, 214, 152, 117, 11, 145, 238, 24, 254, 28, 207, 151, 59, 139, 163, 185, - 1, 71, 123, 2, 71, 82, 253, 191, 96, 191, 99, 246, 37, 106, 253, 108, 96, 126, 18, 154, 230, 43, 149, 243, 83, 100, - 134, 133, 246, 70, 134, 182, 131, 183, 2, 78, 172, 247, 250, 1, 71, 132, 17, 196, 46, 137, 150, 105, 238, 82, 197, - 133, 33, 254, 75, 101, 89, 182, 77, 87, 87, 189, 5, 85, 164, 251, 85, 251, 31, 188, 51, 216, 161, 173, 134, 254, 192, - 66, 186, 28, 208, 219, 243, 253, 166, 165, 196, 115, 217, 7, 253, 216, 100, 109, 69, 5, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 85, 81, 14, 194, 48, 8, 133, 118, 206, 26, 255, 60, 129, 137, 30, 160, 211, + 11, 120, 23, 227, 159, 70, 63, 61, 190, 146, 209, 140, 177, 46, 251, 24, 77, 182, 151, 44, 116, 45, 16, 120, 64, 139, + 208, 34, 252, 63, 228, 245, 134, 165, 99, 73, 251, 30, 250, 72, 186, 55, 150, 113, 30, 26, 180, 243, 21, 75, 197, 232, + 86, 16, 163, 47, 16, 35, 136, 250, 47, 176, 222, 150, 117, 49, 229, 207, 103, 230, 167, 130, 118, 190, 106, 254, 223, + 178, 12, 154, 104, 50, 114, 48, 28, 188, 30, 82, 247, 236, 180, 23, 62, 171, 236, 178, 185, 202, 27, 194, 216, 119, + 36, 54, 142, 35, 185, 149, 203, 233, 18, 131, 34, 220, 48, 167, 38, 176, 191, 18, 181, 168, 5, 63, 178, 179, 8, 123, + 232, 186, 234, 254, 126, 125, 158, 143, 175, 87, 148, 74, 51, 194, 73, 172, 207, 234, 28, 149, 157, 182, 149, 144, 15, + 70, 78, 23, 51, 122, 83, 190, 15, 208, 181, 70, 122, 152, 126, 56, 83, 244, 10, 181, 6, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/acvm-repo/acvm_js/test/shared/foreign_call.ts b/acvm-repo/acvm_js/test/shared/foreign_call.ts index 3500e03776d..498a914cff4 100644 --- a/acvm-repo/acvm_js/test/shared/foreign_call.ts +++ b/acvm-repo/acvm_js/test/shared/foreign_call.ts @@ -2,10 +2,11 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `simple_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 80, 49, 10, 192, 32, 12, 52, 45, 45, 133, 110, 190, 68, 127, 224, 103, 28, 92, - 28, 68, 124, 191, 130, 9, 4, 137, 46, 122, 16, 46, 119, 7, 33, 9, 168, 142, 175, 21, 96, 255, 32, 147, 230, 32, 207, - 33, 155, 61, 88, 56, 55, 203, 240, 125, 175, 177, 1, 110, 170, 197, 101, 55, 242, 43, 100, 132, 159, 229, 33, 22, 159, - 242, 234, 87, 51, 45, 121, 90, 200, 42, 48, 209, 35, 111, 164, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 81, 49, 10, 128, 48, 12, 108, 196, 138, 224, 230, 75, 226, 15, 252, 140, 131, + 139, 131, 136, 239, 111, 161, 9, 28, 165, 205, 210, 28, 132, 36, 119, 16, 114, 9, 133, 130, 53, 7, 73, 29, 37, 107, + 143, 80, 238, 148, 204, 99, 56, 200, 111, 22, 227, 190, 83, 93, 16, 146, 193, 112, 22, 225, 34, 168, 205, 142, 174, + 241, 218, 206, 179, 121, 49, 188, 109, 57, 84, 191, 159, 255, 122, 63, 235, 199, 189, 190, 197, 237, 13, 45, 1, 20, + 245, 146, 30, 92, 2, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000005'], diff --git a/acvm-repo/brillig/src/opcodes.rs b/acvm-repo/brillig/src/opcodes.rs index 2054a34d459..ac469cebf87 100644 --- a/acvm-repo/brillig/src/opcodes.rs +++ b/acvm-repo/brillig/src/opcodes.rs @@ -210,8 +210,8 @@ pub enum BrilligOpcode { /// Copies calldata after the offset to the specified address and length CalldataCopy { destination_address: MemoryAddress, - size: usize, - offset: usize, + size_address: MemoryAddress, + offset_address: MemoryAddress, }, /// We don't support dynamic jumps or calls /// See https://github.com/ethereum/aleth/issues/3404 for reasoning diff --git a/acvm-repo/brillig_vm/src/lib.rs b/acvm-repo/brillig_vm/src/lib.rs index 5097ecf4707..2c2ab17230f 100644 --- a/acvm-repo/brillig_vm/src/lib.rs +++ b/acvm-repo/brillig_vm/src/lib.rs @@ -236,8 +236,10 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> VM<'a, F, B> { } self.set_program_counter(*destination) } - Opcode::CalldataCopy { destination_address, size, offset } => { - let values: Vec<_> = self.calldata[*offset..(*offset + size)] + Opcode::CalldataCopy { destination_address, size_address, offset_address } => { + let size = self.memory.read(*size_address).to_usize(); + let offset = self.memory.read(*offset_address).to_usize(); + let values: Vec<_> = self.calldata[offset..(offset + size)] .iter() .map(|value| MemoryValue::new_field(*value)) .collect(); @@ -754,24 +756,17 @@ mod tests { #[test] fn add_single_step_smoke() { - let calldata = vec![FieldElement::from(27u128)]; - - // Add opcode to add the value in address `0` and `1` - // and place the output in address `2` - let calldata_copy = Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: 1, - offset: 0, - }; + let calldata = vec![]; + + let opcodes = [Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(27u128), + }]; // Start VM - let opcodes = [calldata_copy]; let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); - // Process a single VM opcode - // - // After processing a single opcode, we should have - // the vm status as finished since there is only one opcode let status = vm.process_opcode(); assert_eq!(status, VMStatus::Finished { return_data_offset: 0, return_data_size: 0 }); @@ -786,7 +781,6 @@ mod tests { #[test] fn jmpif_opcode() { let mut calldata: Vec = vec![]; - let mut opcodes = vec![]; let lhs = { calldata.push(2u128.into()); @@ -800,21 +794,35 @@ mod tests { let destination = MemoryAddress::from(calldata.len()); - opcodes.push(Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: 2, - offset: 0, - }); - - opcodes.push(Opcode::BinaryFieldOp { destination, op: BinaryFieldOp::Equals, lhs, rhs }); - opcodes.push(Opcode::Jump { location: 3 }); - opcodes.push(Opcode::JumpIf { condition: destination, location: 4 }); + let opcodes = vec![ + Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(2u64), + }, + Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, + Opcode::CalldataCopy { + destination_address: MemoryAddress(0), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), + }, + Opcode::BinaryFieldOp { destination, op: BinaryFieldOp::Equals, lhs, rhs }, + Opcode::Jump { location: 5 }, + Opcode::JumpIf { condition: destination, location: 6 }, + ]; let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -832,48 +840,49 @@ mod tests { fn jmpifnot_opcode() { let calldata: Vec = vec![1u128.into(), 2u128.into()]; - let calldata_copy = Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: 2, - offset: 0, - }; - - let jump_opcode = Opcode::Jump { location: 3 }; - - let trap_opcode = Opcode::Trap { revert_data: HeapArray::default() }; - - let not_equal_cmp_opcode = Opcode::BinaryFieldOp { - op: BinaryFieldOp::Equals, - lhs: MemoryAddress::from(0), - rhs: MemoryAddress::from(1), - destination: MemoryAddress::from(2), - }; - - let jump_if_not_opcode = - Opcode::JumpIfNot { condition: MemoryAddress::from(2), location: 2 }; - - let add_opcode = Opcode::BinaryFieldOp { - op: BinaryFieldOp::Add, - lhs: MemoryAddress::from(0), - rhs: MemoryAddress::from(1), - destination: MemoryAddress::from(2), - }; - - let opcodes = [ - calldata_copy, - jump_opcode, - trap_opcode, - not_equal_cmp_opcode, - jump_if_not_opcode, - add_opcode, + let opcodes = vec![ + Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(2u64), + }, + Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, + Opcode::CalldataCopy { + destination_address: MemoryAddress(0), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), + }, + Opcode::Jump { location: 5 }, + Opcode::Trap { revert_data: HeapArray::default() }, + Opcode::BinaryFieldOp { + op: BinaryFieldOp::Equals, + lhs: MemoryAddress::from(0), + rhs: MemoryAddress::from(1), + destination: MemoryAddress::from(2), + }, + Opcode::JumpIfNot { condition: MemoryAddress::from(2), location: 4 }, + Opcode::BinaryFieldOp { + op: BinaryFieldOp::Add, + lhs: MemoryAddress::from(0), + rhs: MemoryAddress::from(1), + destination: MemoryAddress::from(2), + }, ]; + let mut vm = VM::new(calldata, &opcodes, vec![], &StubbedBlackBoxSolver); + + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); @@ -888,7 +897,7 @@ mod tests { status, VMStatus::Failure { reason: FailureReason::Trap { revert_data_offset: 0, revert_data_size: 0 }, - call_stack: vec![2] + call_stack: vec![4] } ); @@ -903,10 +912,20 @@ mod tests { let calldata: Vec = vec![((2_u128.pow(32)) - 1).into()]; let opcodes = &[ + Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(1u64), + }, + Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: 1, - offset: 0, + destination_address: MemoryAddress(0), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, Opcode::Cast { destination: MemoryAddress::from(1), @@ -919,10 +938,12 @@ mod tests { let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); let status = vm.process_opcode(); assert_eq!(status, VMStatus::Finished { return_data_offset: 1, return_data_size: 1 }); @@ -936,22 +957,34 @@ mod tests { fn mov_opcode() { let calldata: Vec = vec![(1u128).into(), (2u128).into(), (3u128).into()]; - let calldata_copy = Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: 3, - offset: 0, - }; - - let mov_opcode = - Opcode::Mov { destination: MemoryAddress::from(2), source: MemoryAddress::from(0) }; - - let opcodes = &[calldata_copy, mov_opcode]; + let opcodes = &[ + Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(3u64), + }, + Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, + Opcode::CalldataCopy { + destination_address: MemoryAddress(0), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), + }, + Opcode::Mov { destination: MemoryAddress::from(2), source: MemoryAddress::from(0) }, + ]; let mut vm = VM::new(calldata, opcodes, vec![], &StubbedBlackBoxSolver); let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::Finished { return_data_offset: 0, return_data_size: 0 }); let VM { memory, .. } = vm; @@ -968,28 +1001,32 @@ mod tests { let calldata: Vec = vec![(0u128).into(), (1u128).into(), (2u128).into(), (3u128).into()]; - let calldata_copy = Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: 4, - offset: 0, - }; - - let cast_zero = Opcode::Cast { - destination: MemoryAddress::from(0), - source: MemoryAddress::from(0), - bit_size: BitSize::Integer(IntegerBitSize::U1), - }; - - let cast_one = Opcode::Cast { - destination: MemoryAddress::from(1), - source: MemoryAddress::from(1), - bit_size: BitSize::Integer(IntegerBitSize::U1), - }; - let opcodes = &[ - calldata_copy, - cast_zero, - cast_one, + Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(4u64), + }, + Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, + Opcode::CalldataCopy { + destination_address: MemoryAddress(0), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), + }, + Opcode::Cast { + destination: MemoryAddress::from(0), + source: MemoryAddress::from(0), + bit_size: BitSize::Integer(IntegerBitSize::U1), + }, + Opcode::Cast { + destination: MemoryAddress::from(1), + source: MemoryAddress::from(1), + bit_size: BitSize::Integer(IntegerBitSize::U1), + }, Opcode::ConditionalMov { destination: MemoryAddress(4), // Sets 3_u128 to memory address 4 source_a: MemoryAddress(2), @@ -1007,16 +1044,16 @@ mod tests { let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); - + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); let status = vm.process_opcode(); assert_eq!(status, VMStatus::Finished { return_data_offset: 0, return_data_size: 0 }); @@ -1036,11 +1073,23 @@ mod tests { vec![(2u128).into(), (2u128).into(), (0u128).into(), (5u128).into(), (6u128).into()]; let calldata_size = calldata.len(); - let calldata_copy = Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: 5, - offset: 0, - }; + let calldata_copy_opcodes = vec![ + Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(5u64), + }, + Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, + Opcode::CalldataCopy { + destination_address: MemoryAddress(0), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), + }, + ]; let cast_opcodes: Vec<_> = (0..calldata_size) .map(|index| Opcode::Cast { @@ -1082,7 +1131,8 @@ mod tests { destination: MemoryAddress::from(2), }; - let opcodes: Vec<_> = std::iter::once(calldata_copy) + let opcodes: Vec<_> = calldata_copy_opcodes + .into_iter() .chain(cast_opcodes) .chain([equal_opcode, not_equal_opcode, less_than_opcode, less_than_equal_opcode]) .collect(); @@ -1091,6 +1141,10 @@ mod tests { // Calldata copy let status = vm.process_opcode(); assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); + let status = vm.process_opcode(); + assert_eq!(status, VMStatus::InProgress); for _ in 0..calldata_size { let status = vm.process_opcode(); @@ -1242,7 +1296,7 @@ mod tests { let r_tmp = MemoryAddress::from(3); let r_pointer = MemoryAddress::from(4); - let start: [Opcode; 5] = [ + let start = [ // sum = 0 Opcode::Const { destination: r_sum, value: 0u128.into(), bit_size: BitSize::Field }, // i = 0 @@ -1263,10 +1317,20 @@ mod tests { value: 5u128.into(), bit_size: BitSize::Integer(bit_size), }, + Opcode::Const { + destination: MemoryAddress(100), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(memory.len() as u32), + }, + Opcode::Const { + destination: MemoryAddress(101), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, Opcode::CalldataCopy { destination_address: MemoryAddress(5), - size: memory.len(), - offset: 0, + size_address: MemoryAddress(100), + offset_address: MemoryAddress(101), }, ]; let loop_body = [ @@ -1359,8 +1423,8 @@ mod tests { Opcode::Const { destination: r_pointer, value: 4u128.into(), bit_size }, // call recursive_fn Opcode::Call { - location: 5, // Call after 'start' - }, + location: 5, // Call after 'start' + }, // end program by jumping to end Opcode::Jump { location: 100 }, ]; @@ -1510,10 +1574,20 @@ mod tests { vec![(1u128).into(), (3u128).into(), (2u128).into(), (4u128).into()]; let invert_program = vec![ + Opcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(initial_matrix.len() as u32), + }, + Opcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, Opcode::CalldataCopy { - destination_address: MemoryAddress::from(2), - size: initial_matrix.len(), - offset: 0, + destination_address: MemoryAddress(2), + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, // input = 0 Opcode::Const { @@ -1600,10 +1674,20 @@ mod tests { // First call: let string_double_program = vec![ + Opcode::Const { + destination: MemoryAddress(100), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(input_string.len() as u32), + }, + Opcode::Const { + destination: MemoryAddress(101), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, Opcode::CalldataCopy { destination_address: MemoryAddress(4), - size: input_string.len(), - offset: 0, + size_address: MemoryAddress(100), + offset_address: MemoryAddress(101), }, // input_pointer = 4 Opcode::Const { @@ -1698,10 +1782,20 @@ mod tests { vec![(1u128).into(), (3u128).into(), (2u128).into(), (4u128).into()]; let invert_program = vec![ + Opcode::Const { + destination: MemoryAddress(100), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(initial_matrix.len() as u32), + }, + Opcode::Const { + destination: MemoryAddress(101), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, Opcode::CalldataCopy { - destination_address: MemoryAddress::from(2), - size: initial_matrix.len(), - offset: 0, + destination_address: MemoryAddress(2), + size_address: MemoryAddress(100), + offset_address: MemoryAddress(101), }, // input = 0 Opcode::Const { @@ -1797,10 +1891,20 @@ mod tests { vec![(34u128).into(), (37u128).into(), (78u128).into(), (85u128).into()]; let matrix_mul_program = vec![ + Opcode::Const { + destination: MemoryAddress(100), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(matrix_a.len() + matrix_b.len()), + }, + Opcode::Const { + destination: MemoryAddress(101), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, Opcode::CalldataCopy { - destination_address: MemoryAddress::from(3), - size: matrix_a.len() + matrix_b.len(), - offset: 0, + destination_address: MemoryAddress(3), + size_address: MemoryAddress(100), + offset_address: MemoryAddress(101), }, // input = 3 Opcode::Const { @@ -1944,11 +2048,24 @@ mod tests { let r_input = MemoryAddress::from(r_ptr); let r_output = MemoryAddress::from(r_ptr + 1); - let program: Vec<_> = std::iter::once(Opcode::CalldataCopy { - destination_address: MemoryAddress::from(0), - size: memory.len(), - offset: 0, - }) + let program: Vec<_> = vec![ + Opcode::Const { + destination: MemoryAddress(100), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(memory.len()), + }, + Opcode::Const { + destination: MemoryAddress(101), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, + Opcode::CalldataCopy { + destination_address: MemoryAddress(0), + size_address: MemoryAddress(100), + offset_address: MemoryAddress(101), + }, + ] + .into_iter() .chain(memory.iter().enumerate().map(|(index, mem_value)| Opcode::Cast { destination: MemoryAddress(index), source: MemoryAddress(index), diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs index c17088a5d8c..faf4242a9ca 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs @@ -1,5 +1,5 @@ use acvm::acir::{ - brillig::{BinaryFieldOp, BitSize, MemoryAddress, Opcode as BrilligOpcode}, + brillig::{BinaryFieldOp, BitSize, IntegerBitSize, MemoryAddress, Opcode as BrilligOpcode}, AcirField, }; @@ -19,11 +19,25 @@ pub(crate) fn directive_invert() -> GeneratedBrillig { let zero_const = MemoryAddress::from(2); let input_is_zero = MemoryAddress::from(3); // Location of the stop opcode - let stop_location = 6; + let stop_location = 8; GeneratedBrillig { byte_code: vec![ - BrilligOpcode::CalldataCopy { destination_address: input, size: 1, offset: 0 }, + BrilligOpcode::Const { + destination: MemoryAddress(20), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: F::from(1_usize), + }, + BrilligOpcode::Const { + destination: MemoryAddress::from(21), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: F::from(0_usize), + }, + BrilligOpcode::CalldataCopy { + destination_address: input, + size_address: MemoryAddress::from(20), + offset_address: MemoryAddress::from(21), + }, // Put value zero in register (2) BrilligOpcode::Const { destination: zero_const, @@ -74,10 +88,20 @@ pub(crate) fn directive_quotient() -> GeneratedBrillig { GeneratedBrillig { byte_code: vec![ + BrilligOpcode::Const { + destination: MemoryAddress::from(10), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: F::from(2_usize), + }, + BrilligOpcode::Const { + destination: MemoryAddress::from(11), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: F::from(0_usize), + }, BrilligOpcode::CalldataCopy { destination_address: MemoryAddress::from(0), - size: 2, - offset: 0, + size_address: MemoryAddress::from(10), + offset_address: MemoryAddress::from(11), }, // No cast, since calldata is typed as field by default //q = a/b is set into register (2) diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs index 5ee00cf6c29..c85940cc1c7 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs @@ -46,6 +46,9 @@ impl BrilligContext { arguments: &[BrilligParameter], return_parameters: &[BrilligParameter], ) { + // We need to allocate the variable for every argument first so any register allocation doesn't mangle the expected order. + let mut argument_variables = self.allocate_function_arguments(arguments); + let calldata_size = Self::flattened_tuple_size(arguments); let return_data_size = Self::flattened_tuple_size(return_parameters); @@ -64,75 +67,45 @@ impl BrilligContext { // Copy calldata self.copy_and_cast_calldata(arguments); - // Allocate the variables for every argument: let mut current_calldata_pointer = Self::calldata_start_offset(); - let mut argument_variables: Vec<_> = arguments - .iter() - .map(|argument| match argument { - BrilligParameter::SingleAddr(bit_size) => { - let single_address = self.allocate_register(); - let var = BrilligVariable::SingleAddr(SingleAddrVariable { - address: single_address, - bit_size: *bit_size, - }); - self.mov_instruction(single_address, MemoryAddress(current_calldata_pointer)); - current_calldata_pointer += 1; - var - } - BrilligParameter::Array(_, _) => { - let pointer_to_the_array_in_calldata = - self.make_usize_constant_instruction(current_calldata_pointer.into()); - let rc_register = self.make_usize_constant_instruction(1_usize.into()); - let flattened_size = Self::flattened_size(argument); - let var = BrilligVariable::BrilligArray(BrilligArray { - pointer: pointer_to_the_array_in_calldata.address, - size: flattened_size, - rc: rc_register.address, - }); - - current_calldata_pointer += flattened_size; - var - } - BrilligParameter::Slice(_, _) => { - let pointer_to_the_array_in_calldata = - self.make_usize_constant_instruction(current_calldata_pointer.into()); - - let flattened_size = Self::flattened_size(argument); - let size_register = self.make_usize_constant_instruction(flattened_size.into()); - let rc_register = self.make_usize_constant_instruction(1_usize.into()); - - let var = BrilligVariable::BrilligVector(BrilligVector { - pointer: pointer_to_the_array_in_calldata.address, - size: size_register.address, - rc: rc_register.address, - }); - - current_calldata_pointer += flattened_size; - var - } - }) - .collect(); - - // Deflatten arrays + // Initialize the variables with the calldata for (argument_variable, argument) in argument_variables.iter_mut().zip(arguments) { match (argument_variable, argument) { + (BrilligVariable::SingleAddr(single_address), BrilligParameter::SingleAddr(_)) => { + self.mov_instruction( + single_address.address, + MemoryAddress(current_calldata_pointer), + ); + current_calldata_pointer += 1; + } ( BrilligVariable::BrilligArray(array), BrilligParameter::Array(item_type, item_count), ) => { + let flattened_size = array.size; + self.usize_const_instruction(array.pointer, current_calldata_pointer.into()); + self.usize_const_instruction(array.rc, 1_usize.into()); + + // Deflatten the array let deflattened_address = self.deflatten_array(item_type, array.size, array.pointer); self.mov_instruction(array.pointer, deflattened_address); array.size = item_type.len() * item_count; self.deallocate_register(deflattened_address); + + current_calldata_pointer += flattened_size; } ( BrilligVariable::BrilligVector(vector), BrilligParameter::Slice(item_type, item_count), ) => { let flattened_size = Self::flattened_size(argument); + self.usize_const_instruction(vector.pointer, current_calldata_pointer.into()); + self.usize_const_instruction(vector.rc, 1_usize.into()); + self.usize_const_instruction(vector.size, flattened_size.into()); + // Deflatten the vector let deflattened_address = self.deflatten_array(item_type, flattened_size, vector.pointer); self.mov_instruction(vector.pointer, deflattened_address); @@ -140,14 +113,45 @@ impl BrilligContext { vector.size, (item_type.len() * item_count).into(), ); - self.deallocate_register(deflattened_address); + + current_calldata_pointer += flattened_size; } - _ => {} + _ => unreachable!("ICE: cannot match variables against arguments"), } } } + fn allocate_function_arguments( + &mut self, + arguments: &[BrilligParameter], + ) -> Vec { + arguments + .iter() + .map(|argument| match argument { + BrilligParameter::SingleAddr(bit_size) => { + BrilligVariable::SingleAddr(SingleAddrVariable { + address: self.allocate_register(), + bit_size: *bit_size, + }) + } + BrilligParameter::Array(_, _) => { + let flattened_size = Self::flattened_size(argument); + BrilligVariable::BrilligArray(BrilligArray { + pointer: self.allocate_register(), + size: flattened_size, + rc: self.allocate_register(), + }) + } + BrilligParameter::Slice(_, _) => BrilligVariable::BrilligVector(BrilligVector { + pointer: self.allocate_register(), + size: self.allocate_register(), + rc: self.allocate_register(), + }), + }) + .collect() + } + fn copy_and_cast_calldata(&mut self, arguments: &[BrilligParameter]) { let calldata_size = Self::flattened_tuple_size(arguments); self.calldata_copy_instruction( diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs index afea3f326b0..c728b36c193 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/instructions.rs @@ -481,11 +481,15 @@ impl BrilligContext< ) { self.debug_show.calldata_copy_instruction(destination, calldata_size, offset); + let size_var = self.make_usize_constant_instruction(calldata_size.into()); + let offset_var = self.make_usize_constant_instruction(offset.into()); self.push_opcode(BrilligOpcode::CalldataCopy { destination_address: destination, - size: calldata_size, - offset, + size_address: size_var.address, + offset_address: offset_var.address, }); + self.deallocate_single_addr(size_var); + self.deallocate_single_addr(offset_var); } pub(super) fn trap_instruction(&mut self, revert_data: HeapArray) { diff --git a/compiler/noirc_frontend/src/hir/comptime/errors.rs b/compiler/noirc_frontend/src/hir/comptime/errors.rs index 70589973745..4f419a2119d 100644 --- a/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -602,7 +602,7 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { } InterpreterError::GenericNameShouldBeAnIdent { name, location } => { let msg = - "Generic name needs to be a valid identifer (one word beginning with a letter)" + "Generic name needs to be a valid identifier (one word beginning with a letter)" .to_string(); let secondary = format!("`{name}` is not a valid identifier"); CustomDiagnostic::simple_error(msg, secondary, location.span) diff --git a/docs/docs/noir/standard_library/meta/function_def.md b/docs/docs/noir/standard_library/meta/function_def.md index 7fae5fc381a..63dd1fad2e5 100644 --- a/docs/docs/noir/standard_library/meta/function_def.md +++ b/docs/docs/noir/standard_library/meta/function_def.md @@ -11,7 +11,7 @@ a function definition in the source program. #include_code add_attribute noir_stdlib/src/meta/function_def.nr rust -Adds an attribute to the function. This is only valid +Adds an attribute to the function. This is only valid on functions in the current crate which have not yet been resolved. This means any functions called at compile-time are invalid targets for this method. @@ -19,7 +19,7 @@ This means any functions called at compile-time are invalid targets for this met #include_code body noir_stdlib/src/meta/function_def.nr rust -Returns the body of the function as an expression. This is only valid +Returns the body of the function as an expression. This is only valid on functions in the current crate which have not yet been resolved. This means any functions called at compile-time are invalid targets for this method. @@ -90,8 +90,8 @@ This means any functions called at compile-time are invalid targets for this met #include_code set_return_public noir_stdlib/src/meta/function_def.nr rust -Mutates the function's return visibility to public (if `true` is given) or private (if `false` is given). -This is only valid on functions in the current crate which have not yet been resolved. +Mutates the function's return visibility to public (if `true` is given) or private (if `false` is given). +This is only valid on functions in the current crate which have not yet been resolved. This means any functions called at compile-time are invalid targets for this method. ### set_unconstrained @@ -99,5 +99,5 @@ This means any functions called at compile-time are invalid targets for this met #include_code set_unconstrained noir_stdlib/src/meta/function_def.nr rust Mutates the function to be unconstrained (if `true` is given) or not (if `false` is given). -This is only valid on functions in the current crate which have not yet been resolved. +This is only valid on functions in the current crate which have not yet been resolved. This means any functions called at compile-time are invalid targets for this method. \ No newline at end of file diff --git a/tooling/debugger/src/context.rs b/tooling/debugger/src/context.rs index 0d348cf172d..dde3fe84d88 100644 --- a/tooling/debugger/src/context.rs +++ b/tooling/debugger/src/context.rs @@ -976,10 +976,20 @@ mod tests { let brillig_bytecode = BrilligBytecode { bytecode: vec![ + BrilligOpcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(1u64), + }, + BrilligOpcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, BrilligOpcode::CalldataCopy { destination_address: MemoryAddress(0), - size: 1, - offset: 0, + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, BrilligOpcode::Const { destination: MemoryAddress::from(1), @@ -1036,7 +1046,7 @@ mod tests { }) ); - // Execute the first Brillig opcode (calldata copy) + // Const let result = context.step_into_opcode(); assert!(matches!(result, DebugCommandResult::Ok)); assert_eq!( @@ -1048,7 +1058,7 @@ mod tests { }) ); - // execute the second Brillig opcode (const) + // Const let result = context.step_into_opcode(); assert!(matches!(result, DebugCommandResult::Ok)); assert_eq!( @@ -1060,26 +1070,50 @@ mod tests { }) ); - // try to execute the third Brillig opcode (and resolve the foreign call) + // Calldatacopy let result = context.step_into_opcode(); assert!(matches!(result, DebugCommandResult::Ok)); assert_eq!( context.get_current_debug_location(), Some(DebugLocation { circuit_id: 0, - opcode_location: OpcodeLocation::Brillig { acir_index: 0, brillig_index: 2 }, + opcode_location: OpcodeLocation::Brillig { acir_index: 0, brillig_index: 3 }, brillig_function_id: Some(BrilligFunctionId(0)), }) ); - // retry the third Brillig opcode (foreign call should be finished) + // Const let result = context.step_into_opcode(); assert!(matches!(result, DebugCommandResult::Ok)); assert_eq!( context.get_current_debug_location(), Some(DebugLocation { circuit_id: 0, - opcode_location: OpcodeLocation::Brillig { acir_index: 0, brillig_index: 3 }, + opcode_location: OpcodeLocation::Brillig { acir_index: 0, brillig_index: 4 }, + brillig_function_id: Some(BrilligFunctionId(0)), + }) + ); + + // try to execute the Brillig opcode (and resolve the foreign call) + let result = context.step_into_opcode(); + assert!(matches!(result, DebugCommandResult::Ok)); + assert_eq!( + context.get_current_debug_location(), + Some(DebugLocation { + circuit_id: 0, + opcode_location: OpcodeLocation::Brillig { acir_index: 0, brillig_index: 4 }, + brillig_function_id: Some(BrilligFunctionId(0)), + }) + ); + + // retry the Brillig opcode (foreign call should be finished) + let result = context.step_into_opcode(); + assert!(matches!(result, DebugCommandResult::Ok)); + assert_eq!( + context.get_current_debug_location(), + Some(DebugLocation { + circuit_id: 0, + opcode_location: OpcodeLocation::Brillig { acir_index: 0, brillig_index: 5 }, brillig_function_id: Some(BrilligFunctionId(0)), }) ); @@ -1101,10 +1135,20 @@ mod tests { // This Brillig block is equivalent to: z = x + y let brillig_bytecode = BrilligBytecode { bytecode: vec![ + BrilligOpcode::Const { + destination: MemoryAddress(0), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(2u64), + }, + BrilligOpcode::Const { + destination: MemoryAddress(1), + bit_size: BitSize::Integer(IntegerBitSize::U32), + value: FieldElement::from(0u64), + }, BrilligOpcode::CalldataCopy { destination_address: MemoryAddress(0), - size: 2, - offset: 0, + size_address: MemoryAddress(0), + offset_address: MemoryAddress(1), }, BrilligOpcode::BinaryFieldOp { destination: MemoryAddress::from(0),