From dee564a16293ff8f0aa2c6ba9fb0d1d6235ba251 Mon Sep 17 00:00:00 2001 From: David Banks <47112877+dbanks12@users.noreply.github.com> Date: Thu, 18 Jan 2024 10:39:57 -0500 Subject: [PATCH] chore(avm): list avm opcodes in a (enum => class) map in TS (#4113) --- .../src/avm/interpreter/interpreter.test.ts | 4 +- .../src/avm/opcodes/from_bytecode.test.ts | 4 +- .../src/avm/opcodes/from_bytecode.ts | 47 +++----- .../src/avm/opcodes/instruction_set.ts | 106 ++++++++++++++++++ .../acir-simulator/src/avm/opcodes/memory.ts | 2 +- .../acir-simulator/src/avm/opcodes/opcodes.ts | 3 +- .../images/bit-formats/INTERNALCALLDEPTH.png | Bin 0 -> 3651 bytes 7 files changed, 127 insertions(+), 39 deletions(-) create mode 100644 yarn-project/acir-simulator/src/avm/opcodes/instruction_set.ts create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALCALLDEPTH.png diff --git a/yarn-project/acir-simulator/src/avm/interpreter/interpreter.test.ts b/yarn-project/acir-simulator/src/avm/interpreter/interpreter.test.ts index 3b86414ab63..19fb0e99b54 100644 --- a/yarn-project/acir-simulator/src/avm/interpreter/interpreter.test.ts +++ b/yarn-project/acir-simulator/src/avm/interpreter/interpreter.test.ts @@ -7,7 +7,7 @@ import { AvmStateManager } from '../avm_state_manager.js'; import { Add } from '../opcodes/arithmetic.js'; import { Return } from '../opcodes/control_flow.js'; import { Instruction } from '../opcodes/instruction.js'; -import { CallDataCopy } from '../opcodes/memory.js'; +import { CalldataCopy } from '../opcodes/memory.js'; import { AvmInterpreter } from './interpreter.js'; describe('interpreter', () => { @@ -17,7 +17,7 @@ describe('interpreter', () => { const instructions: Instruction[] = [ // Copy the first two elements of the calldata to memory regions 0 and 1 - new CallDataCopy(0, 2, 0), + new CalldataCopy(0, 2, 0), // Add the two together and store the result in memory region 2 new Add(0, 1, 2), // 1 + 2 // Return the result diff --git a/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.test.ts index e7f95b89b4f..b5ba48bd23a 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.test.ts @@ -1,5 +1,5 @@ import { Add, Sub } from './arithmetic.js'; -import { OPCODE_BYTE_LENGTH, OPERAND_BTYE_LENGTH, interpretBytecode } from './from_bytecode.js'; +import { OPCODE_BYTE_LENGTH, OPERAND_BYTE_LENGTH, interpretBytecode } from './from_bytecode.js'; import { Instruction } from './instruction.js'; describe('Avm Interpreter', () => { @@ -9,7 +9,7 @@ describe('Avm Interpreter', () => { return buf; }; const to4Byte = (num: number): Buffer => { - const buf = Buffer.alloc(OPERAND_BTYE_LENGTH); + const buf = Buffer.alloc(OPERAND_BYTE_LENGTH); buf.writeUInt32BE(num); return buf; }; diff --git a/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.ts b/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.ts index 697ff6be13b..3225123f00b 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/from_bytecode.ts @@ -1,37 +1,12 @@ -import { Add, Mul, Sub } from './arithmetic.js'; import { Instruction } from './instruction.js'; +import { INSTRUCTION_SET } from './instruction_set.js'; +import { Opcode } from './opcodes.js'; export const OPERAND_BIT_LENGTH = 32; -export const OPERAND_BTYE_LENGTH = 4; +export const OPERAND_BYTE_LENGTH = 4; export const OPCODE_BIT_LENGTH = 8; export const OPCODE_BYTE_LENGTH = 1; -const OPERANDS_LOOKUP: { [key: number]: number } = { - 0x1: Add.numberOfOperands, - 0x2: Sub.numberOfOperands, - 0x3: Mul.numberOfOperands, -}; - -/** - * Given the opcode and operands that have been parsed by the interpreter - * We return a construction of the opcode - * - * @param opcode - Opcode value - * @param operands - Array of operands - */ -function instructionLookup(opcode: number, operands: number[]): Instruction { - switch (opcode) { - case 0x1: - return new Add(operands[0], operands[1], operands[2]); - case 0x2: - return new Sub(operands[0], operands[1], operands[2]); - case 0x3: - return new Mul(operands[0], operands[1], operands[2]); - default: - throw new Error(`Opcode ${opcode} not found`); - } -} - /** * Convert a buffer of bytecode into an array of instructions * @param bytecode - Buffer of bytecode @@ -44,18 +19,26 @@ export function interpretBytecode(bytecode: Buffer): Instruction[] { const instructions: Instruction[] = []; while (readPtr < bytecodeLength) { - const opcode = bytecode[readPtr]; + const opcodeByte = bytecode[readPtr]; readPtr += 1; + if (!(opcodeByte in Opcode)) { + throw new Error(`Opcode ${opcodeByte} not implemented`); + } + const opcode = opcodeByte as Opcode; - const numberOfOperands = OPERANDS_LOOKUP[opcode]; + const instructionType = INSTRUCTION_SET.get(opcode); + if (instructionType === undefined) { + throw new Error(`Opcode ${opcode} not implemented`); + } + const numberOfOperands = instructionType.numberOfOperands; const operands: number[] = []; for (let i = 0; i < numberOfOperands; i++) { const operand = bytecode.readUInt32BE(readPtr); - readPtr += OPERAND_BTYE_LENGTH; + readPtr += OPERAND_BYTE_LENGTH; operands.push(operand); } - instructions.push(instructionLookup(opcode, operands)); + instructions.push(new instructionType(...operands)); } return instructions; diff --git a/yarn-project/acir-simulator/src/avm/opcodes/instruction_set.ts b/yarn-project/acir-simulator/src/avm/opcodes/instruction_set.ts new file mode 100644 index 00000000000..5d8c8921daf --- /dev/null +++ b/yarn-project/acir-simulator/src/avm/opcodes/instruction_set.ts @@ -0,0 +1,106 @@ +import { + Add, + /*Div,*/ + Mul, + Sub, +} from './arithmetic.js'; +//import { And, Not, Or, Shl, Shr, Xor } from './bitwise.js'; +//import { Eq, Lt, Lte } from './comparators.js'; +import { Return } from './control_flow.js'; +import { Instruction } from './instruction.js'; +import { + CalldataCopy, + /*Cast, Mov*/ +} from './memory.js'; +import { Opcode } from './opcodes.js'; + +/** - */ +type InstructionConstructor = new (...args: any[]) => Instruction; +/** - */ +type InstructionConstructorAndMembers = InstructionConstructor & { + /** - */ + numberOfOperands: number; +}; + +export const INSTRUCTION_SET: Map = new Map( + new Array<[Opcode, InstructionConstructorAndMembers]>( + // Compute + // Compute - Arithmetic + [Opcode.ADD, Add], + [Opcode.SUB, Sub], + [Opcode.MUL, Mul], + //[Opcode.DIV, Div], + //// Compute - Comparators + //[Opcode.EQ, Eq], + //[Opcode.LT, Lt], + //[Opcode.LTE, Lte], + //// Compute - Bitwise + //[Opcode.AND, And], + //[Opcode.OR, Or], + //[Opcode.XOR, Xor], + //[Opcode.NOT, Not], + //[Opcode.SHL, Shl], + //[Opcode.SHR, Shr], + //// Compute - Type Conversions + //[Opcode.CAST, Cast], + + //// Execution Environment + //[Opcode.ADDRESS, Address], + //[Opcode.STORAGEADDRESS, Storageaddress], + //[Opcode.ORIGIN, Origin], + //[Opcode.SENDER, Sender], + //[Opcode.PORTAL, Portal], + //[Opcode.FEEPERL1GAS, Feeperl1gas], + //[Opcode.FEEPERL2GAS, Feeperl2gas], + //[Opcode.FEEPERDAGAS, Feeperdagas], + //[Opcode.CONTRACTCALLDEPTH, Contractcalldepth], + //// Execution Environment - Globals + //[Opcode.CHAINID, Chainid], + //[Opcode.VERSION, Version], + //[Opcode.BLOCKNUMBER, Blocknumber], + //[Opcode.TIMESTAMP, Timestamp], + //[Opcode.COINBASE, Coinbase], + //[Opcode.BLOCKL1GASLIMIT, Blockl1gaslimit], + //[Opcode.BLOCKL2GASLIMIT, Blockl2gaslimit], + //[Opcode.BLOCKDAGASLIMIT, Blockdagaslimit], + // Execution Environment - Calldata + [Opcode.CALLDATACOPY, CalldataCopy], + + //// Machine State + // Machine State - Gas + //[Opcode.L1GASLEFT, L1gasleft], + //[Opcode.L2GASLEFT, L2gasleft], + //[Opcode.DAGASLEFT, Dagasleft], + //// Machine State - Internal Control Flow + //[Opcode.JUMP, Jump], + //[Opcode.JUMPI, Jumpi], + //[Opcode.INTERNALCALL, Internalcall], + //[Opcode.INTERNALRETURN, Internalreturn], + //// Machine State - Memory + //[Opcode.SET, Set], + //[Opcode.MOV, Mov], + //[Opcode.CMOV, CMov], + + //// World State + //[Opcode.BLOCKHEADERBYNUMBER, Blockheaderbynumber], + //[Opcode.SLOAD, Sload], // Public Storage + //[Opcode.SSTORE, Sstore], // Public Storage + //[Opcode.READL1TOL2MSG, Readl1tol2msg], // Messages + //[Opcode.SENDL2TOL1MSG, Sendl2tol1msg], // Messages + //[Opcode.EMITNOTEHASH, Emitnotehash], // Notes & Nullifiers + //[Opcode.EMITNULLIFIER, Emitnullifier], // Notes & Nullifiers + + //// Accrued Substate + //[Opcode.EMITUNENCRYPTEDLOG, Emitunencryptedlog], + + //// Control Flow - Contract Calls + //[Opcode.CALL, Call], + //[Opcode.STATICCALL, Staticcall], + [Opcode.RETURN, Return], + //[Opcode.REVERT, Revert], + + //// Gadgets + //[Opcode.KECCAK, Keccak], + //[Opcode.POSEIDON, Poseidon], + ), +); diff --git a/yarn-project/acir-simulator/src/avm/opcodes/memory.ts b/yarn-project/acir-simulator/src/avm/opcodes/memory.ts index 38fa560a3e6..bf14c1c235b 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/memory.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/memory.ts @@ -47,7 +47,7 @@ export class Mov implements Instruction { } /** - */ -export class CallDataCopy implements Instruction { +export class CalldataCopy implements Instruction { static type: string = 'CALLDATACOPY'; static numberOfOperands = 3; diff --git a/yarn-project/acir-simulator/src/avm/opcodes/opcodes.ts b/yarn-project/acir-simulator/src/avm/opcodes/opcodes.ts index 2a7fa5a1758..e0760e10213 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/opcodes.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/opcodes.ts @@ -1,7 +1,7 @@ /** * All AVM opcodes */ -export enum Opcodes { +export enum Opcode { // Compute // Compute - Arithmetic ADD, @@ -54,7 +54,6 @@ export enum Opcodes { JUMPI, INTERNALCALL, INTERNALRETURN, - INTERNALCALLDEPTH, // Machine State - Memory SET, MOV, diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALCALLDEPTH.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALCALLDEPTH.png new file mode 100644 index 0000000000000000000000000000000000000000..45f5b1502c358671929abc3b25f08ad87a735e94 GIT binary patch literal 3651 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 literal 0 HcmV?d00001