From 6ca61ab1f006c29bac1174e3d77ee28422f25ea9 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Fri, 26 Jan 2024 17:20:24 +0000 Subject: [PATCH 1/3] fix(avm): fix usage of Fr with tagged memory --- .../src/avm/avm_memory_types.ts | 57 ++++++++++--------- .../src/avm/opcodes/external_calls.test.ts | 12 ++-- .../src/avm/opcodes/external_calls.ts | 10 ++-- .../src/avm/opcodes/storage.test.ts | 2 +- .../acir-simulator/src/avm/opcodes/storage.ts | 8 ++- 5 files changed, 49 insertions(+), 40 deletions(-) diff --git a/yarn-project/acir-simulator/src/avm/avm_memory_types.ts b/yarn-project/acir-simulator/src/avm/avm_memory_types.ts index 69ed95c4a66..8d6d240c922 100644 --- a/yarn-project/acir-simulator/src/avm/avm_memory_types.ts +++ b/yarn-project/acir-simulator/src/avm/avm_memory_types.ts @@ -2,31 +2,35 @@ import { Fr } from '@aztec/foundation/fields'; import { strict as assert } from 'assert'; -export interface MemoryValue { - add(rhs: MemoryValue): MemoryValue; - sub(rhs: MemoryValue): MemoryValue; - mul(rhs: MemoryValue): MemoryValue; - div(rhs: MemoryValue): MemoryValue; +export abstract class MemoryValue { + public abstract add(rhs: MemoryValue): MemoryValue; + public abstract sub(rhs: MemoryValue): MemoryValue; + public abstract mul(rhs: MemoryValue): MemoryValue; + public abstract div(rhs: MemoryValue): MemoryValue; + + // We need this to be able to build an instance of the subclasses. + public abstract build(n: bigint): MemoryValue; // Use sparingly. - toBigInt(): bigint; + public abstract toBigInt(): bigint; } -export interface IntegralValue extends MemoryValue { - shl(rhs: IntegralValue): IntegralValue; - shr(rhs: IntegralValue): IntegralValue; - and(rhs: IntegralValue): IntegralValue; - or(rhs: IntegralValue): IntegralValue; - xor(rhs: IntegralValue): IntegralValue; - not(): IntegralValue; +export abstract class IntegralValue extends MemoryValue { + public abstract shl(rhs: IntegralValue): IntegralValue; + public abstract shr(rhs: IntegralValue): IntegralValue; + public abstract and(rhs: IntegralValue): IntegralValue; + public abstract or(rhs: IntegralValue): IntegralValue; + public abstract xor(rhs: IntegralValue): IntegralValue; + public abstract not(): IntegralValue; } // TODO: Optimize calculation of mod, etc. Can only do once per class? -abstract class UnsignedInteger implements IntegralValue { +abstract class UnsignedInteger extends IntegralValue { private readonly bitmask: bigint; private readonly mod: bigint; protected constructor(private n: bigint, private bits: bigint) { + super(); assert(bits > 0); // x % 2^n == x & (2^n - 1) this.mod = 1n << bits; @@ -34,9 +38,7 @@ abstract class UnsignedInteger implements IntegralValue { assert(n < this.mod); } - // We need this to be able to build an instance of the subclass - // and not of type UnsignedInteger. - protected abstract build(n: bigint): UnsignedInteger; + public abstract build(n: bigint): UnsignedInteger; public add(rhs: UnsignedInteger): UnsignedInteger { assert(this.bits == rhs.bits); @@ -93,10 +95,6 @@ abstract class UnsignedInteger implements IntegralValue { public toBigInt(): bigint { return this.n; } - - public equals(rhs: UnsignedInteger) { - return this.bits == rhs.bits && this.toBigInt() == rhs.toBigInt(); - } } export class Uint8 extends UnsignedInteger { @@ -104,7 +102,7 @@ export class Uint8 extends UnsignedInteger { super(BigInt(n), 8n); } - protected build(n: bigint): Uint8 { + public build(n: bigint): Uint8 { return new Uint8(n); } } @@ -114,7 +112,7 @@ export class Uint16 extends UnsignedInteger { super(BigInt(n), 16n); } - protected build(n: bigint): Uint16 { + public build(n: bigint): Uint16 { return new Uint16(n); } } @@ -124,7 +122,7 @@ export class Uint32 extends UnsignedInteger { super(BigInt(n), 32n); } - protected build(n: bigint): Uint32 { + public build(n: bigint): Uint32 { return new Uint32(n); } } @@ -134,7 +132,7 @@ export class Uint64 extends UnsignedInteger { super(BigInt(n), 64n); } - protected build(n: bigint): Uint64 { + public build(n: bigint): Uint64 { return new Uint64(n); } } @@ -144,19 +142,24 @@ export class Uint128 extends UnsignedInteger { super(BigInt(n), 128n); } - protected build(n: bigint): Uint128 { + public build(n: bigint): Uint128 { return new Uint128(n); } } -export class Field implements MemoryValue { +export class Field extends MemoryValue { public static readonly MODULUS: bigint = Fr.MODULUS; private readonly rep: Fr; constructor(v: number | bigint | Fr) { + super(); this.rep = new Fr(v); } + public build(n: bigint): Field { + return new Field(n); + } + public add(rhs: Field): Field { return new Field(this.rep.add(rhs.rep)); } diff --git a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts index 7a2f74df0e4..8f6fd076038 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.test.ts @@ -40,7 +40,7 @@ describe('External Calls', () => { const addr = new Fr(123456n); const argsOffset = 2; - const args = [new Fr(1n), new Fr(2n), new Fr(3n)]; + const args = [new Field(1n), new Field(2n), new Field(3n)]; const argsSize = args.length; const retOffset = 8; @@ -48,8 +48,8 @@ describe('External Calls', () => { const successOffset = 7; - machineState.memory.set(0, gas); - machineState.memory.set(1, addr); + machineState.memory.set(0, new Field(gas)); + machineState.memory.set(1, new Field(addr)); machineState.memory.setSlice(2, args); const otherContextInstructions: [Opcode, any[]][] = [ @@ -72,10 +72,10 @@ describe('External Calls', () => { await instruction.execute(machineState, journal); const successValue = machineState.memory.get(successOffset); - expect(successValue).toEqual(new Fr(1n)); + expect(successValue).toEqual(new Field(1n)); const retValue = machineState.memory.getSlice(retOffset, retSize); - expect(retValue).toEqual([new Fr(1n), new Fr(2n)]); + expect(retValue).toEqual([new Field(1n), new Field(2n)]); // Check that the storage call has been merged into the parent journal const { storageWrites } = journal.flush(); @@ -126,7 +126,7 @@ describe('External Calls', () => { // No revert has occurred, but the nested execution has failed const successValue = machineState.memory.get(successOffset); - expect(successValue).toEqual(new Fr(0n)); + expect(successValue).toEqual(new Field(0n)); }); }); }); diff --git a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts index fc98f6c780c..280b1284f02 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/external_calls.ts @@ -39,10 +39,11 @@ export class Call extends Instruction { // We only take as much data as was specified in the return size -> TODO: should we be reverting here const returnData = returnObject.output.slice(0, this.retSize); + const convertedReturnData = returnData.map(f => new Field(f)); // Write our return data into memory - machineState.memory.set(this.successOffset, new Fr(success)); - machineState.memory.setSlice(this.retOffset, returnData); + machineState.memory.set(this.successOffset, new Field(success ? 1 : 0)); + machineState.memory.setSlice(this.retOffset, convertedReturnData); if (success) { avmContext.mergeJournal(); @@ -84,10 +85,11 @@ export class StaticCall extends Instruction { // We only take as much data as was specified in the return size -> TODO: should we be reverting here const returnData = returnObject.output.slice(0, this.retSize); + const convertedReturnData = returnData.map(f => new Field(f)); // Write our return data into memory - machineState.memory.set(this.successOffset, new Fr(success)); - machineState.memory.setSlice(this.retOffset, returnData); + machineState.memory.set(this.successOffset, new Field(success ? 1 : 0)); + machineState.memory.setSlice(this.retOffset, convertedReturnData); if (success) { avmContext.mergeJournal(); diff --git a/yarn-project/acir-simulator/src/avm/opcodes/storage.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/storage.test.ts index 47bc4433862..e62b0abc561 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/storage.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/storage.test.ts @@ -63,6 +63,6 @@ describe('Storage Instructions', () => { expect(journal.readStorage).toBeCalledWith(address, new Fr(a.toBigInt())); const actual = machineState.memory.get(1); - expect(actual).toEqual(expectedResult); + expect(actual).toEqual(new Field(expectedResult)); }); }); diff --git a/yarn-project/acir-simulator/src/avm/opcodes/storage.ts b/yarn-project/acir-simulator/src/avm/opcodes/storage.ts index e8f078f7909..419cbecc1da 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/storage.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/storage.ts @@ -1,6 +1,7 @@ import { Fr } from '@aztec/foundation/fields'; import { AvmMachineState } from '../avm_machine_state.js'; +import { Field } from '../avm_memory_types.js'; import { AvmInterpreterError } from '../interpreter/interpreter.js'; import { AvmJournal } from '../journal/journal.js'; import { Instruction } from './instruction.js'; @@ -44,9 +45,12 @@ export class SLoad extends Instruction { async execute(machineState: AvmMachineState, journal: AvmJournal): Promise { const slot = machineState.memory.get(this.slotOffset); - const data = journal.readStorage(machineState.executionEnvironment.storageAddress, new Fr(slot.toBigInt())); + const data: Fr = await journal.readStorage( + machineState.executionEnvironment.storageAddress, + new Fr(slot.toBigInt()), + ); - machineState.memory.set(this.destOffset, await data); + machineState.memory.set(this.destOffset, new Field(data)); this.incrementPc(machineState); } From 5c9ef61a33eb1c44446f5511ba4ee979f268907a Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Fri, 26 Jan 2024 13:04:19 +0000 Subject: [PATCH 2/3] feat(avm): implement comparator opcodes --- .../src/avm/avm_memory_types.ts | 21 +++ .../src/avm/opcodes/comparators.test.ts | 147 ++++++++++++++++++ .../src/avm/opcodes/comparators.ts | 29 ++-- .../src/avm/opcodes/control_flow.test.ts | 6 +- 4 files changed, 190 insertions(+), 13 deletions(-) create mode 100644 yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts diff --git a/yarn-project/acir-simulator/src/avm/avm_memory_types.ts b/yarn-project/acir-simulator/src/avm/avm_memory_types.ts index 8d6d240c922..9f831bfd21e 100644 --- a/yarn-project/acir-simulator/src/avm/avm_memory_types.ts +++ b/yarn-project/acir-simulator/src/avm/avm_memory_types.ts @@ -8,6 +8,9 @@ export abstract class MemoryValue { public abstract mul(rhs: MemoryValue): MemoryValue; public abstract div(rhs: MemoryValue): MemoryValue; + public abstract equals(rhs: MemoryValue): boolean; + public abstract lt(rhs: MemoryValue): boolean; + // We need this to be able to build an instance of the subclasses. public abstract build(n: bigint): MemoryValue; @@ -92,6 +95,16 @@ abstract class UnsignedInteger extends IntegralValue { return this.build(~this.n & this.bitmask); } + public equals(rhs: UnsignedInteger): boolean { + assert(this.bits == rhs.bits); + return this.n === rhs.n; + } + + public lt(rhs: UnsignedInteger): boolean { + assert(this.bits == rhs.bits); + return this.n < rhs.n; + } + public toBigInt(): bigint { return this.n; } @@ -176,6 +189,14 @@ export class Field extends MemoryValue { return new Field(this.rep.div(rhs.rep)); } + public equals(rhs: Field): boolean { + return this.rep.equals(rhs.rep); + } + + public lt(rhs: Field): boolean { + return this.rep.lt(rhs.rep); + } + public toBigInt(): bigint { return this.rep.toBigInt(); } diff --git a/yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts new file mode 100644 index 00000000000..b3ea94c62ca --- /dev/null +++ b/yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts @@ -0,0 +1,147 @@ +import { MockProxy, mock } from 'jest-mock-extended'; + +import { AvmMachineState } from '../avm_machine_state.js'; +import { Field, TypeTag, Uint16, Uint32 } from '../avm_memory_types.js'; +import { initExecutionEnvironment } from '../fixtures/index.js'; +import { AvmJournal } from '../journal/journal.js'; +import { Eq, Lt, Lte } from './comparators.js'; +import { InstructionExecutionError } from './instruction.js'; + +describe('Comparators', () => { + let machineState: AvmMachineState; + let journal: MockProxy; + + beforeEach(async () => { + machineState = new AvmMachineState(initExecutionEnvironment()); + journal = mock(); + }); + + describe('Eq', () => { + it('Works on integral types', async () => { + machineState.memory.setSlice(0, [new Uint32(1), new Uint32(2), new Uint32(3), new Uint32(1)]); + + [ + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT32), + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 11, TypeTag.UINT32), + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 3, /*dstOffset=*/ 12, TypeTag.UINT32), + ].forEach(i => i.execute(machineState, journal)); + + const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); + expect(actual).toEqual([new Uint32(0), new Uint32(0), new Uint32(1)]); + }); + + it('Works on field elements', async () => { + machineState.memory.setSlice(0, [new Field(1), new Field(2), new Field(3), new Field(1)]); + + [ + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 11, TypeTag.FIELD), + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 3, /*dstOffset=*/ 12, TypeTag.FIELD), + ].forEach(i => i.execute(machineState, journal)); + + const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); + expect(actual).toEqual([new Field(0), new Field(0), new Field(1)]); + }); + + it('InTag is checked', async () => { + machineState.memory.setSlice(0, [new Field(1), new Uint32(2), new Uint16(3)]); + + const ops = [ + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), + new Eq(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT32), + new Eq(/*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT16), + new Eq(/*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT16), + ]; + + for (const o of ops) { + await expect(() => o.execute(machineState, journal)).rejects.toThrow(InstructionExecutionError); + } + }); + }); + + describe('Lt', () => { + it('Works on integral types', async () => { + machineState.memory.setSlice(0, [new Uint32(1), new Uint32(2), new Uint32(0)]); + + [ + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.UINT32), + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.UINT32), + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.UINT32), + ].forEach(i => i.execute(machineState, journal)); + + const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); + expect(actual).toEqual([new Uint32(0), new Uint32(1), new Uint32(0)]); + }); + + it('Works on field elements', async () => { + machineState.memory.setSlice(0, [new Field(1), new Field(2), new Field(0)]); + + [ + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.FIELD), + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.FIELD), + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.FIELD), + ].forEach(i => i.execute(machineState, journal)); + + const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); + expect(actual).toEqual([new Field(0), new Field(1), new Field(0)]); + }); + + it('InTag is checked', async () => { + machineState.memory.setSlice(0, [new Field(1), new Uint32(2), new Uint16(3)]); + + const ops = [ + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), + new Lt(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT32), + new Lt(/*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT16), + new Lt(/*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT16), + ]; + + for (const o of ops) { + await expect(() => o.execute(machineState, journal)).rejects.toThrow(InstructionExecutionError); + } + }); + }); + + describe('Lte', () => { + it('Works on integral types', async () => { + machineState.memory.setSlice(0, [new Uint32(1), new Uint32(2), new Uint32(0)]); + + [ + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.UINT32), + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.UINT32), + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.UINT32), + ].forEach(i => i.execute(machineState, journal)); + + const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); + expect(actual).toEqual([new Uint32(1), new Uint32(1), new Uint32(0)]); + }); + + it('Works on field elements', async () => { + machineState.memory.setSlice(0, [new Field(1), new Field(2), new Field(0)]); + + [ + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.FIELD), + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.FIELD), + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.FIELD), + ].forEach(i => i.execute(machineState, journal)); + + const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); + expect(actual).toEqual([new Field(1), new Field(1), new Field(0)]); + }); + + it('InTag is checked', async () => { + machineState.memory.setSlice(0, [new Field(1), new Uint32(2), new Uint16(3)]); + + const ops = [ + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), + new Lte(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT32), + new Lte(/*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT16), + new Lte(/*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT16), + ]; + + for (const o of ops) { + await expect(() => o.execute(machineState, journal)).rejects.toThrow(InstructionExecutionError); + } + }); + }); +}); diff --git a/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts b/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts index 8bdb406f9c6..db8f735cea8 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts @@ -1,5 +1,5 @@ import { AvmMachineState } from '../avm_machine_state.js'; -import { Field } from '../avm_memory_types.js'; +import { TypeTag } from '../avm_memory_types.js'; import { AvmJournal } from '../journal/index.js'; import { Instruction } from './instruction.js'; @@ -7,16 +7,19 @@ export class Eq extends Instruction { static type: string = 'EQ'; static numberOfOperands = 3; - constructor(private aOffset: number, private bOffset: number, private destOffset: number) { + constructor(private aOffset: number, private bOffset: number, private dstOffset: number, private inTag: TypeTag) { super(); } async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { + Instruction.checkTags(machineState, this.inTag, this.aOffset, this.bOffset); + const a = machineState.memory.get(this.aOffset); const b = machineState.memory.get(this.bOffset); - const dest = new Field(a.toBigInt() == b.toBigInt() ? 1 : 0); - machineState.memory.set(this.destOffset, dest); + // Result will be of the same type as 'a'. + const dest = a.build(a.equals(b) ? 1n : 0n); + machineState.memory.set(this.dstOffset, dest); this.incrementPc(machineState); } @@ -26,16 +29,19 @@ export class Lt extends Instruction { static type: string = 'Lt'; static numberOfOperands = 3; - constructor(private aOffset: number, private bOffset: number, private destOffset: number) { + constructor(private aOffset: number, private bOffset: number, private dstOffset: number, private inTag: TypeTag) { super(); } async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { + Instruction.checkTags(machineState, this.inTag, this.aOffset, this.bOffset); + const a = machineState.memory.get(this.aOffset); const b = machineState.memory.get(this.bOffset); - const dest = new Field(a.toBigInt() < b.toBigInt() ? 1 : 0); - machineState.memory.set(this.destOffset, dest); + // Result will be of the same type as 'a'. + const dest = a.build(a.lt(b) ? 1n : 0n); + machineState.memory.set(this.dstOffset, dest); this.incrementPc(machineState); } @@ -45,16 +51,19 @@ export class Lte extends Instruction { static type: string = 'LTE'; static numberOfOperands = 3; - constructor(private aOffset: number, private bOffset: number, private destOffset: number) { + constructor(private aOffset: number, private bOffset: number, private dstOffset: number, private inTag: TypeTag) { super(); } async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { + Instruction.checkTags(machineState, this.inTag, this.aOffset, this.bOffset); + const a = machineState.memory.get(this.aOffset); const b = machineState.memory.get(this.bOffset); - const dest = new Field(a.toBigInt() < b.toBigInt() ? 1 : 0); - machineState.memory.set(this.destOffset, dest); + // Result will be of the same type as 'a'. + const dest = a.build(a.equals(b) || a.lt(b) ? 1n : 0n); + machineState.memory.set(this.dstOffset, dest); this.incrementPc(machineState); } diff --git a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts index ca4cdd45a5c..d4b8d28b1f9 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts @@ -121,9 +121,9 @@ describe('Control Flow Opcodes', () => { new Add(0, 1, 2), new Sub(0, 1, 2), new Mul(0, 1, 2), - new Lt(0, 1, 2), - new Lte(0, 1, 2), - new Eq(0, 1, 2), + new Lt(0, 1, 2, TypeTag.UINT16), + new Lte(0, 1, 2, TypeTag.UINT16), + new Eq(0, 1, 2, TypeTag.UINT16), new Xor(0, 1, 2, TypeTag.UINT16), new And(0, 1, 2, TypeTag.UINT16), new Or(0, 1, 2, TypeTag.UINT16), From 6fbf124ea646b80b9052602cde565ad0d292adca Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Mon, 29 Jan 2024 09:57:33 +0000 Subject: [PATCH 3/3] moving inTag to avoid breaking David's cleanup --- .../src/avm/opcodes/comparators.test.ts | 60 +++++++++---------- .../src/avm/opcodes/comparators.ts | 6 +- .../src/avm/opcodes/control_flow.test.ts | 6 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts index b3ea94c62ca..ff604dbf2cb 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/comparators.test.ts @@ -21,9 +21,9 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Uint32(1), new Uint32(2), new Uint32(3), new Uint32(1)]); [ - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT32), - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 11, TypeTag.UINT32), - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 3, /*dstOffset=*/ 12, TypeTag.UINT32), + new Eq(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10), + new Eq(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 11), + new Eq(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 3, /*dstOffset=*/ 12), ].forEach(i => i.execute(machineState, journal)); const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); @@ -34,9 +34,9 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Field(1), new Field(2), new Field(3), new Field(1)]); [ - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 11, TypeTag.FIELD), - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 3, /*dstOffset=*/ 12, TypeTag.FIELD), + new Eq(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10), + new Eq(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 11), + new Eq(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 3, /*dstOffset=*/ 12), ].forEach(i => i.execute(machineState, journal)); const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); @@ -47,10 +47,10 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Field(1), new Uint32(2), new Uint16(3)]); const ops = [ - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), - new Eq(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT32), - new Eq(/*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT16), - new Eq(/*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT16), + new Eq(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10), + new Eq(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10), + new Eq(TypeTag.UINT16, /*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10), + new Eq(TypeTag.UINT16, /*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10), ]; for (const o of ops) { @@ -64,9 +64,9 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Uint32(1), new Uint32(2), new Uint32(0)]); [ - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.UINT32), - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.UINT32), - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.UINT32), + new Lt(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10), + new Lt(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11), + new Lt(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12), ].forEach(i => i.execute(machineState, journal)); const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); @@ -77,9 +77,9 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Field(1), new Field(2), new Field(0)]); [ - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.FIELD), - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.FIELD), - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.FIELD), + new Lt(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10), + new Lt(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11), + new Lt(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12), ].forEach(i => i.execute(machineState, journal)); const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); @@ -90,10 +90,10 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Field(1), new Uint32(2), new Uint16(3)]); const ops = [ - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), - new Lt(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT32), - new Lt(/*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT16), - new Lt(/*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT16), + new Lt(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10), + new Lt(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10), + new Lt(TypeTag.UINT16, /*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10), + new Lt(TypeTag.UINT16, /*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10), ]; for (const o of ops) { @@ -107,9 +107,9 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Uint32(1), new Uint32(2), new Uint32(0)]); [ - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.UINT32), - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.UINT32), - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.UINT32), + new Lte(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10), + new Lte(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11), + new Lte(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12), ].forEach(i => i.execute(machineState, journal)); const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); @@ -120,9 +120,9 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Field(1), new Field(2), new Field(0)]); [ - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10, TypeTag.FIELD), - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11, TypeTag.FIELD), - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12, TypeTag.FIELD), + new Lte(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 10), + new Lte(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 11), + new Lte(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 12), ].forEach(i => i.execute(machineState, journal)); const actual = machineState.memory.getSlice(/*offset=*/ 10, /*size=*/ 4); @@ -133,10 +133,10 @@ describe('Comparators', () => { machineState.memory.setSlice(0, [new Field(1), new Uint32(2), new Uint16(3)]); const ops = [ - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.FIELD), - new Lte(/*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT32), - new Lte(/*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10, TypeTag.UINT16), - new Lte(/*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10, TypeTag.UINT16), + new Lte(TypeTag.FIELD, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 10), + new Lte(TypeTag.UINT32, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 10), + new Lte(TypeTag.UINT16, /*aOffset=*/ 1, /*bOffset=*/ 2, /*dstOffset=*/ 10), + new Lte(TypeTag.UINT16, /*aOffset=*/ 1, /*bOffset=*/ 1, /*dstOffset=*/ 10), ]; for (const o of ops) { diff --git a/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts b/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts index db8f735cea8..f89d450dbb9 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/comparators.ts @@ -7,7 +7,7 @@ export class Eq extends Instruction { static type: string = 'EQ'; static numberOfOperands = 3; - constructor(private aOffset: number, private bOffset: number, private dstOffset: number, private inTag: TypeTag) { + constructor(private inTag: TypeTag, private aOffset: number, private bOffset: number, private dstOffset: number) { super(); } @@ -29,7 +29,7 @@ export class Lt extends Instruction { static type: string = 'Lt'; static numberOfOperands = 3; - constructor(private aOffset: number, private bOffset: number, private dstOffset: number, private inTag: TypeTag) { + constructor(private inTag: TypeTag, private aOffset: number, private bOffset: number, private dstOffset: number) { super(); } @@ -51,7 +51,7 @@ export class Lte extends Instruction { static type: string = 'LTE'; static numberOfOperands = 3; - constructor(private aOffset: number, private bOffset: number, private dstOffset: number, private inTag: TypeTag) { + constructor(private inTag: TypeTag, private aOffset: number, private bOffset: number, private dstOffset: number) { super(); } diff --git a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts index d4b8d28b1f9..973655279e6 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts @@ -121,9 +121,9 @@ describe('Control Flow Opcodes', () => { new Add(0, 1, 2), new Sub(0, 1, 2), new Mul(0, 1, 2), - new Lt(0, 1, 2, TypeTag.UINT16), - new Lte(0, 1, 2, TypeTag.UINT16), - new Eq(0, 1, 2, TypeTag.UINT16), + new Lt(TypeTag.UINT16, 0, 1, 2), + new Lte(TypeTag.UINT16, 0, 1, 2), + new Eq(TypeTag.UINT16, 0, 1, 2), new Xor(0, 1, 2, TypeTag.UINT16), new And(0, 1, 2, TypeTag.UINT16), new Or(0, 1, 2, TypeTag.UINT16),