Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(avm): complete SET instruction #4378

Merged
merged 1 commit into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the instruction spec in yellow paper, the value should be of type corresponding to TypeTag. At least, if serialized in this way, the truncation should never happen. I would rather return an error here.

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming of routine "integralFromTag" gave me the impression that we cast a tag into an int. Maybe renaming like "integralBaseOnTag" would be a bit more clear.

machineState.memory.set(this.dstOffset, res);

this.incrementPc(machineState);
Expand Down
Loading