Skip to content

Commit

Permalink
feat: update de-serialisation for indirect
Browse files Browse the repository at this point in the history
  • Loading branch information
IlyasRidhuan committed Mar 1, 2024
1 parent 553c2c6 commit 699a32c
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ namespace bb::avm_trace {
namespace {

const std::vector<OperandType> three_operand_format = {
OperandType::TAG,
OperandType::UINT32,
OperandType::UINT32,
OperandType::UINT32,
OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32,
};

// Contrary to TS, the format does not contain the opcode byte which prefixes any instruction.
Expand All @@ -32,22 +29,22 @@ const std::unordered_map<OpCode, std::vector<OperandType>> OPCODE_WIRE_FORMAT =
// Compute - Comparators
{ OpCode::EQ, three_operand_format },
// Compute - Bitwise
{ OpCode::NOT, { OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } },
{ OpCode::NOT, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } },
// Execution Environment - Calldata
{ OpCode::CALLDATACOPY, { OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } },
{ OpCode::CALLDATACOPY, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } },
// Machine State - Internal Control Flow
{ OpCode::JUMP, { OperandType::UINT32 } },
{ OpCode::INTERNALCALL, { OperandType::UINT32 } },
{ OpCode::INTERNALRETURN, {} },
// Machine State - Memory
// OpCode::SET is handled differently
// Control Flow - Contract Calls
{ OpCode::RETURN, { OperandType::UINT32, OperandType::UINT32 } },
{ OpCode::RETURN, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } },
};

const std::unordered_map<OperandType, size_t> OPERAND_TYPE_SIZE = {
{ OperandType::TAG, 1 }, { OperandType::UINT8, 1 }, { OperandType::UINT16, 2 },
{ OperandType::UINT32, 4 }, { OperandType::UINT64, 8 }, { OperandType::UINT128, 16 },
{ OperandType::INDIRECT, 1 }, { OperandType::TAG, 1 }, { OperandType::UINT8, 1 }, { OperandType::UINT16, 2 },
{ OperandType::UINT32, 4 }, { OperandType::UINT64, 8 }, { OperandType::UINT128, 16 },
};

} // Anonymous namespace
Expand Down Expand Up @@ -130,6 +127,10 @@ std::vector<Instruction> Deserialization::parse(std::vector<uint8_t> const& byte
}

switch (opType) {
case OperandType::INDIRECT: {
operands.emplace_back(bytecode.at(pos));
break;
}
case OperandType::TAG: {
uint8_t tag_u8 = bytecode.at(pos);
if (tag_u8 == static_cast<uint8_t>(AvmMemoryTag::U0) || tag_u8 > MAX_MEM_TAG) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ namespace bb::avm_trace {
// Possible types for an instruction's operand in its wire format. (Keep in sync with TS code.
// See avm/serialization/instruction_serialization.ts).
// Note that the TAG enum value is not supported in TS and is parsed as UINT8.
enum class OperandType : uint8_t { TAG, UINT8, UINT16, UINT32, UINT64, UINT128 };
// INDIRECT is parsed as UINT8 where the bits represent the operands that have indirect mem access.
enum class OperandType : uint8_t { INDIRECT, TAG, UINT8, UINT16, UINT32, UINT64, UINT128 };

class Deserialization {
public:
Expand All @@ -24,4 +25,4 @@ class Deserialization {
static std::vector<Instruction> parse(std::vector<uint8_t> const& bytecode);
};

} // namespace bb::avm_trace
} // namespace bb::avm_trace
38 changes: 20 additions & 18 deletions barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,44 +58,46 @@ std::vector<Row> Execution::gen_trace(std::vector<Instruction> const& instructio
while ((pc = trace_builder.getPc()) < inst_size) {
auto inst = instructions.at(pc);

// todo: We do not yet support the indirect flag. Therefore we do not extract
// inst.operands(0) (i.e. the indirect flag) when processiing the instructions.
switch (inst.op_code) {
// Compute
// Compute - Arithmetic
case OpCode::ADD:
trace_builder.op_add(std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(2)),
trace_builder.op_add(std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(3)),
std::get<AvmMemoryTag>(inst.operands.at(0)));
std::get<uint32_t>(inst.operands.at(4)),
std::get<AvmMemoryTag>(inst.operands.at(1)));
break;
case OpCode::SUB:
trace_builder.op_sub(std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(2)),
trace_builder.op_sub(std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(3)),
std::get<AvmMemoryTag>(inst.operands.at(0)));
std::get<uint32_t>(inst.operands.at(4)),
std::get<AvmMemoryTag>(inst.operands.at(1)));
break;
case OpCode::MUL:
trace_builder.op_mul(std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(2)),
trace_builder.op_mul(std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(3)),
std::get<AvmMemoryTag>(inst.operands.at(0)));
std::get<uint32_t>(inst.operands.at(4)),
std::get<AvmMemoryTag>(inst.operands.at(1)));
break;
case OpCode::DIV:
trace_builder.op_div(std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(2)),
trace_builder.op_div(std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(3)),
std::get<AvmMemoryTag>(inst.operands.at(0)));
std::get<uint32_t>(inst.operands.at(4)),
std::get<AvmMemoryTag>(inst.operands.at(1)));
break;
// Compute - Bitwise
case OpCode::NOT:
trace_builder.op_not(std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(3)),
std::get<AvmMemoryTag>(inst.operands.at(0)));
trace_builder.op_not(std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(4)),
std::get<AvmMemoryTag>(inst.operands.at(1)));
break;
// Execution Environment - Calldata
case OpCode::CALLDATACOPY:
trace_builder.calldata_copy(std::get<uint32_t>(inst.operands.at(0)),
std::get<uint32_t>(inst.operands.at(1)),
trace_builder.calldata_copy(std::get<uint32_t>(inst.operands.at(1)),
std::get<uint32_t>(inst.operands.at(2)),
std::get<uint32_t>(inst.operands.at(3)),
calldata);
break;
// Machine State - Internal Control Flow
Expand Down Expand Up @@ -140,7 +142,7 @@ std::vector<Row> Execution::gen_trace(std::vector<Instruction> const& instructio
}
// Control Flow - Contract Calls
case OpCode::RETURN:
trace_builder.return_op(std::get<uint32_t>(inst.operands.at(0)), std::get<uint32_t>(inst.operands.at(1)));
trace_builder.return_op(std::get<uint32_t>(inst.operands.at(1)), std::get<uint32_t>(inst.operands.at(2)));
break;
default:
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ class Instruction {
, operands(std::move(operands)){};
};

} // namespace bb::avm_trace
} // namespace bb::avm_trace
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,4 @@ class Bytecode {

std::string to_hex(OpCode opcode);

} // namespace bb::avm_trace
} // namespace bb::avm_trace
Loading

0 comments on commit 699a32c

Please sign in to comment.