@aztec/simulator 0.56.0 → 0.58.0

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.
Files changed (205) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +2 -5
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +7 -38
  4. package/dest/acvm/oracle/typed_oracle.d.ts +4 -8
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +1 -10
  7. package/dest/avm/avm_execution_environment.d.ts +2 -3
  8. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  9. package/dest/avm/avm_execution_environment.js +3 -4
  10. package/dest/avm/avm_gas.d.ts.map +1 -1
  11. package/dest/avm/avm_gas.js +2 -3
  12. package/dest/avm/avm_memory_types.d.ts +10 -5
  13. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  14. package/dest/avm/avm_memory_types.js +31 -16
  15. package/dest/avm/avm_simulator.d.ts.map +1 -1
  16. package/dest/avm/avm_simulator.js +5 -2
  17. package/dest/avm/errors.d.ts +1 -1
  18. package/dest/avm/errors.d.ts.map +1 -1
  19. package/dest/avm/errors.js +12 -3
  20. package/dest/avm/fixtures/index.d.ts.map +1 -1
  21. package/dest/avm/fixtures/index.js +4 -4
  22. package/dest/avm/journal/journal.d.ts +2 -1
  23. package/dest/avm/journal/journal.d.ts.map +1 -1
  24. package/dest/avm/journal/journal.js +8 -8
  25. package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
  26. package/dest/avm/opcodes/accrued_substate.js +54 -47
  27. package/dest/avm/opcodes/addressing_mode.d.ts +3 -2
  28. package/dest/avm/opcodes/addressing_mode.d.ts.map +1 -1
  29. package/dest/avm/opcodes/addressing_mode.js +25 -21
  30. package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
  31. package/dest/avm/opcodes/arithmetic.js +7 -6
  32. package/dest/avm/opcodes/bitwise.d.ts +3 -3
  33. package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
  34. package/dest/avm/opcodes/bitwise.js +19 -16
  35. package/dest/avm/opcodes/commitment.d.ts.map +1 -1
  36. package/dest/avm/opcodes/commitment.js +6 -5
  37. package/dest/avm/opcodes/comparators.d.ts.map +1 -1
  38. package/dest/avm/opcodes/comparators.js +7 -6
  39. package/dest/avm/opcodes/contract.d.ts.map +1 -1
  40. package/dest/avm/opcodes/contract.js +8 -6
  41. package/dest/avm/opcodes/control_flow.js +7 -7
  42. package/dest/avm/opcodes/conversion.d.ts.map +1 -1
  43. package/dest/avm/opcodes/conversion.js +11 -10
  44. package/dest/avm/opcodes/ec_add.d.ts.map +1 -1
  45. package/dest/avm/opcodes/ec_add.js +25 -15
  46. package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
  47. package/dest/avm/opcodes/environment_getters.js +6 -5
  48. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  49. package/dest/avm/opcodes/external_calls.js +37 -26
  50. package/dest/avm/opcodes/hashing.d.ts +1 -3
  51. package/dest/avm/opcodes/hashing.d.ts.map +1 -1
  52. package/dest/avm/opcodes/hashing.js +39 -48
  53. package/dest/avm/opcodes/instruction.d.ts +2 -6
  54. package/dest/avm/opcodes/instruction.d.ts.map +1 -1
  55. package/dest/avm/opcodes/instruction.js +3 -9
  56. package/dest/avm/opcodes/instruction_impl.d.ts +1 -2
  57. package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
  58. package/dest/avm/opcodes/instruction_impl.js +2 -5
  59. package/dest/avm/opcodes/memory.d.ts +0 -12
  60. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  61. package/dest/avm/opcodes/memory.js +24 -54
  62. package/dest/avm/opcodes/misc.d.ts.map +1 -1
  63. package/dest/avm/opcodes/misc.js +10 -9
  64. package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
  65. package/dest/avm/opcodes/multi_scalar_mul.js +35 -20
  66. package/dest/avm/opcodes/storage.d.ts.map +1 -1
  67. package/dest/avm/opcodes/storage.js +13 -11
  68. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  69. package/dest/avm/serialization/bytecode_serialization.js +2 -3
  70. package/dest/avm/serialization/instruction_serialization.d.ts +32 -34
  71. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  72. package/dest/avm/serialization/instruction_serialization.js +34 -37
  73. package/dest/avm/test_utils.d.ts +1 -2
  74. package/dest/avm/test_utils.d.ts.map +1 -1
  75. package/dest/avm/test_utils.js +1 -1
  76. package/dest/client/client_execution_context.d.ts +6 -30
  77. package/dest/client/client_execution_context.d.ts.map +1 -1
  78. package/dest/client/client_execution_context.js +36 -54
  79. package/dest/client/db_oracle.d.ts +1 -2
  80. package/dest/client/db_oracle.d.ts.map +1 -1
  81. package/dest/client/db_oracle.js +1 -1
  82. package/dest/client/index.d.ts +1 -1
  83. package/dest/client/index.d.ts.map +1 -1
  84. package/dest/client/index.js +2 -2
  85. package/dest/client/private_execution.d.ts +12 -3
  86. package/dest/client/private_execution.d.ts.map +1 -1
  87. package/dest/client/private_execution.js +29 -23
  88. package/dest/client/simulator.d.ts +2 -3
  89. package/dest/client/simulator.d.ts.map +1 -1
  90. package/dest/client/simulator.js +1 -1
  91. package/dest/client/view_data_oracle.d.ts +1 -2
  92. package/dest/client/view_data_oracle.d.ts.map +1 -1
  93. package/dest/client/view_data_oracle.js +1 -1
  94. package/dest/common/debug_fn_name.d.ts +4 -0
  95. package/dest/common/debug_fn_name.d.ts.map +1 -0
  96. package/dest/common/debug_fn_name.js +15 -0
  97. package/dest/common/index.d.ts +0 -1
  98. package/dest/common/index.d.ts.map +1 -1
  99. package/dest/common/index.js +1 -2
  100. package/dest/public/db_interfaces.d.ts +1 -2
  101. package/dest/public/db_interfaces.d.ts.map +1 -1
  102. package/dest/public/dual_side_effect_trace.d.ts +76 -0
  103. package/dest/public/dual_side_effect_trace.d.ts.map +1 -0
  104. package/dest/public/dual_side_effect_trace.js +109 -0
  105. package/dest/public/enqueued_call_side_effect_trace.d.ts +114 -0
  106. package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -0
  107. package/dest/public/enqueued_call_side_effect_trace.js +314 -0
  108. package/dest/public/enqueued_call_simulator.d.ts +2 -2
  109. package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
  110. package/dest/public/enqueued_call_simulator.js +20 -10
  111. package/dest/public/enqueued_calls_processor.d.ts +2 -2
  112. package/dest/public/enqueued_calls_processor.d.ts.map +1 -1
  113. package/dest/public/enqueued_calls_processor.js +3 -5
  114. package/dest/public/execution.d.ts +11 -5
  115. package/dest/public/execution.d.ts.map +1 -1
  116. package/dest/public/execution.js +13 -1
  117. package/dest/public/executor.d.ts +7 -6
  118. package/dest/public/executor.d.ts.map +1 -1
  119. package/dest/public/executor.js +24 -15
  120. package/dest/public/fee_payment.d.ts +1 -1
  121. package/dest/public/fee_payment.d.ts.map +1 -1
  122. package/dest/public/fee_payment.js +4 -7
  123. package/dest/public/hints_builder.d.ts +2 -2
  124. package/dest/public/hints_builder.d.ts.map +1 -1
  125. package/dest/public/hints_builder.js +2 -2
  126. package/dest/public/public_db_sources.d.ts +4 -5
  127. package/dest/public/public_db_sources.d.ts.map +1 -1
  128. package/dest/public/public_db_sources.js +15 -11
  129. package/dest/public/public_kernel_tail_simulator.d.ts +3 -3
  130. package/dest/public/public_kernel_tail_simulator.d.ts.map +1 -1
  131. package/dest/public/public_kernel_tail_simulator.js +1 -1
  132. package/dest/public/public_processor.d.ts +7 -10
  133. package/dest/public/public_processor.d.ts.map +1 -1
  134. package/dest/public/public_processor.js +9 -10
  135. package/dest/public/side_effect_errors.d.ts +4 -0
  136. package/dest/public/side_effect_errors.d.ts.map +1 -0
  137. package/dest/public/side_effect_errors.js +7 -0
  138. package/dest/public/side_effect_trace.d.ts +3 -4
  139. package/dest/public/side_effect_trace.d.ts.map +1 -1
  140. package/dest/public/side_effect_trace.js +54 -29
  141. package/dest/public/side_effect_trace_interface.d.ts +1 -1
  142. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  143. package/package.json +12 -9
  144. package/src/acvm/oracle/oracle.ts +8 -86
  145. package/src/acvm/oracle/typed_oracle.ts +8 -33
  146. package/src/avm/avm_execution_environment.ts +1 -3
  147. package/src/avm/avm_gas.ts +1 -2
  148. package/src/avm/avm_memory_types.ts +38 -16
  149. package/src/avm/avm_simulator.ts +7 -1
  150. package/src/avm/errors.ts +11 -3
  151. package/src/avm/fixtures/index.ts +2 -3
  152. package/src/avm/journal/journal.ts +14 -10
  153. package/src/avm/opcodes/accrued_substate.ts +53 -61
  154. package/src/avm/opcodes/addressing_mode.ts +27 -24
  155. package/src/avm/opcodes/arithmetic.ts +6 -8
  156. package/src/avm/opcodes/bitwise.ts +18 -18
  157. package/src/avm/opcodes/commitment.ts +6 -7
  158. package/src/avm/opcodes/comparators.ts +6 -8
  159. package/src/avm/opcodes/contract.ts +7 -8
  160. package/src/avm/opcodes/control_flow.ts +6 -6
  161. package/src/avm/opcodes/conversion.ts +10 -12
  162. package/src/avm/opcodes/ec_add.ts +29 -24
  163. package/src/avm/opcodes/environment_getters.ts +5 -4
  164. package/src/avm/opcodes/external_calls.ts +37 -30
  165. package/src/avm/opcodes/hashing.ts +38 -63
  166. package/src/avm/opcodes/instruction.ts +3 -10
  167. package/src/avm/opcodes/instruction_impl.ts +0 -3
  168. package/src/avm/opcodes/memory.ts +23 -67
  169. package/src/avm/opcodes/misc.ts +9 -11
  170. package/src/avm/opcodes/multi_scalar_mul.ts +31 -26
  171. package/src/avm/opcodes/storage.ts +12 -10
  172. package/src/avm/serialization/bytecode_serialization.ts +0 -2
  173. package/src/avm/serialization/instruction_serialization.ts +1 -4
  174. package/src/avm/test_utils.ts +1 -2
  175. package/src/client/client_execution_context.ts +46 -97
  176. package/src/client/db_oracle.ts +6 -2
  177. package/src/client/index.ts +1 -1
  178. package/src/client/private_execution.ts +45 -15
  179. package/src/client/simulator.ts +2 -3
  180. package/src/client/view_data_oracle.ts +1 -2
  181. package/src/common/debug_fn_name.ts +22 -0
  182. package/src/common/index.ts +0 -1
  183. package/src/public/db_interfaces.ts +5 -2
  184. package/src/public/dual_side_effect_trace.ts +173 -0
  185. package/src/public/enqueued_call_side_effect_trace.ts +552 -0
  186. package/src/public/enqueued_call_simulator.ts +35 -14
  187. package/src/public/enqueued_calls_processor.ts +4 -6
  188. package/src/public/execution.ts +15 -6
  189. package/src/public/executor.ts +42 -19
  190. package/src/public/fee_payment.ts +4 -6
  191. package/src/public/hints_builder.ts +9 -11
  192. package/src/public/public_db_sources.ts +31 -22
  193. package/src/public/public_kernel_tail_simulator.ts +3 -3
  194. package/src/public/public_processor.ts +17 -13
  195. package/src/public/side_effect_errors.ts +6 -0
  196. package/src/public/side_effect_trace.ts +74 -29
  197. package/src/public/side_effect_trace_interface.ts +2 -2
  198. package/dest/client/execution_result.d.ts +0 -104
  199. package/dest/client/execution_result.d.ts.map +0 -1
  200. package/dest/client/execution_result.js +0 -136
  201. package/dest/common/return_values.d.ts +0 -11
  202. package/dest/common/return_values.d.ts.map +0 -1
  203. package/dest/common/return_values.js +0 -13
  204. package/src/client/execution_result.ts +0 -228
  205. package/src/common/return_values.ts +0 -18
@@ -1,5 +1,5 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
- import { TypeTag, Uint8 } from '../avm_memory_types.js';
2
+ import { TypeTag, Uint1 } from '../avm_memory_types.js';
3
3
  import { InstructionExecutionError, StaticCallAlterationError } from '../errors.js';
4
4
  import { NullifierCollisionError } from '../journal/nullifiers.js';
5
5
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
@@ -13,9 +13,9 @@ export class NoteHashExists extends Instruction {
13
13
  static readonly wireFormat = [
14
14
  OperandType.UINT8,
15
15
  OperandType.UINT8,
16
- OperandType.UINT32,
17
- OperandType.UINT32,
18
- OperandType.UINT32,
16
+ OperandType.UINT16,
17
+ OperandType.UINT16,
18
+ OperandType.UINT16,
19
19
  ];
20
20
 
21
21
  constructor(
@@ -28,13 +28,11 @@ export class NoteHashExists extends Instruction {
28
28
  }
29
29
 
30
30
  public async execute(context: AvmContext): Promise<void> {
31
- const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
32
31
  const memory = context.machineState.memory.track(this.type);
33
- context.machineState.consumeGas(this.gasCost(memoryOperations));
34
- const [noteHashOffset, leafIndexOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
35
- [this.noteHashOffset, this.leafIndexOffset, this.existsOffset],
36
- memory,
37
- );
32
+ context.machineState.consumeGas(this.gasCost());
33
+ const operands = [this.noteHashOffset, this.leafIndexOffset, this.existsOffset];
34
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
35
+ const [noteHashOffset, leafIndexOffset, existsOffset] = addressing.resolve(operands, memory);
38
36
  memory.checkTags(TypeTag.FIELD, noteHashOffset, leafIndexOffset);
39
37
 
40
38
  // Note that this instruction accepts any type in memory, and converts to Field.
@@ -46,9 +44,9 @@ export class NoteHashExists extends Instruction {
46
44
  noteHash,
47
45
  leafIndex,
48
46
  );
49
- memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
47
+ memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0));
50
48
 
51
- memory.assert(memoryOperations);
49
+ memory.assert({ reads: 2, writes: 1, addressing });
52
50
  context.machineState.incrementPc();
53
51
  }
54
52
  }
@@ -57,18 +55,19 @@ export class EmitNoteHash extends Instruction {
57
55
  static type: string = 'EMITNOTEHASH';
58
56
  static readonly opcode: Opcode = Opcode.EMITNOTEHASH;
59
57
  // Informs (de)serialization. See Instruction.deserialize.
60
- static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32];
58
+ static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16];
61
59
 
62
60
  constructor(private indirect: number, private noteHashOffset: number) {
63
61
  super();
64
62
  }
65
63
 
66
64
  public async execute(context: AvmContext): Promise<void> {
67
- const memoryOperations = { reads: 1, indirect: this.indirect };
68
65
  const memory = context.machineState.memory.track(this.type);
69
- context.machineState.consumeGas(this.gasCost(memoryOperations));
66
+ context.machineState.consumeGas(this.gasCost());
70
67
 
71
- const [noteHashOffset] = Addressing.fromWire(this.indirect).resolve([this.noteHashOffset], memory);
68
+ const operands = [this.noteHashOffset];
69
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
70
+ const [noteHashOffset] = addressing.resolve(operands, memory);
72
71
  memory.checkTag(TypeTag.FIELD, noteHashOffset);
73
72
 
74
73
  if (context.environment.isStaticCall) {
@@ -78,7 +77,7 @@ export class EmitNoteHash extends Instruction {
78
77
  const noteHash = memory.get(noteHashOffset).toFr();
79
78
  context.persistableState.writeNoteHash(context.environment.storageAddress, noteHash);
80
79
 
81
- memory.assert(memoryOperations);
80
+ memory.assert({ reads: 1, addressing });
82
81
  context.machineState.incrementPc();
83
82
  }
84
83
  }
@@ -90,9 +89,9 @@ export class NullifierExists extends Instruction {
90
89
  static readonly wireFormat = [
91
90
  OperandType.UINT8,
92
91
  OperandType.UINT8,
93
- OperandType.UINT32,
94
- OperandType.UINT32,
95
- OperandType.UINT32,
92
+ OperandType.UINT16,
93
+ OperandType.UINT16,
94
+ OperandType.UINT16,
96
95
  ];
97
96
 
98
97
  constructor(
@@ -105,23 +104,21 @@ export class NullifierExists extends Instruction {
105
104
  }
106
105
 
107
106
  public async execute(context: AvmContext): Promise<void> {
108
- const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
109
107
  const memory = context.machineState.memory.track(this.type);
110
- context.machineState.consumeGas(this.gasCost(memoryOperations));
108
+ context.machineState.consumeGas(this.gasCost());
111
109
 
112
- const [nullifierOffset, addressOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
113
- [this.nullifierOffset, this.addressOffset, this.existsOffset],
114
- memory,
115
- );
110
+ const operands = [this.nullifierOffset, this.addressOffset, this.existsOffset];
111
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
112
+ const [nullifierOffset, addressOffset, existsOffset] = addressing.resolve(operands, memory);
116
113
  memory.checkTags(TypeTag.FIELD, nullifierOffset, addressOffset);
117
114
 
118
115
  const nullifier = memory.get(nullifierOffset).toFr();
119
116
  const address = memory.get(addressOffset).toFr();
120
117
  const exists = await context.persistableState.checkNullifierExists(address, nullifier);
121
118
 
122
- memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
119
+ memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0));
123
120
 
124
- memory.assert(memoryOperations);
121
+ memory.assert({ reads: 2, writes: 1, addressing });
125
122
  context.machineState.incrementPc();
126
123
  }
127
124
  }
@@ -130,7 +127,7 @@ export class EmitNullifier extends Instruction {
130
127
  static type: string = 'EMITNULLIFIER';
131
128
  static readonly opcode: Opcode = Opcode.EMITNULLIFIER;
132
129
  // Informs (de)serialization. See Instruction.deserialize.
133
- static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32];
130
+ static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16];
134
131
 
135
132
  constructor(private indirect: number, private nullifierOffset: number) {
136
133
  super();
@@ -141,11 +138,12 @@ export class EmitNullifier extends Instruction {
141
138
  throw new StaticCallAlterationError();
142
139
  }
143
140
 
144
- const memoryOperations = { reads: 1, indirect: this.indirect };
145
141
  const memory = context.machineState.memory.track(this.type);
146
- context.machineState.consumeGas(this.gasCost(memoryOperations));
142
+ context.machineState.consumeGas(this.gasCost());
147
143
 
148
- const [nullifierOffset] = Addressing.fromWire(this.indirect).resolve([this.nullifierOffset], memory);
144
+ const operands = [this.nullifierOffset];
145
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
146
+ const [nullifierOffset] = addressing.resolve(operands, memory);
149
147
  memory.checkTag(TypeTag.FIELD, nullifierOffset);
150
148
 
151
149
  const nullifier = memory.get(nullifierOffset).toFr();
@@ -162,7 +160,7 @@ export class EmitNullifier extends Instruction {
162
160
  }
163
161
  }
164
162
 
165
- memory.assert(memoryOperations);
163
+ memory.assert({ reads: 1, addressing });
166
164
  context.machineState.incrementPc();
167
165
  }
168
166
  }
@@ -174,9 +172,9 @@ export class L1ToL2MessageExists extends Instruction {
174
172
  static readonly wireFormat = [
175
173
  OperandType.UINT8,
176
174
  OperandType.UINT8,
177
- OperandType.UINT32,
178
- OperandType.UINT32,
179
- OperandType.UINT32,
175
+ OperandType.UINT16,
176
+ OperandType.UINT16,
177
+ OperandType.UINT16,
180
178
  ];
181
179
 
182
180
  constructor(
@@ -189,14 +187,12 @@ export class L1ToL2MessageExists extends Instruction {
189
187
  }
190
188
 
191
189
  public async execute(context: AvmContext): Promise<void> {
192
- const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
193
190
  const memory = context.machineState.memory.track(this.type);
194
- context.machineState.consumeGas(this.gasCost(memoryOperations));
191
+ context.machineState.consumeGas(this.gasCost());
195
192
 
196
- const [msgHashOffset, msgLeafIndexOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
197
- [this.msgHashOffset, this.msgLeafIndexOffset, this.existsOffset],
198
- memory,
199
- );
193
+ const operands = [this.msgHashOffset, this.msgLeafIndexOffset, this.existsOffset];
194
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
195
+ const [msgHashOffset, msgLeafIndexOffset, existsOffset] = addressing.resolve(operands, memory);
200
196
  memory.checkTags(TypeTag.FIELD, msgHashOffset, msgLeafIndexOffset);
201
197
 
202
198
  const msgHash = memory.get(msgHashOffset).toFr();
@@ -206,9 +202,9 @@ export class L1ToL2MessageExists extends Instruction {
206
202
  msgHash,
207
203
  msgLeafIndex,
208
204
  );
209
- memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
205
+ memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0));
210
206
 
211
- memory.assert(memoryOperations);
207
+ memory.assert({ reads: 2, writes: 1, addressing });
212
208
  context.machineState.incrementPc();
213
209
  }
214
210
  }
@@ -217,7 +213,7 @@ export class EmitUnencryptedLog extends Instruction {
217
213
  static type: string = 'EMITUNENCRYPTEDLOG';
218
214
  static readonly opcode: Opcode = Opcode.EMITUNENCRYPTEDLOG;
219
215
  // Informs (de)serialization. See Instruction.deserialize.
220
- static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32];
216
+ static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16, OperandType.UINT16];
221
217
 
222
218
  constructor(private indirect: number, private logOffset: number, private logSizeOffset: number) {
223
219
  super();
@@ -230,22 +226,20 @@ export class EmitUnencryptedLog extends Instruction {
230
226
 
231
227
  const memory = context.machineState.memory.track(this.type);
232
228
 
233
- const [logOffset, logSizeOffset] = Addressing.fromWire(this.indirect).resolve(
234
- [this.logOffset, this.logSizeOffset],
235
- memory,
236
- );
229
+ const operands = [this.logOffset, this.logSizeOffset];
230
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
231
+ const [logOffset, logSizeOffset] = addressing.resolve(operands, memory);
237
232
  memory.checkTag(TypeTag.UINT32, logSizeOffset);
238
233
  const logSize = memory.get(logSizeOffset).toNumber();
239
234
  memory.checkTagsRange(TypeTag.FIELD, logOffset, logSize);
240
235
 
241
236
  const contractAddress = context.environment.address;
242
237
 
243
- const memoryOperations = { reads: 1 + logSize, indirect: this.indirect };
244
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: logSize }));
238
+ context.machineState.consumeGas(this.gasCost(logSize));
245
239
  const log = memory.getSlice(logOffset, logSize).map(f => f.toFr());
246
240
  context.persistableState.writeUnencryptedLog(contractAddress, log);
247
241
 
248
- memory.assert(memoryOperations);
242
+ memory.assert({ reads: 1 + logSize, addressing });
249
243
  context.machineState.incrementPc();
250
244
  }
251
245
  }
@@ -254,7 +248,7 @@ export class SendL2ToL1Message extends Instruction {
254
248
  static type: string = 'SENDL2TOL1MSG';
255
249
  static readonly opcode: Opcode = Opcode.SENDL2TOL1MSG;
256
250
  // Informs (de)serialization. See Instruction.deserialize.
257
- static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32];
251
+ static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16, OperandType.UINT16];
258
252
 
259
253
  constructor(private indirect: number, private recipientOffset: number, private contentOffset: number) {
260
254
  super();
@@ -265,20 +259,18 @@ export class SendL2ToL1Message extends Instruction {
265
259
  throw new StaticCallAlterationError();
266
260
  }
267
261
 
268
- const memoryOperations = { reads: 2, indirect: this.indirect };
269
262
  const memory = context.machineState.memory.track(this.type);
270
- context.machineState.consumeGas(this.gasCost(memoryOperations));
263
+ context.machineState.consumeGas(this.gasCost());
271
264
 
272
- const [recipientOffset, contentOffset] = Addressing.fromWire(this.indirect).resolve(
273
- [this.recipientOffset, this.contentOffset],
274
- memory,
275
- );
265
+ const operands = [this.recipientOffset, this.contentOffset];
266
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
267
+ const [recipientOffset, contentOffset] = addressing.resolve(operands, memory);
276
268
 
277
269
  const recipient = memory.get(recipientOffset).toFr();
278
270
  const content = memory.get(contentOffset).toFr();
279
- context.persistableState.writeL2ToL1Message(recipient, content);
271
+ context.persistableState.writeL2ToL1Message(context.environment.address, recipient, content);
280
272
 
281
- memory.assert(memoryOperations);
273
+ memory.assert({ reads: 2, addressing });
282
274
  context.machineState.incrementPc();
283
275
  }
284
276
  }
@@ -3,9 +3,10 @@ import { strict as assert } from 'assert';
3
3
  import { type TaggedMemoryInterface } from '../avm_memory_types.js';
4
4
 
5
5
  export enum AddressingMode {
6
- DIRECT,
7
- INDIRECT,
8
- INDIRECT_PLUS_CONSTANT, // Not implemented yet.
6
+ DIRECT = 0,
7
+ INDIRECT = 1,
8
+ RELATIVE = 2,
9
+ INDIRECT_RELATIVE = 3,
9
10
  }
10
11
 
11
12
  /** A class to represent the addressing mode of an instruction. */
@@ -13,16 +14,17 @@ export class Addressing {
13
14
  public constructor(
14
15
  /** The addressing mode for each operand. The length of this array is the number of operands of the instruction. */
15
16
  private readonly modePerOperand: AddressingMode[],
16
- ) {
17
- assert(modePerOperand.length <= 8, 'At most 8 operands are supported');
18
- }
17
+ ) {}
19
18
 
20
- public static fromWire(wireModes: number): Addressing {
19
+ // TODO(facundo): 8 for backwards compatibility.
20
+ public static fromWire(wireModes: number, numOperands: number = 8): Addressing {
21
21
  // The modes are stored in the wire format as a byte, with each bit representing the mode for an operand.
22
22
  // The least significant bit represents the zeroth operand, and the most significant bit represents the last operand.
23
- const modes = new Array<AddressingMode>(8);
24
- for (let i = 0; i < 8; i++) {
25
- modes[i] = (wireModes & (1 << i)) === 0 ? AddressingMode.DIRECT : AddressingMode.INDIRECT;
23
+ const modes = new Array<AddressingMode>(numOperands);
24
+ for (let i = 0; i < numOperands; i++) {
25
+ modes[i] =
26
+ (((wireModes >> i) & 1) * AddressingMode.INDIRECT) |
27
+ (((wireModes >> (i + numOperands)) & 1) * AddressingMode.RELATIVE);
26
28
  }
27
29
  return new Addressing(modes);
28
30
  }
@@ -31,17 +33,20 @@ export class Addressing {
31
33
  // The modes are stored in the wire format as a byte, with each bit representing the mode for an operand.
32
34
  // The least significant bit represents the zeroth operand, and the least significant bit represents the last operand.
33
35
  let wire: number = 0;
34
- for (let i = 0; i < 8; i++) {
35
- if (this.modePerOperand[i] === AddressingMode.INDIRECT) {
36
+ for (let i = 0; i < this.modePerOperand.length; i++) {
37
+ if (this.modePerOperand[i] & AddressingMode.INDIRECT) {
36
38
  wire |= 1 << i;
37
39
  }
40
+ if (this.modePerOperand[i] & AddressingMode.RELATIVE) {
41
+ wire |= 1 << (this.modePerOperand.length + i);
42
+ }
38
43
  }
39
44
  return wire;
40
45
  }
41
46
 
42
47
  /** Returns how many operands use the given addressing mode. */
43
48
  public count(mode: AddressingMode): number {
44
- return this.modePerOperand.filter(m => m === mode).length;
49
+ return this.modePerOperand.filter(m => (m & mode) !== 0).length;
45
50
  }
46
51
 
47
52
  /**
@@ -54,17 +59,15 @@ export class Addressing {
54
59
  assert(offsets.length <= this.modePerOperand.length);
55
60
  const resolved = new Array(offsets.length);
56
61
  for (const [i, offset] of offsets.entries()) {
57
- switch (this.modePerOperand[i]) {
58
- case AddressingMode.INDIRECT:
59
- // NOTE(reviewer): less than equal is a deviation from the spec - i dont see why this shouldnt be possible!
60
- mem.checkIsValidMemoryOffsetTag(offset);
61
- resolved[i] = Number(mem.get(offset).toBigInt());
62
- break;
63
- case AddressingMode.DIRECT:
64
- resolved[i] = offset;
65
- break;
66
- default:
67
- throw new Error(`Unimplemented addressing mode: ${AddressingMode[this.modePerOperand[i]]}`);
62
+ const mode = this.modePerOperand[i];
63
+ resolved[i] = offset;
64
+ if (mode & AddressingMode.RELATIVE) {
65
+ mem.checkIsValidMemoryOffsetTag(0);
66
+ resolved[i] += Number(mem.get(0).toBigInt());
67
+ }
68
+ if (mode & AddressingMode.INDIRECT) {
69
+ mem.checkIsValidMemoryOffsetTag(resolved[i]);
70
+ resolved[i] = Number(mem.get(resolved[i]).toBigInt());
68
71
  }
69
72
  }
70
73
  return resolved;
@@ -6,15 +6,13 @@ import { ThreeOperandInstruction } from './instruction_impl.js';
6
6
 
7
7
  export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInstruction {
8
8
  public async execute(context: AvmContext): Promise<void> {
9
- const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
10
9
  const memory = context.machineState.memory.track(this.type);
11
- context.machineState.consumeGas(this.gasCost(memoryOperations));
10
+ context.machineState.consumeGas(this.gasCost());
12
11
 
13
- const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
14
- [this.aOffset, this.bOffset, this.dstOffset],
15
- memory,
16
- );
17
- memory.checkTags(this.inTag, aOffset, bOffset);
12
+ const operands = [this.aOffset, this.bOffset, this.dstOffset];
13
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
14
+ const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
15
+ memory.checkTagsAreSame(aOffset, bOffset);
18
16
 
19
17
  const a = memory.get(aOffset);
20
18
  const b = memory.get(bOffset);
@@ -22,7 +20,7 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
22
20
  const dest = this.compute(a, b);
23
21
  memory.set(dstOffset, dest);
24
22
 
25
- memory.assert(memoryOperations);
23
+ memory.assert({ reads: 2, writes: 1, addressing });
26
24
  context.machineState.incrementPc();
27
25
  }
28
26
 
@@ -7,15 +7,13 @@ import { ThreeOperandInstruction } from './instruction_impl.js';
7
7
 
8
8
  abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
9
9
  public async execute(context: AvmContext): Promise<void> {
10
- const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
11
10
  const memory = context.machineState.memory.track(this.type);
12
- context.machineState.consumeGas(this.gasCost(memoryOperations));
11
+ context.machineState.consumeGas(this.gasCost());
13
12
 
14
- const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
15
- [this.aOffset, this.bOffset, this.dstOffset],
16
- memory,
17
- );
18
- this.checkTags(memory, this.inTag, aOffset, bOffset);
13
+ const operands = [this.aOffset, this.bOffset, this.dstOffset];
14
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
15
+ const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
16
+ this.checkTags(memory, aOffset, bOffset);
19
17
 
20
18
  const a = memory.getAs<IntegralValue>(aOffset);
21
19
  const b = memory.getAs<IntegralValue>(bOffset);
@@ -23,13 +21,14 @@ abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
23
21
  const res = this.compute(a, b);
24
22
  memory.set(dstOffset, res);
25
23
 
26
- memory.assert(memoryOperations);
24
+ memory.assert({ reads: 2, writes: 1, addressing });
27
25
  context.machineState.incrementPc();
28
26
  }
29
27
 
30
28
  protected abstract compute(a: IntegralValue, b: IntegralValue): IntegralValue;
31
- protected checkTags(memory: TaggedMemoryInterface, inTag: number, aOffset: number, bOffset: number) {
32
- memory.checkTags(inTag, aOffset, bOffset);
29
+ protected checkTags(memory: TaggedMemoryInterface, aOffset: number, bOffset: number) {
30
+ TaggedMemory.checkIsIntegralTag(memory.getTag(aOffset));
31
+ memory.checkTagsAreSame(aOffset, bOffset);
33
32
  }
34
33
  }
35
34
 
@@ -67,8 +66,8 @@ export class Shl extends ThreeOperandBitwiseInstruction {
67
66
  protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue {
68
67
  return a.shl(b);
69
68
  }
70
- protected override checkTags(memory: TaggedMemoryInterface, inTag: number, aOffset: number, bOffset: number) {
71
- memory.checkTag(inTag, aOffset);
69
+ protected override checkTags(memory: TaggedMemoryInterface, aOffset: number, bOffset: number) {
70
+ TaggedMemory.checkIsIntegralTag(memory.getTag(aOffset));
72
71
  memory.checkTag(TypeTag.UINT8, bOffset);
73
72
  }
74
73
  }
@@ -80,8 +79,8 @@ export class Shr extends ThreeOperandBitwiseInstruction {
80
79
  protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue {
81
80
  return a.shr(b);
82
81
  }
83
- protected override checkTags(memory: TaggedMemoryInterface, inTag: number, aOffset: number, bOffset: number) {
84
- memory.checkTag(inTag, aOffset);
82
+ protected override checkTags(memory: TaggedMemoryInterface, aOffset: number, bOffset: number) {
83
+ TaggedMemory.checkIsIntegralTag(memory.getTag(aOffset));
85
84
  memory.checkTag(TypeTag.UINT8, bOffset);
86
85
  }
87
86
  }
@@ -98,18 +97,19 @@ export class Not extends Instruction {
98
97
  }
99
98
 
100
99
  public async execute(context: AvmContext): Promise<void> {
101
- const memoryOperations = { reads: 1, writes: 1, indirect: this.indirect };
102
100
  const memory = context.machineState.memory.track(this.type);
103
- context.machineState.consumeGas(this.gasCost(memoryOperations));
101
+ context.machineState.consumeGas(this.gasCost());
104
102
 
105
- const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.srcOffset, this.dstOffset], memory);
103
+ const operands = [this.srcOffset, this.dstOffset];
104
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
105
+ const [srcOffset, dstOffset] = addressing.resolve(operands, memory);
106
106
  TaggedMemory.checkIsIntegralTag(memory.getTag(srcOffset));
107
107
  const value = memory.getAs<IntegralValue>(srcOffset);
108
108
 
109
109
  const res = value.not();
110
110
  memory.set(dstOffset, res);
111
111
 
112
- memory.assert(memoryOperations);
112
+ memory.assert({ reads: 1, writes: 1, addressing });
113
113
  context.machineState.incrementPc();
114
114
  }
115
115
  }
@@ -32,10 +32,10 @@ export class PedersenCommitment extends Instruction {
32
32
 
33
33
  public async execute(context: AvmContext): Promise<void> {
34
34
  const memory = context.machineState.memory.track(this.type);
35
- const [inputOffset, outputOffset, inputSizeOffset, genIndexOffset] = Addressing.fromWire(this.indirect).resolve(
36
- [this.inputOffset, this.outputOffset, this.inputSizeOffset, this.genIndexOffset],
37
- memory,
38
- );
35
+
36
+ const operands = [this.inputOffset, this.outputOffset, this.inputSizeOffset, this.genIndexOffset];
37
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
38
+ const [inputOffset, outputOffset, inputSizeOffset, genIndexOffset] = addressing.resolve(operands, memory);
39
39
 
40
40
  const inputSize = memory.get(inputSizeOffset).toNumber();
41
41
  memory.checkTag(TypeTag.UINT32, inputSizeOffset);
@@ -46,8 +46,7 @@ export class PedersenCommitment extends Instruction {
46
46
  const generatorIndex = memory.get(genIndexOffset).toNumber();
47
47
  memory.checkTag(TypeTag.UINT32, genIndexOffset);
48
48
 
49
- const memoryOperations = { reads: inputSize + 2, writes: 3, indirect: this.indirect };
50
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: inputSize }));
49
+ context.machineState.consumeGas(this.gasCost(inputSize));
51
50
 
52
51
  const inputBuffer: Buffer[] = inputs.map(input => input.toBuffer());
53
52
  // TODO: Add the generate index to the pedersenCommit function
@@ -60,7 +59,7 @@ export class PedersenCommitment extends Instruction {
60
59
  memory.set(outputOffset + 1, commitment[1]); // Field typed
61
60
  memory.set(outputOffset + 2, new Uint8(isInfinity ? 1 : 0)); // U8 typed
62
61
 
63
- memory.assert(memoryOperations);
62
+ memory.assert({ reads: inputSize + 2, writes: 3, addressing });
64
63
  context.machineState.incrementPc();
65
64
  }
66
65
  }
@@ -6,15 +6,13 @@ import { ThreeOperandInstruction } from './instruction_impl.js';
6
6
 
7
7
  abstract class ComparatorInstruction extends ThreeOperandInstruction {
8
8
  public async execute(context: AvmContext): Promise<void> {
9
- const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
10
9
  const memory = context.machineState.memory.track(this.type);
11
- context.machineState.consumeGas(this.gasCost(memoryOperations));
10
+ context.machineState.consumeGas(this.gasCost());
12
11
 
13
- const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
14
- [this.aOffset, this.bOffset, this.dstOffset],
15
- memory,
16
- );
17
- memory.checkTags(this.inTag, aOffset, bOffset);
12
+ const operands = [this.aOffset, this.bOffset, this.dstOffset];
13
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
14
+ const [aOffset, bOffset, dstOffset] = addressing.resolve(operands, memory);
15
+ memory.checkTagsAreSame(aOffset, bOffset);
18
16
 
19
17
  const a = memory.get(aOffset);
20
18
  const b = memory.get(bOffset);
@@ -22,7 +20,7 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction {
22
20
  const dest = new Uint1(this.compare(a, b) ? 1 : 0);
23
21
  memory.set(dstOffset, dest);
24
22
 
25
- memory.assert(memoryOperations);
23
+ memory.assert({ reads: 2, writes: 1, addressing });
26
24
  context.machineState.incrementPc();
27
25
  }
28
26
 
@@ -22,14 +22,12 @@ export class GetContractInstance extends Instruction {
22
22
  }
23
23
 
24
24
  async execute(context: AvmContext): Promise<void> {
25
- const memoryOperations = { reads: 1, writes: 6, indirect: this.indirect };
26
25
  const memory = context.machineState.memory.track(this.type);
27
- context.machineState.consumeGas(this.gasCost(memoryOperations));
26
+ context.machineState.consumeGas(this.gasCost());
28
27
 
29
- const [addressOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
30
- [this.addressOffset, this.dstOffset],
31
- memory,
32
- );
28
+ const operands = [this.addressOffset, this.dstOffset];
29
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
30
+ const [addressOffset, dstOffset] = addressing.resolve(operands, memory);
33
31
  memory.checkTag(TypeTag.FIELD, addressOffset);
34
32
 
35
33
  const address = memory.get(addressOffset).toFr();
@@ -41,12 +39,13 @@ export class GetContractInstance extends Instruction {
41
39
  instance.deployer.toField(),
42
40
  instance.contractClassId,
43
41
  instance.initializationHash,
44
- instance.publicKeysHash,
42
+ // This this okay ?
43
+ ...instance.publicKeys.toFields(),
45
44
  ].map(f => new Field(f));
46
45
 
47
46
  memory.setSlice(dstOffset, data);
48
47
 
49
- memory.assert(memoryOperations);
48
+ memory.assert({ reads: 1, writes: 17, addressing });
50
49
  context.machineState.incrementPc();
51
50
  }
52
51
  }
@@ -41,21 +41,21 @@ export class JumpI extends Instruction {
41
41
  }
42
42
 
43
43
  public async execute(context: AvmContext): Promise<void> {
44
- const memoryOperations = { reads: 1, indirect: this.indirect };
45
44
  const memory = context.machineState.memory.track(this.type);
46
- context.machineState.consumeGas(this.gasCost(memoryOperations));
45
+ context.machineState.consumeGas(this.gasCost());
47
46
 
48
- const [condOffset] = Addressing.fromWire(this.indirect).resolve([this.condOffset], memory);
47
+ const operands = [this.condOffset];
48
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
49
+ const [condOffset] = addressing.resolve(operands, memory);
49
50
  const condition = memory.getAs<IntegralValue>(condOffset);
50
51
 
51
- // TODO: reconsider this casting
52
52
  if (condition.toBigInt() == 0n) {
53
53
  context.machineState.incrementPc();
54
54
  } else {
55
55
  context.machineState.pc = this.loc;
56
56
  }
57
57
 
58
- memory.assert(memoryOperations);
58
+ memory.assert({ reads: 1, addressing });
59
59
  }
60
60
  }
61
61
 
@@ -63,7 +63,7 @@ export class InternalCall extends Instruction {
63
63
  static readonly type: string = 'INTERNALCALL';
64
64
  static readonly opcode: Opcode = Opcode.INTERNALCALL;
65
65
  // Informs (de)serialization. See Instruction.deserialize.
66
- static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT32];
66
+ static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT16];
67
67
 
68
68
  constructor(private loc: number) {
69
69
  super();
@@ -13,11 +13,11 @@ export class ToRadixLE extends Instruction {
13
13
  static readonly wireFormat: OperandType[] = [
14
14
  OperandType.UINT8, // Opcode
15
15
  OperandType.UINT8, // Indirect
16
- OperandType.UINT32, // src memory address
17
- OperandType.UINT32, // dst memory address
18
- OperandType.UINT32, // radix memory address
19
- OperandType.UINT32, // number of limbs (Immediate)
20
- OperandType.UINT1, // output is in "bits" mode (Immediate - Uint1 still takes up a whole byte)
16
+ OperandType.UINT16, // src memory address
17
+ OperandType.UINT16, // dst memory address
18
+ OperandType.UINT16, // radix memory address
19
+ OperandType.UINT16, // number of limbs (Immediate)
20
+ OperandType.UINT8, // output is in "bits" mode (Immediate - Uint1 still takes up a whole byte)
21
21
  ];
22
22
 
23
23
  constructor(
@@ -33,12 +33,10 @@ export class ToRadixLE extends Instruction {
33
33
 
34
34
  public async execute(context: AvmContext): Promise<void> {
35
35
  const memory = context.machineState.memory.track(this.type);
36
- const [srcOffset, dstOffset, radixOffset] = Addressing.fromWire(this.indirect).resolve(
37
- [this.srcOffset, this.dstOffset, this.radixOffset],
38
- memory,
39
- );
40
- const memoryOperations = { reads: 2, writes: this.numLimbs, indirect: this.indirect };
41
- context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.numLimbs }));
36
+ const operands = [this.srcOffset, this.dstOffset, this.radixOffset];
37
+ const addressing = Addressing.fromWire(this.indirect, operands.length);
38
+ const [srcOffset, dstOffset, radixOffset] = addressing.resolve(operands, memory);
39
+ context.machineState.consumeGas(this.gasCost(this.numLimbs));
42
40
 
43
41
  // The radix gadget only takes in a Field
44
42
  memory.checkTag(TypeTag.FIELD, srcOffset);
@@ -62,7 +60,7 @@ export class ToRadixLE extends Instruction {
62
60
  const res = limbArray.map(byte => new outputType(byte));
63
61
  memory.setSlice(dstOffset, res);
64
62
 
65
- memory.assert(memoryOperations);
63
+ memory.assert({ reads: 2, writes: this.numLimbs, addressing });
66
64
  context.machineState.incrementPc();
67
65
  }
68
66
  }