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 00000000000..45f5b1502c3 Binary files /dev/null and b/yellow-paper/docs/public-vm/gen/images/bit-formats/INTERNALCALLDEPTH.png differ