Skip to content

Commit

Permalink
feat(avm): complete SET instruction (AztecProtocol#4378)
Browse files Browse the repository at this point in the history
This pull request completes the implementation of the SET instruction
and adds handling for invalid tags. It also includes necessary tests for
the new functionality.

SET takes the given u128, casts it to the provided inTag type, and sets
the memory.

Ref: AztecProtocol#4267, AztecProtocol#4271.
  • Loading branch information
fcarreiro authored Feb 2, 2024
1 parent 3b4dfd4 commit adb2af6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
22 changes: 22 additions & 0 deletions yarn-project/acir-simulator/src/avm/opcodes/memory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { AvmMachineState } from '../avm_machine_state.js';
import { Field, TypeTag, Uint8, Uint16, Uint32, Uint64, Uint128 } from '../avm_memory_types.js';
import { initExecutionEnvironment } from '../fixtures/index.js';
import { AvmJournal } from '../journal/journal.js';
import { InstructionExecutionError } from './instruction.js';
import { CMov, CalldataCopy, Cast, Mov, Set } from './memory.js';

describe('Memory instructions', () => {
Expand Down Expand Up @@ -64,6 +65,27 @@ describe('Memory instructions', () => {
expect(actual).toEqual(new Uint32(1234n));
expect(tag).toEqual(TypeTag.UINT32);
});

it('should correctly set value and tag (truncating)', async () => {
await new Set(/*indirect=*/ 0, /*inTag=*/ TypeTag.UINT16, /*value=*/ 0x12345678n, /*offset=*/ 1).execute(
machineState,
journal,
);

const actual = machineState.memory.get(1);
const tag = machineState.memory.getTag(1);

expect(actual).toEqual(new Uint16(0x5678));
expect(tag).toEqual(TypeTag.UINT16);
});

it('should throw if tag is FIELD, UNINITIALIZED, INVALID', async () => {
for (const tag of [TypeTag.FIELD, TypeTag.UNINITIALIZED, TypeTag.INVALID]) {
await expect(
new Set(/*indirect=*/ 0, /*inTag=*/ tag, /*value=*/ 1234n, /*offset=*/ 1).execute(machineState, journal),
).rejects.toThrow(InstructionExecutionError);
}
});
});

describe('CAST', () => {
Expand Down
8 changes: 6 additions & 2 deletions yarn-project/acir-simulator/src/avm/opcodes/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AvmMachineState } from '../avm_machine_state.js';
import { Field, TaggedMemory, TypeTag } from '../avm_memory_types.js';
import { AvmJournal } from '../journal/index.js';
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
import { Instruction } from './instruction.js';
import { Instruction, InstructionExecutionError } from './instruction.js';
import { TwoOperandInstruction } from './instruction_impl.js';

export class Set extends Instruction {
Expand All @@ -22,8 +22,12 @@ export class Set extends Instruction {
}

async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise<void> {
const res = TaggedMemory.integralFromTag(this.value, this.inTag);
// Per the YP, the tag cannot be a field.
if ([TypeTag.FIELD, TypeTag.UNINITIALIZED, TypeTag.INVALID].includes(this.inTag)) {
throw new InstructionExecutionError(`Invalid tag ${TypeTag[this.inTag]} for SET.`);
}

const res = TaggedMemory.integralFromTag(this.value, this.inTag);
machineState.memory.set(this.dstOffset, res);

this.incrementPc(machineState);
Expand Down

0 comments on commit adb2af6

Please sign in to comment.