Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fcarreiro committed Sep 4, 2024
1 parent 249e50e commit 91cc9b8
Show file tree
Hide file tree
Showing 16 changed files with 449 additions and 240 deletions.
62 changes: 60 additions & 2 deletions avm-transpiler/src/transpile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,29 @@ pub fn brillig_to_avm(
});
}
BrilligOpcode::CalldataCopy { destination_address, size, offset } => {
// FIXME: I need scratch space or Brillig to change CALLDATA!
// This will break for small calldatas
avm_instrs.push(generate_set_instruction(
AvmTypeTag::UINT32,
destination_address.0 as u32,
*offset as u128,
false,
));
avm_instrs.push(generate_set_instruction(
AvmTypeTag::UINT32,
(destination_address.0 + 1) as u32,
*size as u128,
false,
));

avm_instrs.push(AvmInstruction {
opcode: AvmOpcode::CALLDATACOPY,
indirect: Some(ALL_DIRECT),
operands: vec![
AvmOperand::U32 {
value: *offset as u32, // cdOffset (calldata offset)
value: destination_address.0 as u32, // cdOffset (calldata offset)
},
AvmOperand::U32 { value: *size as u32 },
AvmOperand::U32 { value: (destination_address.0 + 1) as u32 }, // sizeOffset
AvmOperand::U32 {
value: destination_address.to_usize() as u32, // dstOffset
},
Expand Down Expand Up @@ -265,6 +280,7 @@ fn handle_foreign_call(
"avmOpcodeGetContractInstance" => {
handle_get_contract_instance(avm_instrs, destinations, inputs);
}
"avmOpcodeCalldataCopy" => handle_calldata_copy(avm_instrs, destinations, inputs),
"avmOpcodeStorageRead" => handle_storage_read(avm_instrs, destinations, inputs),
"avmOpcodeStorageWrite" => handle_storage_write(avm_instrs, destinations, inputs),
"debugLog" => handle_debug_log(avm_instrs, destinations, inputs),
Expand Down Expand Up @@ -974,6 +990,47 @@ fn handle_debug_log(
});
}

// #[oracle(avmOpcodeCalldataCopy)]
// unconstrained fn calldata_copy_opcode<let N: u32>(cdoffset: Field) -> [Field; N] {}
fn handle_calldata_copy(
avm_instrs: &mut Vec<AvmInstruction>,
destinations: &Vec<ValueOrArray>,
inputs: &Vec<ValueOrArray>,
) {
assert!(inputs.len() == 2);
assert!(destinations.len() == 1);

let cd_offset = match inputs[0] {
ValueOrArray::MemoryAddress(address) => address.0,
_ => panic!("CalldataCopy offset should be a memory address"),
};

let copy_size_offset = match inputs[1] {
ValueOrArray::MemoryAddress(address) => address.0,
_ => panic!("CalldataCopy size should be a memory address"),
};

let (dest_offset, ..) = match destinations[0] {
ValueOrArray::HeapArray(HeapArray { pointer, size }) => (pointer.0, size),
_ => panic!("CalldataCopy destination should be an array"),
};

avm_instrs.push(AvmInstruction {
opcode: AvmOpcode::CALLDATACOPY,
indirect: Some(SECOND_OPERAND_INDIRECT),
operands: vec![
AvmOperand::U32 {
value: cd_offset as u32, // cdOffset (calldata offset)
},
AvmOperand::U32 { value: copy_size_offset as u32 }, // copy size
AvmOperand::U32 {
value: dest_offset as u32, // dstOffset
},
],
..Default::default()
});
}

/// Emit a storage write opcode
/// The current implementation writes an array of values into storage ( contiguous slots in memory )
fn handle_storage_write(
Expand Down Expand Up @@ -1131,6 +1188,7 @@ pub fn map_brillig_pcs_to_avm_pcs(brillig_bytecode: &[BrilligOpcode<FieldElement
BrilligOpcode::Const { bit_size: BitSize::Field, .. } => 2,
BrilligOpcode::IndirectConst { bit_size: BitSize::Field, .. } => 2,
BrilligOpcode::Cast { bit_size: BitSize::Integer(IntegerBitSize::U1), .. } => 3,
BrilligOpcode::CalldataCopy { .. } => 3,
_ => 1,
};
// next Brillig pc will map to an AVM pc offset by the
Expand Down
41 changes: 31 additions & 10 deletions barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,9 @@ TEST_F(AvmArithmeticTestsFF, addition)
{
std::vector<FF> const calldata = { 37, 4, 11 };
gen_trace_builder(calldata);
trace_builder.op_calldata_copy(0, 0, 3, 0);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 3, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [37,4,11,0,0,0,....]
trace_builder.op_add(0, 0, 1, 4, AvmMemoryTag::FF); // [37,4,11,0,41,0,....]
Expand All @@ -415,7 +417,9 @@ TEST_F(AvmArithmeticTestsFF, subtraction)
{
std::vector<FF> const calldata = { 8, 4, 17 };
gen_trace_builder(calldata);
trace_builder.op_calldata_copy(0, 0, 3, 0);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 3, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [8,4,17,0,0,0,....]
trace_builder.op_sub(0, 2, 0, 1, AvmMemoryTag::FF); // [8,9,17,0,0,0....]
Expand All @@ -436,7 +440,9 @@ TEST_F(AvmArithmeticTestsFF, multiplication)
{
std::vector<FF> const calldata = { 5, 0, 20 };
gen_trace_builder(calldata);
trace_builder.op_calldata_copy(0, 0, 3, 0);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 3, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [5,0,20,0,0,0,....]
trace_builder.op_mul(0, 2, 0, 1, AvmMemoryTag::FF); // [5,100,20,0,0,0....]
Expand All @@ -456,8 +462,10 @@ TEST_F(AvmArithmeticTestsFF, multiplication)
// Test on multiplication by zero over finite field type.
TEST_F(AvmArithmeticTestsFF, multiplicationByZero)
{
std::vector<FF> const calldata = { 127 };
std::vector<FF> const calldata = { 127, 0, 0 };
gen_trace_builder(calldata);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 3, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [127,0,0,0,0,0,....]
Expand All @@ -480,7 +488,9 @@ TEST_F(AvmArithmeticTestsFF, fDivision)
{
std::vector<FF> const calldata = { 15, 315 };
gen_trace_builder(calldata);
trace_builder.op_calldata_copy(0, 0, 2, 0);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 2, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [15,315,0,0,0,0,....]
trace_builder.op_fdiv(0, 1, 0, 2); // [15,315,21,0,0,0....]
Expand All @@ -504,8 +514,10 @@ TEST_F(AvmArithmeticTestsFF, fDivision)
// Test on division with zero numerator over finite field type.
TEST_F(AvmArithmeticTestsFF, fDivisionNumeratorZero)
{
std::vector<FF> const calldata = { 15 };
std::vector<FF> const calldata = { 15, 0, 0 };
gen_trace_builder(calldata);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 3, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [15,0,0,0,0,0,....]
Expand All @@ -531,8 +543,10 @@ TEST_F(AvmArithmeticTestsFF, fDivisionNumeratorZero)
// We check that the operator error flag is raised.
TEST_F(AvmArithmeticTestsFF, fDivisionByZeroError)
{
std::vector<FF> const calldata = { 15 };
std::vector<FF> const calldata = { 15, 0, 0 };
gen_trace_builder(calldata);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 3, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [15,0,0,0,0,0,....]
Expand Down Expand Up @@ -585,7 +599,9 @@ TEST_F(AvmArithmeticTestsFF, mixedOperationsWithError)
{
std::vector<FF> const calldata = { 45, 23, 12 };
gen_trace_builder(calldata);
trace_builder.op_calldata_copy(0, 0, 3, 2);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 3, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

// Memory layout: [0,0,45,23,12,0,0,0,....]
trace_builder.op_add(0, 2, 3, 4, AvmMemoryTag::FF); // [0,0,45,23,68,0,0,0,....]
Expand All @@ -610,7 +626,9 @@ TEST_F(AvmArithmeticTestsFF, equality)
FF elem = FF::modulus - FF(1);
std::vector<FF> const calldata = { elem, elem };
gen_trace_builder(calldata);
trace_builder.op_calldata_copy(0, 0, 2, 0);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 2, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);
trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::FF); // Memory Layout [q - 1, q - 1, 1, 0..]
trace_builder.op_return(0, 0, 3);
auto trace = trace_builder.finalize();
Expand All @@ -631,7 +649,10 @@ TEST_F(AvmArithmeticTestsFF, nonEquality)
FF elem = FF::modulus - FF(1);
std::vector<FF> const calldata = { elem, elem + FF(1) };
gen_trace_builder(calldata);
trace_builder.op_calldata_copy(0, 0, 2, 0);
trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32);
trace_builder.op_set(0, 2, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);

trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::FF); // Memory Layout [q - 1, q, 0, 0..]
trace_builder.op_return(0, 0, 3);
auto trace = trace_builder.finalize();
Expand Down
2 changes: 2 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ TEST_F(AvmCastTests, truncationFFToU16ModMinus1)
{
calldata = { FF::modulus - 1 };
trace_builder = AvmTraceBuilder(public_inputs, {}, 0, calldata);
trace_builder.op_set(0, 1, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);
trace_builder.op_cast(0, 0, 1, AvmMemoryTag::U16);
trace_builder.op_return(0, 0, 0);
Expand All @@ -184,6 +185,7 @@ TEST_F(AvmCastTests, truncationFFToU16ModMinus2)
{
calldata = { FF::modulus_minus_two };
trace_builder = AvmTraceBuilder(public_inputs, {}, 0, calldata);
trace_builder.op_set(0, 1, 1, AvmMemoryTag::U32);
trace_builder.op_calldata_copy(0, 0, 1, 0);
trace_builder.op_cast(0, 0, 1, AvmMemoryTag::U16);
trace_builder.op_return(0, 0, 0);
Expand Down
Loading

0 comments on commit 91cc9b8

Please sign in to comment.