Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Stop with HeapVector #9810

Merged
merged 12 commits into from
Nov 12, 2024
59 changes: 34 additions & 25 deletions avm-transpiler/src/transpile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,16 +306,12 @@ pub fn brillig_to_avm(brillig_bytecode: &[BrilligOpcode<FieldElement>]) -> (Vec<
}
BrilligOpcode::Return {} => avm_instrs
.push(AvmInstruction { opcode: AvmOpcode::INTERNALRETURN, ..Default::default() }),
BrilligOpcode::Stop { return_data_offset, return_data_size } => {
avm_instrs.push(AvmInstruction {
opcode: AvmOpcode::RETURN,
indirect: Some(AddressingModeBuilder::default().build()),
operands: vec![
AvmOperand::U16 { value: *return_data_offset as u16 },
AvmOperand::U16 { value: *return_data_size as u16 },
],
..Default::default()
});
BrilligOpcode::Stop { return_data } => {
generate_return_instruction(
&mut avm_instrs,
&return_data.pointer,
&return_data.size,
);
}
BrilligOpcode::Trap { revert_data } => {
generate_revert_instruction(
Expand Down Expand Up @@ -960,6 +956,28 @@ fn generate_revert_instruction(
});
}

/// Generates an AVM RETURN instruction.
fn generate_return_instruction(
avm_instrs: &mut Vec<AvmInstruction>,
return_data_pointer: &MemoryAddress,
return_data_size_offset: &MemoryAddress,
) {
avm_instrs.push(AvmInstruction {
opcode: AvmOpcode::RETURN,
indirect: Some(
AddressingModeBuilder::default()
.indirect_operand(return_data_pointer)
.direct_operand(return_data_size_offset)
.build(),
),
operands: vec![
AvmOperand::U16 { value: return_data_pointer.to_usize() as u16 },
AvmOperand::U16 { value: return_data_size_offset.to_usize() as u16 },
],
..Default::default()
});
}

/// Generates an AVM MOV instruction.
fn generate_mov_instruction(
indirect: Option<AvmOperand>,
Expand Down Expand Up @@ -1323,25 +1341,16 @@ fn handle_return(
destinations: &Vec<ValueOrArray>,
inputs: &Vec<ValueOrArray>,
) {
assert!(inputs.len() == 1);
assert!(inputs.len() == 2);
assert!(destinations.len() == 0);

let (return_data_offset, return_data_size) = match inputs[0] {
ValueOrArray::HeapArray(HeapArray { pointer, size }) => (pointer, size as u32),
_ => panic!("Return instruction's args input should be a HeapArray"),
// First arg is the size, which is ignored because it's redundant.
let (return_data_offset, return_data_size) = match inputs[1] {
ValueOrArray::HeapVector(HeapVector { pointer, size }) => (pointer, size),
_ => panic!("Revert instruction's args input should be a HeapVector"),
};

avm_instrs.push(AvmInstruction {
opcode: AvmOpcode::RETURN,
indirect: Some(
AddressingModeBuilder::default().indirect_operand(&return_data_offset).build(),
),
operands: vec![
AvmOperand::U16 { value: return_data_offset.to_usize() as u16 },
AvmOperand::U16 { value: return_data_size as u16 },
],
..Default::default()
});
generate_return_instruction(avm_instrs, &return_data_offset, &return_data_size);
}

// #[oracle(avmOpcodeRevert)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class AcirAvmRecursionConstraint : public ::testing::Test {
trace_builder.op_add(0, 1, 2, 3);
trace_builder.op_sub(0, 3, 2, 3);
trace_builder.op_mul(0, 1, 1, 3);
trace_builder.op_return(0, 0, 0);
trace_builder.op_set(0, 0, 100, AvmMemoryTag::U32);
trace_builder.op_return(0, 0, 100);
auto trace = trace_builder.finalize(); // Passing true enables a longer trace with lookups

avm_trace::inject_end_gas_values(public_inputs, trace);
Expand Down
14 changes: 4 additions & 10 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,7 @@ struct BrilligOpcode {
};

struct Stop {
uint64_t return_data_offset;
uint64_t return_data_size;
Program::HeapVector return_data;

friend bool operator==(const Stop&, const Stop&);
std::vector<uint8_t> bincodeSerialize() const;
Expand Down Expand Up @@ -6401,10 +6400,7 @@ namespace Program {

inline bool operator==(const BrilligOpcode::Stop& lhs, const BrilligOpcode::Stop& rhs)
{
if (!(lhs.return_data_offset == rhs.return_data_offset)) {
return false;
}
if (!(lhs.return_data_size == rhs.return_data_size)) {
if (!(lhs.return_data == rhs.return_data)) {
return false;
}
return true;
Expand Down Expand Up @@ -6434,8 +6430,7 @@ template <typename Serializer>
void serde::Serializable<Program::BrilligOpcode::Stop>::serialize(const Program::BrilligOpcode::Stop& obj,
Serializer& serializer)
{
serde::Serializable<decltype(obj.return_data_offset)>::serialize(obj.return_data_offset, serializer);
serde::Serializable<decltype(obj.return_data_size)>::serialize(obj.return_data_size, serializer);
serde::Serializable<decltype(obj.return_data)>::serialize(obj.return_data, serializer);
}

template <>
Expand All @@ -6444,8 +6439,7 @@ Program::BrilligOpcode::Stop serde::Deserializable<Program::BrilligOpcode::Stop>
Deserializer& deserializer)
{
Program::BrilligOpcode::Stop obj;
obj.return_data_offset = serde::Deserializable<decltype(obj.return_data_offset)>::deserialize(deserializer);
obj.return_data_size = serde::Deserializable<decltype(obj.return_data_size)>::deserialize(deserializer);
obj.return_data = serde::Deserializable<decltype(obj.return_data)>::deserialize(deserializer);
return obj;
}

Expand Down
Loading
Loading