From f90b2cf6737f254405f48dbf7341d10d055edce3 Mon Sep 17 00:00:00 2001 From: Facundo Date: Mon, 18 Mar 2024 10:38:57 +0000 Subject: [PATCH] fix(avm-transpiler): RETURN is direct (#5277) * Brillig's `STOP` uses direct memory access, so it should be transpiled with `ALL_DIRECT`. * Implement indirect support for `RETURN`, `REVERT`, `CALLDATACOPY` for the future. cc @sirasistant --- avm-transpiler/src/transpile.rs | 2 +- .../simulator/src/avm/opcodes/external_calls.ts | 12 +++++++----- yarn-project/simulator/src/avm/opcodes/memory.ts | 4 +++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 17c6cecd8b3..4af9ab4078e 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -194,7 +194,7 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { BrilligOpcode::Stop { return_data_offset, return_data_size } => { avm_instrs.push(AvmInstruction { opcode: AvmOpcode::RETURN, - indirect: Some(ZEROTH_OPERAND_INDIRECT), + indirect: Some(ALL_DIRECT), operands: vec![ AvmOperand::U32 { value: *return_data_offset as u32 }, AvmOperand::U32 { value: *return_data_size as u32 }, diff --git a/yarn-project/simulator/src/avm/opcodes/external_calls.ts b/yarn-project/simulator/src/avm/opcodes/external_calls.ts index 0c1f5abdc0b..9a8e5b6d69c 100644 --- a/yarn-project/simulator/src/avm/opcodes/external_calls.ts +++ b/yarn-project/simulator/src/avm/opcodes/external_calls.ts @@ -165,14 +165,16 @@ export class Return extends Instruction { } async execute(context: AvmContext): Promise { - const output = context.machineState.memory.getSlice(this.returnOffset, this.copySize).map(word => word.toFr()); + const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], context.machineState.memory); + + const output = context.machineState.memory.getSlice(returnOffset, this.copySize).map(word => word.toFr()); context.machineState.return(output); } } export class Revert extends Instruction { - static type: string = 'RETURN'; + static type: string = 'REVERT'; static readonly opcode: Opcode = Opcode.REVERT; // Informs (de)serialization. See Instruction.deserialize. static readonly wireFormat: OperandType[] = [ @@ -187,9 +189,9 @@ export class Revert extends Instruction { } async execute(context: AvmContext): Promise { - const output = context.machineState.memory - .getSlice(this.returnOffset, this.returnOffset + this.retSize) - .map(word => word.toFr()); + const [returnOffset] = Addressing.fromWire(this.indirect).resolve([this.returnOffset], context.machineState.memory); + + const output = context.machineState.memory.getSlice(returnOffset, this.retSize).map(word => word.toFr()); context.machineState.revert(output); } diff --git a/yarn-project/simulator/src/avm/opcodes/memory.ts b/yarn-project/simulator/src/avm/opcodes/memory.ts index 4f8f28e1f86..36bd9a18995 100644 --- a/yarn-project/simulator/src/avm/opcodes/memory.ts +++ b/yarn-project/simulator/src/avm/opcodes/memory.ts @@ -183,11 +183,13 @@ export class CalldataCopy extends Instruction { } async execute(context: AvmContext): Promise { + const [dstOffset] = Addressing.fromWire(this.indirect).resolve([this.dstOffset], context.machineState.memory); + const transformedData = context.environment.calldata .slice(this.cdOffset, this.cdOffset + this.copySize) .map(f => new Field(f)); - context.machineState.memory.setSlice(this.dstOffset, transformedData); + context.machineState.memory.setSlice(dstOffset, transformedData); context.machineState.incrementPc(); }