@aztec/simulator 0.86.0-starknet.1 → 0.87.0-nightly.20250521
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/common/errors.d.ts.map +1 -1
- package/dest/private/acvm/acvm.d.ts +0 -2
- package/dest/private/acvm/acvm.d.ts.map +1 -1
- package/dest/private/acvm/acvm.js +1 -1
- package/dest/private/acvm/deserialize.d.ts +0 -2
- package/dest/private/acvm/deserialize.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.d.ts +2 -2
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.js +30 -33
- package/dest/private/acvm/oracle/typed_oracle.d.ts +1 -3
- package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/private/acvm/serialize.d.ts +8 -2
- package/dest/private/acvm/serialize.d.ts.map +1 -1
- package/dest/private/acvm/serialize.js +26 -0
- package/dest/private/index.d.ts +3 -0
- package/dest/private/index.d.ts.map +1 -1
- package/dest/private/index.js +3 -0
- package/dest/private/providers/acvm_native.d.ts +0 -2
- package/dest/private/providers/acvm_native.d.ts.map +1 -1
- package/dest/private/providers/acvm_native.js +1 -1
- package/dest/private/providers/circuit_recording/circuit_recorder.d.ts +0 -2
- package/dest/private/providers/circuit_recording/circuit_recorder.d.ts.map +1 -1
- package/dest/private/providers/simulation_provider.js +2 -2
- package/dest/private/simulator.d.ts.map +1 -1
- package/dest/private/utility_execution_oracle.d.ts +0 -2
- package/dest/private/utility_execution_oracle.d.ts.map +1 -1
- package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
- package/dest/public/avm/avm_contract_call_result.js +2 -2
- package/dest/public/avm/avm_execution_environment.d.ts +2 -1
- package/dest/public/avm/avm_execution_environment.d.ts.map +1 -1
- package/dest/public/avm/avm_execution_environment.js +4 -2
- package/dest/public/avm/avm_gas.d.ts +0 -15
- package/dest/public/avm/avm_gas.d.ts.map +1 -1
- package/dest/public/avm/avm_gas.js +0 -18
- package/dest/public/avm/avm_memory_types.d.ts +84 -86
- package/dest/public/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.d.ts +1 -3
- package/dest/public/avm/avm_simulator.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.js +3 -3
- package/dest/public/avm/avm_simulator_interface.d.ts +0 -2
- package/dest/public/avm/avm_simulator_interface.d.ts.map +1 -1
- package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
- package/dest/public/avm/fixtures/initializers.js +1 -1
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/public/avm/opcodes/accrued_substate.js +7 -7
- package/dest/public/avm/opcodes/addressing_mode.d.ts +7 -6
- package/dest/public/avm/opcodes/addressing_mode.d.ts.map +1 -1
- package/dest/public/avm/opcodes/addressing_mode.js +18 -15
- package/dest/public/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/public/avm/opcodes/arithmetic.js +1 -1
- package/dest/public/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/public/avm/opcodes/bitwise.js +2 -2
- package/dest/public/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/public/avm/opcodes/comparators.js +1 -1
- package/dest/public/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/public/avm/opcodes/contract.js +1 -1
- package/dest/public/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/public/avm/opcodes/control_flow.js +1 -1
- package/dest/public/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/public/avm/opcodes/conversion.js +1 -1
- package/dest/public/avm/opcodes/ec_add.d.ts.map +1 -1
- package/dest/public/avm/opcodes/ec_add.js +1 -1
- package/dest/public/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/public/avm/opcodes/environment_getters.js +1 -1
- package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/public/avm/opcodes/external_calls.js +4 -4
- package/dest/public/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/public/avm/opcodes/hashing.js +3 -3
- package/dest/public/avm/opcodes/instruction.d.ts +0 -2
- package/dest/public/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/public/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/public/avm/opcodes/memory.js +6 -6
- package/dest/public/avm/opcodes/misc.d.ts.map +1 -1
- package/dest/public/avm/opcodes/misc.js +18 -11
- package/dest/public/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/public/avm/opcodes/storage.js +2 -2
- package/dest/public/avm/serialization/buffer_cursor.d.ts +0 -2
- package/dest/public/avm/serialization/buffer_cursor.d.ts.map +1 -1
- package/dest/public/avm/serialization/bytecode_serialization.d.ts +0 -2
- package/dest/public/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/public/avm/serialization/instruction_serialization.d.ts +0 -2
- package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +1 -1
- package/dest/public/fixtures/utils.d.ts.map +1 -1
- package/dest/public/fixtures/utils.js +19 -26
- package/dest/public/hinting_db_sources.d.ts +0 -2
- package/dest/public/hinting_db_sources.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.d.ts +3 -5
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +8 -5
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +1 -1
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +3 -3
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +5 -9
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +2 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +15 -3
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +1 -1
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +2 -2
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +5 -5
- package/dest/public/state_manager/nullifiers.d.ts.map +1 -1
- package/dest/public/state_manager/public_storage.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.d.ts +6 -2
- package/dest/public/state_manager/state_manager.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.js +6 -0
- package/dest/public/unique_class_ids.d.ts.map +1 -1
- package/dest/test/utils.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/private/acvm/acvm.ts +1 -1
- package/src/private/acvm/oracle/oracle.ts +38 -31
- package/src/private/acvm/oracle/typed_oracle.ts +1 -1
- package/src/private/acvm/serialize.ts +35 -0
- package/src/private/index.ts +3 -0
- package/src/private/pick_notes.ts +4 -4
- package/src/private/providers/acvm_native.ts +6 -2
- package/src/private/providers/simulation_provider.ts +2 -2
- package/src/private/simulator.ts +4 -1
- package/src/public/avm/avm_contract_call_result.ts +2 -2
- package/src/public/avm/avm_execution_environment.ts +7 -1
- package/src/public/avm/avm_gas.ts +0 -20
- package/src/public/avm/avm_simulator.ts +3 -1
- package/src/public/avm/fixtures/initializers.ts +1 -0
- package/src/public/avm/opcodes/accrued_substate.ts +31 -11
- package/src/public/avm/opcodes/addressing_mode.ts +23 -20
- package/src/public/avm/opcodes/arithmetic.ts +2 -1
- package/src/public/avm/opcodes/bitwise.ts +9 -3
- package/src/public/avm/opcodes/comparators.ts +2 -1
- package/src/public/avm/opcodes/contract.ts +2 -1
- package/src/public/avm/opcodes/control_flow.ts +7 -2
- package/src/public/avm/opcodes/conversion.ts +2 -1
- package/src/public/avm/opcodes/ec_add.ts +2 -1
- package/src/public/avm/opcodes/environment_getters.ts +7 -2
- package/src/public/avm/opcodes/external_calls.ts +19 -7
- package/src/public/avm/opcodes/hashing.ts +17 -5
- package/src/public/avm/opcodes/memory.ts +27 -9
- package/src/public/avm/opcodes/misc.ts +23 -15
- package/src/public/avm/opcodes/storage.ts +9 -3
- package/src/public/avm/serialization/buffer_cursor.ts +4 -1
- package/src/public/fixtures/public_tx_simulation_tester.ts +1 -0
- package/src/public/fixtures/utils.ts +21 -28
- package/src/public/hinting_db_sources.ts +8 -2
- package/src/public/public_processor/public_processor.ts +9 -3
- package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +3 -2
- package/src/public/public_tx_simulator/public_tx_context.ts +4 -23
- package/src/public/public_tx_simulator/public_tx_simulator.ts +14 -1
- package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +10 -1
- package/src/public/side_effect_trace.ts +5 -7
- package/src/public/state_manager/state_manager.ts +13 -0
- package/src/public/avm/opcodes/.eslintrc.cjs +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/simulator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0-nightly.20250521",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./server": "./dest/server.js",
|
|
@@ -58,34 +58,34 @@
|
|
|
58
58
|
]
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@aztec/constants": "0.
|
|
62
|
-
"@aztec/foundation": "0.
|
|
63
|
-
"@aztec/noir-acvm_js": "0.
|
|
64
|
-
"@aztec/noir-noirc_abi": "0.
|
|
65
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
66
|
-
"@aztec/noir-types": "0.
|
|
67
|
-
"@aztec/protocol-contracts": "0.
|
|
68
|
-
"@aztec/stdlib": "0.
|
|
69
|
-
"@aztec/telemetry-client": "0.
|
|
70
|
-
"@aztec/world-state": "0.
|
|
61
|
+
"@aztec/constants": "0.87.0-nightly.20250521",
|
|
62
|
+
"@aztec/foundation": "0.87.0-nightly.20250521",
|
|
63
|
+
"@aztec/noir-acvm_js": "0.87.0-nightly.20250521",
|
|
64
|
+
"@aztec/noir-noirc_abi": "0.87.0-nightly.20250521",
|
|
65
|
+
"@aztec/noir-protocol-circuits-types": "0.87.0-nightly.20250521",
|
|
66
|
+
"@aztec/noir-types": "0.87.0-nightly.20250521",
|
|
67
|
+
"@aztec/protocol-contracts": "0.87.0-nightly.20250521",
|
|
68
|
+
"@aztec/stdlib": "0.87.0-nightly.20250521",
|
|
69
|
+
"@aztec/telemetry-client": "0.87.0-nightly.20250521",
|
|
70
|
+
"@aztec/world-state": "0.87.0-nightly.20250521",
|
|
71
71
|
"lodash.clonedeep": "^4.5.0",
|
|
72
72
|
"lodash.merge": "^4.6.2",
|
|
73
73
|
"tslib": "^2.4.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@aztec/kv-store": "0.
|
|
77
|
-
"@aztec/merkle-tree": "0.
|
|
78
|
-
"@aztec/noir-contracts.js": "0.
|
|
79
|
-
"@aztec/noir-test-contracts.js": "0.
|
|
76
|
+
"@aztec/kv-store": "0.87.0-nightly.20250521",
|
|
77
|
+
"@aztec/merkle-tree": "0.87.0-nightly.20250521",
|
|
78
|
+
"@aztec/noir-contracts.js": "0.87.0-nightly.20250521",
|
|
79
|
+
"@aztec/noir-test-contracts.js": "0.87.0-nightly.20250521",
|
|
80
80
|
"@jest/globals": "^29.5.0",
|
|
81
81
|
"@types/jest": "^29.5.0",
|
|
82
82
|
"@types/lodash.clonedeep": "^4.5.7",
|
|
83
83
|
"@types/lodash.merge": "^4.6.9",
|
|
84
|
-
"@types/node": "^
|
|
84
|
+
"@types/node": "^22.15.17",
|
|
85
85
|
"jest": "^29.5.0",
|
|
86
86
|
"jest-mock-extended": "^3.0.4",
|
|
87
87
|
"ts-node": "^10.9.1",
|
|
88
|
-
"typescript": "^5.
|
|
88
|
+
"typescript": "^5.3.3",
|
|
89
89
|
"viem": "2.23.7"
|
|
90
90
|
},
|
|
91
91
|
"files": [
|
|
@@ -95,6 +95,6 @@
|
|
|
95
95
|
],
|
|
96
96
|
"types": "./dest/index.d.ts",
|
|
97
97
|
"engines": {
|
|
98
|
-
"node": ">=
|
|
98
|
+
"node": ">=20.10"
|
|
99
99
|
}
|
|
100
100
|
}
|
package/src/private/acvm/acvm.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { Fr, Point } from '@aztec/foundation/fields';
|
|
2
2
|
import { EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
3
3
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
-
import { ContractClassLog, LogWithTxData } from '@aztec/stdlib/logs';
|
|
4
|
+
import { ContractClassLog, ContractClassLogFields, LogWithTxData } from '@aztec/stdlib/logs';
|
|
5
5
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
6
6
|
import { TxHash } from '@aztec/stdlib/tx';
|
|
7
7
|
|
|
8
8
|
import type { ACVMField } from '../acvm_types.js';
|
|
9
9
|
import { fromBoundedVec, fromUintArray, fromUintBoundedVec } from '../deserialize.js';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
arrayOfArraysToBoundedVecOfArrays,
|
|
12
|
+
bufferToBoundedVec,
|
|
13
|
+
toACVMField,
|
|
14
|
+
toACVMFieldSingleOrArray,
|
|
15
|
+
} from '../serialize.js';
|
|
11
16
|
import type { TypedOracle } from './typed_oracle.js';
|
|
12
17
|
|
|
13
18
|
/**
|
|
@@ -169,8 +174,9 @@ export class Oracle {
|
|
|
169
174
|
[limit]: ACVMField[],
|
|
170
175
|
[offset]: ACVMField[],
|
|
171
176
|
[status]: ACVMField[],
|
|
172
|
-
[
|
|
173
|
-
|
|
177
|
+
[maxNotes]: ACVMField[],
|
|
178
|
+
[packedRetrievedNoteLength]: ACVMField[],
|
|
179
|
+
): Promise<(ACVMField | ACVMField[])[]> {
|
|
174
180
|
const noteDatas = await this.typedOracle.getNotes(
|
|
175
181
|
Fr.fromString(storageSlot),
|
|
176
182
|
+numSelects,
|
|
@@ -188,32 +194,30 @@ export class Oracle {
|
|
|
188
194
|
+status,
|
|
189
195
|
);
|
|
190
196
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
197
|
+
if (noteDatas.length > 0) {
|
|
198
|
+
const noteLength = noteDatas[0].note.items.length;
|
|
199
|
+
if (!noteDatas.every(({ note }) => noteLength === note.items.length)) {
|
|
200
|
+
throw new Error('Notes should all be the same length.');
|
|
201
|
+
}
|
|
194
202
|
}
|
|
195
203
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// Values indicates whether the note is settled or transient.
|
|
199
|
-
const noteTypes = {
|
|
200
|
-
isSettled: new Fr(0),
|
|
201
|
-
isTransient: new Fr(1),
|
|
202
|
-
};
|
|
203
|
-
const flattenData = noteDatas.flatMap(({ nonce, note, index }) => [
|
|
204
|
-
nonce,
|
|
205
|
-
index === undefined ? noteTypes.isTransient : noteTypes.isSettled,
|
|
206
|
-
...note.items,
|
|
207
|
-
]);
|
|
208
|
-
|
|
209
|
-
const returnFieldSize = +returnSize;
|
|
210
|
-
const returnData = [noteDatas.length, contractAddress, ...flattenData].map(v => toACVMField(v));
|
|
211
|
-
if (returnData.length > returnFieldSize) {
|
|
212
|
-
throw new Error(`Return data size too big. Maximum ${returnFieldSize} fields. Got ${flattenData.length}.`);
|
|
213
|
-
}
|
|
204
|
+
// The expected return type is a BoundedVec<[Field; packedRetrievedNoteLength], maxNotes> where each
|
|
205
|
+
// array is structured as [contract_address, nonce, nonzero_note_hash_counter, ...packed_note].
|
|
214
206
|
|
|
215
|
-
const
|
|
216
|
-
|
|
207
|
+
const returnDataAsArrayOfArrays = noteDatas.map(({ contractAddress, nonce, index, note }) => {
|
|
208
|
+
// If index is undefined, the note is transient which implies that the nonzero_note_hash_counter has to be true
|
|
209
|
+
const noteIsTransient = index === undefined;
|
|
210
|
+
const nonzeroNoteHashCounter = noteIsTransient ? true : false;
|
|
211
|
+
// If you change the array on the next line you have to change the `unpack_retrieved_note` function in
|
|
212
|
+
// `aztec/src/note/retrieved_note.nr`
|
|
213
|
+
return [contractAddress, nonce, nonzeroNoteHashCounter, ...note.items];
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Now we convert each sub-array to an array of ACVMField
|
|
217
|
+
const returnDataAsArrayOfACVMFieldArrays = returnDataAsArrayOfArrays.map(subArray => subArray.map(toACVMField));
|
|
218
|
+
|
|
219
|
+
// At last we convert the array of arrays to a bounded vec of arrays
|
|
220
|
+
return arrayOfArraysToBoundedVecOfArrays(returnDataAsArrayOfACVMFieldArrays, +maxNotes, +packedRetrievedNoteLength);
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
notifyCreatedNote(
|
|
@@ -288,10 +292,11 @@ export class Oracle {
|
|
|
288
292
|
notifyCreatedContractClassLog(
|
|
289
293
|
[contractAddress]: ACVMField[],
|
|
290
294
|
message: ACVMField[],
|
|
295
|
+
[length]: ACVMField[],
|
|
291
296
|
[counter]: ACVMField[],
|
|
292
297
|
): Promise<ACVMField[]> {
|
|
293
|
-
const
|
|
294
|
-
const log = new ContractClassLog(new AztecAddress(Fr.fromString(contractAddress)),
|
|
298
|
+
const logFields = new ContractClassLogFields(message.map(Fr.fromString));
|
|
299
|
+
const log = new ContractClassLog(new AztecAddress(Fr.fromString(contractAddress)), logFields, +length);
|
|
295
300
|
|
|
296
301
|
this.typedOracle.notifyCreatedContractClassLog(log, +counter);
|
|
297
302
|
return Promise.resolve([]);
|
|
@@ -351,8 +356,10 @@ export class Oracle {
|
|
|
351
356
|
return [];
|
|
352
357
|
}
|
|
353
358
|
|
|
354
|
-
notifySetMinRevertibleSideEffectCounter([minRevertibleSideEffectCounter]: ACVMField[]): Promise<ACVMField[]> {
|
|
355
|
-
this.typedOracle.notifySetMinRevertibleSideEffectCounter(
|
|
359
|
+
async notifySetMinRevertibleSideEffectCounter([minRevertibleSideEffectCounter]: ACVMField[]): Promise<ACVMField[]> {
|
|
360
|
+
await this.typedOracle.notifySetMinRevertibleSideEffectCounter(
|
|
361
|
+
Fr.fromString(minRevertibleSideEffectCounter).toNumber(),
|
|
362
|
+
);
|
|
356
363
|
return Promise.resolve([]);
|
|
357
364
|
}
|
|
358
365
|
|
|
@@ -198,7 +198,7 @@ export abstract class TypedOracle {
|
|
|
198
198
|
return Promise.reject(new OracleMethodNotAvailableError('notifySetPublicTeardownFunctionCall'));
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
notifySetMinRevertibleSideEffectCounter(_minRevertibleSideEffectCounter: number): void {
|
|
201
|
+
notifySetMinRevertibleSideEffectCounter(_minRevertibleSideEffectCounter: number): Promise<void> {
|
|
202
202
|
throw new OracleMethodNotAvailableError('notifySetMinRevertibleSideEffectCounter');
|
|
203
203
|
}
|
|
204
204
|
|
|
@@ -86,3 +86,38 @@ export function arrayToBoundedVec(bVecStorage: ACVMField[], maxLen: number): [AC
|
|
|
86
86
|
const len = toACVMField(BigInt(bVecStorage.length));
|
|
87
87
|
return [storage, len];
|
|
88
88
|
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Converts an array of arrays representing Noir BoundedVec of nested arrays into its Noir serialized form.
|
|
92
|
+
* @param bVecStorage - The array underlying the BoundedVec.
|
|
93
|
+
* @param maxLen - The max length of the BoundedVec (max num of the nested arrays in the BoundedVec).
|
|
94
|
+
* @param nestedArrayLength - The length of the nested arrays (each nested array has to have the same length).
|
|
95
|
+
* @returns Serialized BoundedVec following Noir intrinsic serialization.
|
|
96
|
+
*/
|
|
97
|
+
export function arrayOfArraysToBoundedVecOfArrays(
|
|
98
|
+
bVecStorage: ACVMField[][],
|
|
99
|
+
maxLen: number,
|
|
100
|
+
nestedArrayLength: number,
|
|
101
|
+
): [ACVMField[], ACVMField] {
|
|
102
|
+
if (bVecStorage.length > maxLen) {
|
|
103
|
+
throw new Error(`Array of length ${bVecStorage.length} larger than maxLen ${maxLen}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check that all nested arrays have length nestedArrayLength
|
|
107
|
+
if (!bVecStorage.every(nestedArray => nestedArray.length === nestedArrayLength)) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`Nested array length passed in from Noir does not correspond to the length obtained in TS: ${nestedArrayLength} !== ${bVecStorage[0].length}`,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Flatten the array of arrays
|
|
114
|
+
const flattenedStorage = bVecStorage.flat();
|
|
115
|
+
|
|
116
|
+
// Calculate and add padding
|
|
117
|
+
const numFieldsToPad = maxLen * nestedArrayLength - flattenedStorage.length;
|
|
118
|
+
const flattenedStorageWithPadding = flattenedStorage.concat(Array(numFieldsToPad).fill(toACVMField(BigInt(0))));
|
|
119
|
+
|
|
120
|
+
// Return flattened array with padding and length
|
|
121
|
+
const len = toACVMField(BigInt(bVecStorage.length));
|
|
122
|
+
return [flattenedStorageWithPadding, len];
|
|
123
|
+
}
|
package/src/private/index.ts
CHANGED
|
@@ -9,6 +9,9 @@ export { ExecutionNoteCache } from './execution_note_cache.js';
|
|
|
9
9
|
export { extractPrivateCircuitPublicInputs, readCurrentClassId } from './private_execution.js';
|
|
10
10
|
export { witnessMapToFields } from './acvm/deserialize.js';
|
|
11
11
|
export { toACVMWitness } from './acvm/serialize.js';
|
|
12
|
+
export { executePrivateFunction } from './private_execution.js';
|
|
13
|
+
export { PrivateExecutionOracle } from './private_execution_oracle.js';
|
|
14
|
+
export { UtilityExecutionOracle } from './utility_execution_oracle.js';
|
|
12
15
|
export { extractCallStack } from './acvm/acvm.js';
|
|
13
16
|
export { type NoteData, TypedOracle } from './acvm/oracle/typed_oracle.js';
|
|
14
17
|
export { Oracle } from './acvm/oracle/oracle.js';
|
|
@@ -113,19 +113,19 @@ const sortNotes = (a: Fr[], b: Fr[], sorts: Sort[], level = 0): number => {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
const { selector, order } = sorts[level];
|
|
116
|
-
if (order === 0) {
|
|
116
|
+
if (order === (0 as SortOrder)) {
|
|
117
117
|
return 0;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
const aValue = selectPropertyFromPackedNoteContent(a, selector);
|
|
121
121
|
const bValue = selectPropertyFromPackedNoteContent(b, selector);
|
|
122
122
|
|
|
123
|
-
const dir = order === 1 ? [-1, 1] : [1, -1];
|
|
123
|
+
const dir = order === (1 as SortOrder) ? [-1, 1] : [1, -1];
|
|
124
124
|
return aValue.toBigInt() === bValue.toBigInt()
|
|
125
125
|
? sortNotes(a, b, sorts, level + 1)
|
|
126
126
|
: aValue.toBigInt() > bValue.toBigInt()
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
? dir[0]
|
|
128
|
+
: dir[1];
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
/**
|
|
@@ -78,7 +78,7 @@ export async function executeNativeCircuit(
|
|
|
78
78
|
try {
|
|
79
79
|
// Check that the directory exists
|
|
80
80
|
await fs.access(workingDirectory);
|
|
81
|
-
} catch
|
|
81
|
+
} catch {
|
|
82
82
|
return { status: ACVM_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -138,7 +138,11 @@ export async function executeNativeCircuit(
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
export class NativeACVMSimulator implements SimulationProvider {
|
|
141
|
-
constructor(
|
|
141
|
+
constructor(
|
|
142
|
+
private workingDirectory: string,
|
|
143
|
+
private pathToAcvm: string,
|
|
144
|
+
private witnessFilename?: string,
|
|
145
|
+
) {}
|
|
142
146
|
|
|
143
147
|
async executeProtocolCircuit(
|
|
144
148
|
input: ACVMWitness,
|
|
@@ -60,7 +60,7 @@ export function enrichNoirError(artifact: NoirCompiledCircuit, originalError: Ex
|
|
|
60
60
|
// If not, attach the payload to the original error
|
|
61
61
|
enrichedError.decodedAssertionPayload = decodedPayload;
|
|
62
62
|
}
|
|
63
|
-
} catch
|
|
63
|
+
} catch {
|
|
64
64
|
// Ignore errors decoding the payload
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -82,7 +82,7 @@ export function enrichNoirError(artifact: NoirCompiledCircuit, originalError: Ex
|
|
|
82
82
|
return `at ${errorLocation.locationText} (${errorLocation.filePath}:${errorLocation.line}:${errorLocation.column})`;
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
|
-
} catch
|
|
85
|
+
} catch {
|
|
86
86
|
// Ignore errors resolving the callstack
|
|
87
87
|
}
|
|
88
88
|
|
package/src/private/simulator.ts
CHANGED
|
@@ -22,7 +22,10 @@ import { UtilityExecutionOracle } from './utility_execution_oracle.js';
|
|
|
22
22
|
export class AcirSimulator {
|
|
23
23
|
private log: Logger;
|
|
24
24
|
|
|
25
|
-
constructor(
|
|
25
|
+
constructor(
|
|
26
|
+
private executionDataProvider: ExecutionDataProvider,
|
|
27
|
+
private simulationProvider: SimulationProvider,
|
|
28
|
+
) {
|
|
26
29
|
this.log = createLogger('simulator');
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -25,7 +25,7 @@ export class AvmContractCallResult {
|
|
|
25
25
|
this.gasLeft,
|
|
26
26
|
)}, totalInstructions: ${this.totalInstructions}`;
|
|
27
27
|
if (this.revertReason) {
|
|
28
|
-
resultsStr += `, revertReason: ${this.revertReason}`;
|
|
28
|
+
resultsStr += `, revertReason: ${this.revertReason.message}`;
|
|
29
29
|
}
|
|
30
30
|
return resultsStr;
|
|
31
31
|
}
|
|
@@ -60,7 +60,7 @@ export class AvmFinalizedCallResult {
|
|
|
60
60
|
this.gasLeft,
|
|
61
61
|
)}, totalInstructions: ${this.totalInstructions}`;
|
|
62
62
|
if (this.revertReason) {
|
|
63
|
-
resultsStr += `, revertReason: ${this.revertReason}`;
|
|
63
|
+
resultsStr += `, revertReason: ${this.revertReason.message}`;
|
|
64
64
|
}
|
|
65
65
|
return resultsStr;
|
|
66
66
|
}
|
|
@@ -15,9 +15,14 @@ export class AvmExecutionEnvironment {
|
|
|
15
15
|
public readonly globals: GlobalVariables,
|
|
16
16
|
public readonly isStaticCall: boolean,
|
|
17
17
|
public readonly calldata: Fr[],
|
|
18
|
+
public readonly clientInitiatedSimulation: boolean = false,
|
|
18
19
|
) {}
|
|
19
20
|
|
|
20
|
-
private deriveEnvironmentForNestedCallInternal(
|
|
21
|
+
private deriveEnvironmentForNestedCallInternal(
|
|
22
|
+
targetAddress: AztecAddress,
|
|
23
|
+
calldata: Fr[],
|
|
24
|
+
isStaticCall: boolean,
|
|
25
|
+
): AvmExecutionEnvironment {
|
|
21
26
|
return new AvmExecutionEnvironment(
|
|
22
27
|
/*address=*/ targetAddress,
|
|
23
28
|
/*sender=*/ this.address,
|
|
@@ -26,6 +31,7 @@ export class AvmExecutionEnvironment {
|
|
|
26
31
|
this.globals,
|
|
27
32
|
isStaticCall,
|
|
28
33
|
calldata,
|
|
34
|
+
/*clientInitiatedSimulation=*/ this.clientInitiatedSimulation,
|
|
29
35
|
);
|
|
30
36
|
}
|
|
31
37
|
|
|
@@ -2,7 +2,6 @@ import * as c from '@aztec/constants';
|
|
|
2
2
|
|
|
3
3
|
import { TypeTag } from './avm_memory_types.js';
|
|
4
4
|
import { InstructionExecutionError } from './errors.js';
|
|
5
|
-
import { Addressing, AddressingMode } from './opcodes/addressing_mode.js';
|
|
6
5
|
import { Opcode } from './serialization/instruction_serialization.js';
|
|
7
6
|
|
|
8
7
|
/** Gas counters in L1, L2, and DA. */
|
|
@@ -136,7 +135,6 @@ const DYNAMIC_GAS_COSTS = new Map<Opcode, Gas>([
|
|
|
136
135
|
[Opcode.RETURN, makeCost(c.AVM_RETURN_DYN_L2_GAS, 0)],
|
|
137
136
|
[Opcode.REVERT_8, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)],
|
|
138
137
|
[Opcode.REVERT_16, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)],
|
|
139
|
-
[Opcode.DEBUGLOG, makeCost(c.AVM_DEBUGLOG_DYN_L2_GAS, 0)],
|
|
140
138
|
[Opcode.TORADIXBE, makeCost(c.AVM_TORADIXBE_DYN_L2_GAS, 0)],
|
|
141
139
|
]);
|
|
142
140
|
|
|
@@ -149,24 +147,6 @@ export function getDynamicGasCost(opcode: Opcode): Gas {
|
|
|
149
147
|
return DYNAMIC_GAS_COSTS.has(opcode) ? DYNAMIC_GAS_COSTS.get(opcode)! : makeCost(0, 0);
|
|
150
148
|
}
|
|
151
149
|
|
|
152
|
-
/** Returns the gas cost associated with the memory operations performed. */
|
|
153
|
-
export function getMemoryGasCost(args: { reads?: number; writes?: number; indirect?: number }) {
|
|
154
|
-
const { reads, writes, indirect } = args;
|
|
155
|
-
const indirectCount = Addressing.fromWire(indirect ?? 0).count(AddressingMode.INDIRECT);
|
|
156
|
-
const l2MemoryGasCost =
|
|
157
|
-
(reads ?? 0) * GAS_COST_CONSTANTS.MEMORY_READ +
|
|
158
|
-
(writes ?? 0) * GAS_COST_CONSTANTS.MEMORY_WRITE +
|
|
159
|
-
indirectCount * GAS_COST_CONSTANTS.MEMORY_INDIRECT_READ_PENALTY;
|
|
160
|
-
return makeGas({ l2Gas: l2MemoryGasCost });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Constants used in base cost calculations. */
|
|
164
|
-
export const GAS_COST_CONSTANTS = {
|
|
165
|
-
MEMORY_READ: 10,
|
|
166
|
-
MEMORY_INDIRECT_READ_PENALTY: 10,
|
|
167
|
-
MEMORY_WRITE: 100,
|
|
168
|
-
};
|
|
169
|
-
|
|
170
150
|
/** Returns gas cost for an operation on a given type tag based on the base cost per byte. */
|
|
171
151
|
export function getGasCostForTypeTag(tag: TypeTag, baseCost: Gas) {
|
|
172
152
|
return mulGas(baseCost, getGasCostMultiplierFromTypeTag(tag));
|
|
@@ -79,6 +79,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
79
79
|
isStaticCall: boolean,
|
|
80
80
|
calldata: Fr[],
|
|
81
81
|
allocatedGas: Gas,
|
|
82
|
+
clientInitiatedSimulation: boolean = false,
|
|
82
83
|
) {
|
|
83
84
|
const avmExecutionEnv = new AvmExecutionEnvironment(
|
|
84
85
|
address,
|
|
@@ -88,6 +89,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
88
89
|
globals,
|
|
89
90
|
isStaticCall,
|
|
90
91
|
calldata,
|
|
92
|
+
clientInitiatedSimulation,
|
|
91
93
|
);
|
|
92
94
|
|
|
93
95
|
const avmMachineState = new AvmMachineState(allocatedGas);
|
|
@@ -108,7 +110,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
|
|
|
108
110
|
throw err;
|
|
109
111
|
}
|
|
110
112
|
return await this.handleFailureToRetrieveBytecode(
|
|
111
|
-
`Bytecode retrieval for contract '${this.context.environment.address}' failed with ${err}. Reverting...`,
|
|
113
|
+
`Bytecode retrieval for contract '${this.context.environment.address}' failed with ${err.message}. Reverting...`,
|
|
112
114
|
);
|
|
113
115
|
}
|
|
114
116
|
|
|
@@ -71,6 +71,7 @@ export function initExecutionEnvironment(overrides?: Partial<AvmExecutionEnviron
|
|
|
71
71
|
overrides?.globals ?? GlobalVariables.empty(),
|
|
72
72
|
overrides?.isStaticCall ?? false,
|
|
73
73
|
overrides?.calldata ?? [],
|
|
74
|
+
overrides?.clientInitiatedSimulation ?? true, // default to true for testing even though internal default is false
|
|
74
75
|
);
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -29,9 +29,10 @@ export class NoteHashExists extends Instruction {
|
|
|
29
29
|
|
|
30
30
|
public async execute(context: AvmContext): Promise<void> {
|
|
31
31
|
const memory = context.machineState.memory;
|
|
32
|
+
const addressing = Addressing.fromWire(this.indirect);
|
|
33
|
+
|
|
32
34
|
context.machineState.consumeGas(this.gasCost());
|
|
33
35
|
const operands = [this.noteHashOffset, this.leafIndexOffset, this.existsOffset];
|
|
34
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
35
36
|
const [noteHashOffset, leafIndexOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
36
37
|
memory.checkTags(TypeTag.FIELD, noteHashOffset, leafIndexOffset);
|
|
37
38
|
|
|
@@ -50,16 +51,20 @@ export class EmitNoteHash extends Instruction {
|
|
|
50
51
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
51
52
|
static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16];
|
|
52
53
|
|
|
53
|
-
constructor(
|
|
54
|
+
constructor(
|
|
55
|
+
private indirect: number,
|
|
56
|
+
private noteHashOffset: number,
|
|
57
|
+
) {
|
|
54
58
|
super();
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
public async execute(context: AvmContext): Promise<void> {
|
|
58
62
|
const memory = context.machineState.memory;
|
|
63
|
+
const addressing = Addressing.fromWire(this.indirect);
|
|
64
|
+
|
|
59
65
|
context.machineState.consumeGas(this.gasCost());
|
|
60
66
|
|
|
61
67
|
const operands = [this.noteHashOffset];
|
|
62
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
63
68
|
const [noteHashOffset] = addressing.resolve(operands, memory);
|
|
64
69
|
memory.checkTag(TypeTag.FIELD, noteHashOffset);
|
|
65
70
|
|
|
@@ -95,10 +100,11 @@ export class NullifierExists extends Instruction {
|
|
|
95
100
|
|
|
96
101
|
public async execute(context: AvmContext): Promise<void> {
|
|
97
102
|
const memory = context.machineState.memory;
|
|
103
|
+
const addressing = Addressing.fromWire(this.indirect);
|
|
104
|
+
|
|
98
105
|
context.machineState.consumeGas(this.gasCost());
|
|
99
106
|
|
|
100
107
|
const operands = [this.nullifierOffset, this.addressOffset, this.existsOffset];
|
|
101
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
102
108
|
const [nullifierOffset, addressOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
103
109
|
memory.checkTags(TypeTag.FIELD, nullifierOffset, addressOffset);
|
|
104
110
|
|
|
@@ -116,7 +122,10 @@ export class EmitNullifier extends Instruction {
|
|
|
116
122
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
117
123
|
static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16];
|
|
118
124
|
|
|
119
|
-
constructor(
|
|
125
|
+
constructor(
|
|
126
|
+
private indirect: number,
|
|
127
|
+
private nullifierOffset: number,
|
|
128
|
+
) {
|
|
120
129
|
super();
|
|
121
130
|
}
|
|
122
131
|
|
|
@@ -126,10 +135,11 @@ export class EmitNullifier extends Instruction {
|
|
|
126
135
|
}
|
|
127
136
|
|
|
128
137
|
const memory = context.machineState.memory;
|
|
138
|
+
const addressing = Addressing.fromWire(this.indirect);
|
|
139
|
+
|
|
129
140
|
context.machineState.consumeGas(this.gasCost());
|
|
130
141
|
|
|
131
142
|
const operands = [this.nullifierOffset];
|
|
132
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
133
143
|
const [nullifierOffset] = addressing.resolve(operands, memory);
|
|
134
144
|
memory.checkTag(TypeTag.FIELD, nullifierOffset);
|
|
135
145
|
|
|
@@ -172,10 +182,11 @@ export class L1ToL2MessageExists extends Instruction {
|
|
|
172
182
|
|
|
173
183
|
public async execute(context: AvmContext): Promise<void> {
|
|
174
184
|
const memory = context.machineState.memory;
|
|
185
|
+
const addressing = Addressing.fromWire(this.indirect);
|
|
186
|
+
|
|
175
187
|
context.machineState.consumeGas(this.gasCost());
|
|
176
188
|
|
|
177
189
|
const operands = [this.msgHashOffset, this.msgLeafIndexOffset, this.existsOffset];
|
|
178
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
179
190
|
const [msgHashOffset, msgLeafIndexOffset, existsOffset] = addressing.resolve(operands, memory);
|
|
180
191
|
memory.checkTags(TypeTag.FIELD, msgHashOffset, msgLeafIndexOffset);
|
|
181
192
|
|
|
@@ -193,7 +204,11 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
193
204
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
194
205
|
static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16, OperandType.UINT16];
|
|
195
206
|
|
|
196
|
-
constructor(
|
|
207
|
+
constructor(
|
|
208
|
+
private indirect: number,
|
|
209
|
+
private logOffset: number,
|
|
210
|
+
private logSizeOffset: number,
|
|
211
|
+
) {
|
|
197
212
|
super();
|
|
198
213
|
}
|
|
199
214
|
|
|
@@ -203,9 +218,9 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
203
218
|
}
|
|
204
219
|
|
|
205
220
|
const memory = context.machineState.memory;
|
|
221
|
+
const addressing = Addressing.fromWire(this.indirect);
|
|
206
222
|
|
|
207
223
|
const operands = [this.logOffset, this.logSizeOffset];
|
|
208
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
209
224
|
const [logOffset, logSizeOffset] = addressing.resolve(operands, memory);
|
|
210
225
|
memory.checkTag(TypeTag.UINT32, logSizeOffset);
|
|
211
226
|
const logSize = memory.get(logSizeOffset).toNumber();
|
|
@@ -225,7 +240,11 @@ export class SendL2ToL1Message extends Instruction {
|
|
|
225
240
|
// Informs (de)serialization. See Instruction.deserialize.
|
|
226
241
|
static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16, OperandType.UINT16];
|
|
227
242
|
|
|
228
|
-
constructor(
|
|
243
|
+
constructor(
|
|
244
|
+
private indirect: number,
|
|
245
|
+
private recipientOffset: number,
|
|
246
|
+
private contentOffset: number,
|
|
247
|
+
) {
|
|
229
248
|
super();
|
|
230
249
|
}
|
|
231
250
|
|
|
@@ -235,10 +254,11 @@ export class SendL2ToL1Message extends Instruction {
|
|
|
235
254
|
}
|
|
236
255
|
|
|
237
256
|
const memory = context.machineState.memory;
|
|
257
|
+
const addressing = Addressing.fromWire(this.indirect);
|
|
258
|
+
|
|
238
259
|
context.machineState.consumeGas(this.gasCost());
|
|
239
260
|
|
|
240
261
|
const operands = [this.recipientOffset, this.contentOffset];
|
|
241
|
-
const addressing = Addressing.fromWire(this.indirect, operands.length);
|
|
242
262
|
const [recipientOffset, contentOffset] = addressing.resolve(operands, memory);
|
|
243
263
|
memory.checkTags(TypeTag.FIELD, recipientOffset, contentOffset);
|
|
244
264
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AVM_MAX_OPERANDS } from '@aztec/constants';
|
|
2
|
+
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
3
|
+
import type { Tuple } from '@aztec/foundation/serialize';
|
|
2
4
|
|
|
3
5
|
import { TaggedMemory, type TaggedMemoryInterface } from '../avm_memory_types.js';
|
|
4
6
|
import { RelativeAddressOutOfRangeError } from '../errors.js';
|
|
@@ -13,21 +15,28 @@ export enum AddressingMode {
|
|
|
13
15
|
/** A class to represent the addressing mode of an instruction. */
|
|
14
16
|
export class Addressing {
|
|
15
17
|
public constructor(
|
|
16
|
-
/** The addressing mode for each operand.
|
|
17
|
-
private readonly modePerOperand: AddressingMode
|
|
18
|
+
/** The addressing mode for each possible operand. */
|
|
19
|
+
private readonly modePerOperand: Tuple<AddressingMode, typeof AVM_MAX_OPERANDS>,
|
|
18
20
|
) {}
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
public static fromModes(modes: AddressingMode[]): Addressing {
|
|
23
|
+
if (modes.length > AVM_MAX_OPERANDS) {
|
|
24
|
+
throw new Error('Too many operands for addressing mode');
|
|
25
|
+
}
|
|
26
|
+
return new Addressing(padArrayEnd(modes, AddressingMode.DIRECT, AVM_MAX_OPERANDS));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public static fromWire(wireModes: number): Addressing {
|
|
30
|
+
// The modes are stored in the wire format as one or two bytes, with each two bits representing the modes for an operand.
|
|
31
|
+
// Even bits are indirect, odd bits are relative.
|
|
32
|
+
const modes = new Array<AddressingMode>(AVM_MAX_OPERANDS);
|
|
33
|
+
for (let i = 0; i < AVM_MAX_OPERANDS; i++) {
|
|
26
34
|
modes[i] =
|
|
27
|
-
(((wireModes >> i) & 1) * AddressingMode.INDIRECT) |
|
|
28
|
-
(((wireModes >> (i +
|
|
35
|
+
(((wireModes >> (i * 2)) & 1) * AddressingMode.INDIRECT) |
|
|
36
|
+
(((wireModes >> (i * 2 + 1)) & 1) * AddressingMode.RELATIVE);
|
|
29
37
|
}
|
|
30
|
-
|
|
38
|
+
// Casting the array to tuple since it should be more performant than using makeTuple
|
|
39
|
+
return new Addressing(modes as Tuple<AddressingMode, typeof AVM_MAX_OPERANDS>);
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
public toWire(): number {
|
|
@@ -36,20 +45,15 @@ export class Addressing {
|
|
|
36
45
|
let wire: number = 0;
|
|
37
46
|
for (let i = 0; i < this.modePerOperand.length; i++) {
|
|
38
47
|
if (this.modePerOperand[i] & AddressingMode.INDIRECT) {
|
|
39
|
-
wire |= 1 << i;
|
|
48
|
+
wire |= 1 << (i * 2);
|
|
40
49
|
}
|
|
41
50
|
if (this.modePerOperand[i] & AddressingMode.RELATIVE) {
|
|
42
|
-
wire |= 1 << (
|
|
51
|
+
wire |= 1 << (i * 2 + 1);
|
|
43
52
|
}
|
|
44
53
|
}
|
|
45
54
|
return wire;
|
|
46
55
|
}
|
|
47
56
|
|
|
48
|
-
/** Returns how many operands use the given addressing mode. */
|
|
49
|
-
public count(mode: AddressingMode): number {
|
|
50
|
-
return this.modePerOperand.filter(m => (m & mode) !== 0).length;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
57
|
/**
|
|
54
58
|
* Resolves the offsets using the addressing mode.
|
|
55
59
|
* @param offsets The offsets to resolve.
|
|
@@ -57,7 +61,6 @@ export class Addressing {
|
|
|
57
61
|
* @returns The resolved offsets. The length of the returned array is the same as the length of the input array.
|
|
58
62
|
*/
|
|
59
63
|
public resolve(offsets: number[], mem: TaggedMemoryInterface): number[] {
|
|
60
|
-
assert(offsets.length <= this.modePerOperand.length);
|
|
61
64
|
const resolved = new Array(offsets.length);
|
|
62
65
|
|
|
63
66
|
let didRelativeOnce = false;
|