Skip to content

Commit a0c8915

Browse files
authored
feat(avm)!: variants for REVERT opcode (#8487)
3-6% bytecode improvement.
1 parent bce1eea commit a0c8915

File tree

12 files changed

+65
-27
lines changed

12 files changed

+65
-27
lines changed

avm-transpiler/src/opcodes.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ pub enum AvmOpcode {
7979
STATICCALL,
8080
DELEGATECALL,
8181
RETURN,
82-
REVERT,
82+
REVERT_8,
83+
REVERT_16,
8384
// Misc
8485
DEBUGLOG,
8586
// Gadgets
@@ -189,7 +190,8 @@ impl AvmOpcode {
189190
AvmOpcode::STATICCALL => "STATICCALL",
190191
AvmOpcode::DELEGATECALL => "DELEGATECALL",
191192
AvmOpcode::RETURN => "RETURN",
192-
AvmOpcode::REVERT => "REVERT",
193+
AvmOpcode::REVERT_8 => "REVERT_8",
194+
AvmOpcode::REVERT_16 => "REVERT_16",
193195

194196
// Misc
195197
AvmOpcode::DEBUGLOG => "DEBUGLOG",

avm-transpiler/src/transpile.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,22 @@ pub fn brillig_to_avm(
274274
});
275275
}
276276
BrilligOpcode::Trap { revert_data } => {
277+
let bits_needed = [revert_data.pointer.0, revert_data.size]
278+
.iter()
279+
.map(bits_needed_for)
280+
.max()
281+
.unwrap();
282+
let avm_opcode = match bits_needed {
283+
8 => AvmOpcode::REVERT_8,
284+
16 => AvmOpcode::REVERT_16,
285+
_ => panic!("REVERT only support 8 or 16 bit encodings, got: {}", bits_needed),
286+
};
277287
avm_instrs.push(AvmInstruction {
278-
opcode: AvmOpcode::REVERT,
288+
opcode: avm_opcode,
279289
indirect: Some(ZEROTH_OPERAND_INDIRECT),
280290
operands: vec![
281-
AvmOperand::U32 { value: revert_data.pointer.0 as u32 },
282-
AvmOperand::U32 { value: revert_data.size as u32 },
291+
make_operand(bits_needed, &revert_data.pointer.0),
292+
make_operand(bits_needed, &revert_data.size),
283293
],
284294
..Default::default()
285295
});

barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ const std::unordered_map<OpCode, std::vector<OperandType>> OPCODE_WIRE_FORMAT =
160160
// DELEGATECALL, -- not in simulator
161161
{ OpCode::RETURN, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } },
162162
// REVERT,
163-
{ OpCode::REVERT, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } },
163+
{ OpCode::REVERT_8, { OperandType::INDIRECT, OperandType::UINT8, OperandType::UINT8 } },
164+
{ OpCode::REVERT_16, { OperandType::INDIRECT, OperandType::UINT16, OperandType::UINT16 } },
164165

165166
// Misc
166167
{ OpCode::DEBUGLOG,

barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -815,10 +815,18 @@ std::vector<Row> Execution::gen_trace(std::vector<Instruction> const& instructio
815815

816816
break;
817817
}
818-
case OpCode::REVERT: {
818+
case OpCode::REVERT_8: {
819819
auto ret = trace_builder.op_revert(std::get<uint8_t>(inst.operands.at(0)),
820-
std::get<uint32_t>(inst.operands.at(1)),
821-
std::get<uint32_t>(inst.operands.at(2)));
820+
std::get<uint8_t>(inst.operands.at(1)),
821+
std::get<uint8_t>(inst.operands.at(2)));
822+
returndata.insert(returndata.end(), ret.begin(), ret.end());
823+
824+
break;
825+
}
826+
case OpCode::REVERT_16: {
827+
auto ret = trace_builder.op_revert(std::get<uint8_t>(inst.operands.at(0)),
828+
std::get<uint16_t>(inst.operands.at(1)),
829+
std::get<uint16_t>(inst.operands.at(2)));
822830
returndata.insert(returndata.end(), ret.begin(), ret.end());
823831

824832
break;

barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ const std::unordered_map<OpCode, FixedGasTable::GasRow> GAS_COST_TABLE = {
8989
{ OpCode::STATICCALL, make_cost(AVM_STATICCALL_BASE_L2_GAS, 0, AVM_STATICCALL_DYN_L2_GAS, 0) },
9090
{ OpCode::DELEGATECALL, make_cost(AVM_DELEGATECALL_BASE_L2_GAS, 0, AVM_DELEGATECALL_DYN_L2_GAS, 0) },
9191
{ OpCode::RETURN, make_cost(AVM_RETURN_BASE_L2_GAS, 0, AVM_RETURN_DYN_L2_GAS, 0) },
92-
{ OpCode::REVERT, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) },
92+
{ OpCode::REVERT_8, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) },
93+
{ OpCode::REVERT_16, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) },
9394
{ OpCode::DEBUGLOG, make_cost(AVM_DEBUGLOG_BASE_L2_GAS, 0, AVM_DEBUGLOG_DYN_L2_GAS, 0) },
9495
{ OpCode::KECCAK, make_cost(AVM_KECCAK_BASE_L2_GAS, 0, AVM_KECCAK_DYN_L2_GAS, 0) },
9596
{ OpCode::POSEIDON2, make_cost(AVM_POSEIDON2_BASE_L2_GAS, 0, AVM_POSEIDON2_DYN_L2_GAS, 0) },

barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,10 @@ std::string to_string(OpCode opcode)
174174
return "DELEGATECALL";
175175
case OpCode::RETURN:
176176
return "RETURN";
177-
case OpCode::REVERT:
178-
return "REVERT";
177+
case OpCode::REVERT_8:
178+
return "REVERT_8";
179+
case OpCode::REVERT_16:
180+
return "REVERT_16";
179181
// Misc
180182
case OpCode::DEBUGLOG:
181183
return "DEBUGLOG";

barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ enum class OpCode : uint8_t {
105105
STATICCALL,
106106
DELEGATECALL,
107107
RETURN,
108-
REVERT,
108+
REVERT_8,
109+
REVERT_16,
109110

110111
// Misc
111112
DEBUGLOG,

yarn-project/simulator/src/avm/avm_gas.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ const BaseGasCosts: Record<Opcode, Gas> = {
126126
[Opcode.STATICCALL]: makeCost(c.AVM_STATICCALL_BASE_L2_GAS, 0),
127127
[Opcode.DELEGATECALL]: makeCost(c.AVM_DELEGATECALL_BASE_L2_GAS, 0),
128128
[Opcode.RETURN]: makeCost(c.AVM_RETURN_BASE_L2_GAS, 0),
129-
[Opcode.REVERT]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0),
129+
[Opcode.REVERT_8]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0),
130+
[Opcode.REVERT_16]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0),
130131
[Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_BASE_L2_GAS, 0),
131132
[Opcode.KECCAK]: makeCost(c.AVM_KECCAK_BASE_L2_GAS, 0),
132133
[Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_BASE_L2_GAS, 0),
@@ -210,7 +211,8 @@ const DynamicGasCosts: Record<Opcode, Gas> = {
210211
[Opcode.STATICCALL]: makeCost(c.AVM_STATICCALL_DYN_L2_GAS, 0),
211212
[Opcode.DELEGATECALL]: makeCost(c.AVM_DELEGATECALL_DYN_L2_GAS, 0),
212213
[Opcode.RETURN]: makeCost(c.AVM_RETURN_DYN_L2_GAS, 0),
213-
[Opcode.REVERT]: makeCost(c.AVM_REVERT_DYN_L2_GAS, 0),
214+
[Opcode.REVERT_8]: makeCost(c.AVM_REVERT_DYN_L2_GAS, 0),
215+
[Opcode.REVERT_16]: makeCost(c.AVM_REVERT_DYN_L2_GAS, 0),
214216
[Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_DYN_L2_GAS, 0),
215217
[Opcode.KECCAK]: makeCost(c.AVM_KECCAK_DYN_L2_GAS, 0),
216218
[Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_DYN_L2_GAS, 0),

yarn-project/simulator/src/avm/opcodes/external_calls.test.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -287,14 +287,17 @@ describe('External Calls', () => {
287287
describe('REVERT', () => {
288288
it('Should (de)serialize correctly', () => {
289289
const buf = Buffer.from([
290-
Revert.opcode, // opcode
290+
Opcode.REVERT_16, // opcode
291291
0x01, // indirect
292-
...Buffer.from('12345678', 'hex'), // returnOffset
293-
...Buffer.from('a2345678', 'hex'), // retSize
292+
...Buffer.from('1234', 'hex'), // returnOffset
293+
...Buffer.from('a234', 'hex'), // retSize
294294
]);
295-
const inst = new Revert(/*indirect=*/ 0x01, /*returnOffset=*/ 0x12345678, /*retSize=*/ 0xa2345678);
295+
const inst = new Revert(/*indirect=*/ 0x01, /*returnOffset=*/ 0x1234, /*retSize=*/ 0xa234).as(
296+
Opcode.REVERT_16,
297+
Revert.wireFormat16,
298+
);
296299

297-
expect(Revert.deserialize(buf)).toEqual(inst);
300+
expect(Revert.as(Revert.wireFormat16).deserialize(buf)).toEqual(inst);
298301
expect(inst.serialize()).toEqual(buf);
299302
});
300303

yarn-project/simulator/src/avm/opcodes/external_calls.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,19 @@ export class Return extends Instruction {
183183

184184
export class Revert extends Instruction {
185185
static type: string = 'REVERT';
186-
static readonly opcode: Opcode = Opcode.REVERT;
187-
// Informs (de)serialization. See Instruction.deserialize.
188-
static readonly wireFormat: OperandType[] = [
186+
static readonly opcode: Opcode = Opcode.REVERT_8;
187+
188+
static readonly wireFormat8: OperandType[] = [
189189
OperandType.UINT8,
190190
OperandType.UINT8,
191-
OperandType.UINT32,
192-
OperandType.UINT32,
191+
OperandType.UINT8,
192+
OperandType.UINT8,
193+
];
194+
static readonly wireFormat16: OperandType[] = [
195+
OperandType.UINT8,
196+
OperandType.UINT8,
197+
OperandType.UINT16,
198+
OperandType.UINT16,
193199
];
194200

195201
constructor(private indirect: number, private returnOffset: number, private retSize: number) {

yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ const INSTRUCTION_SET = () =>
155155
[StaticCall.opcode, Instruction.deserialize.bind(StaticCall)],
156156
//[DelegateCall.opcode, Instruction.deserialize.bind(DelegateCall)],
157157
[Return.opcode, Instruction.deserialize.bind(Return)],
158-
[Revert.opcode, Instruction.deserialize.bind(Revert)],
158+
[Opcode.REVERT_8, Revert.as(Revert.wireFormat8).deserialize],
159+
[Opcode.REVERT_16, Revert.as(Revert.wireFormat16).deserialize],
159160

160161
// Misc
161162
[DebugLog.opcode, Instruction.deserialize.bind(DebugLog)],

yarn-project/simulator/src/avm/serialization/instruction_serialization.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ export enum Opcode {
8383
STATICCALL,
8484
DELEGATECALL,
8585
RETURN,
86-
REVERT,
86+
REVERT_8,
87+
REVERT_16,
8788
// Misc
8889
DEBUGLOG,
8990
// Gadgets

0 commit comments

Comments
 (0)