@aztec/simulator 0.53.0 → 0.55.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 (60) hide show
  1. package/dest/avm/avm_execution_environment.d.ts +2 -2
  2. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  3. package/dest/avm/avm_execution_environment.js +5 -6
  4. package/dest/avm/avm_gas.d.ts.map +1 -1
  5. package/dest/avm/avm_gas.js +85 -41
  6. package/dest/avm/avm_memory_types.d.ts +1 -1
  7. package/dest/avm/avm_memory_types.d.ts.map +1 -1
  8. package/dest/avm/avm_memory_types.js +5 -3
  9. package/dest/avm/bytecode_utils.js +5 -5
  10. package/dest/avm/opcodes/arithmetic.d.ts +9 -16
  11. package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
  12. package/dest/avm/opcodes/arithmetic.js +12 -37
  13. package/dest/avm/opcodes/bitwise.d.ts +6 -6
  14. package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
  15. package/dest/avm/opcodes/bitwise.js +7 -7
  16. package/dest/avm/opcodes/comparators.d.ts +3 -3
  17. package/dest/avm/opcodes/comparators.d.ts.map +1 -1
  18. package/dest/avm/opcodes/comparators.js +4 -4
  19. package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
  20. package/dest/avm/opcodes/control_flow.js +6 -6
  21. package/dest/avm/opcodes/external_calls.d.ts +2 -1
  22. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  23. package/dest/avm/opcodes/external_calls.js +11 -6
  24. package/dest/avm/opcodes/instruction.d.ts +18 -12
  25. package/dest/avm/opcodes/instruction.d.ts.map +1 -1
  26. package/dest/avm/opcodes/instruction.js +36 -19
  27. package/dest/avm/opcodes/instruction_impl.d.ts +10 -6
  28. package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
  29. package/dest/avm/opcodes/instruction_impl.js +29 -13
  30. package/dest/avm/opcodes/memory.d.ts +9 -10
  31. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  32. package/dest/avm/opcodes/memory.js +60 -60
  33. package/dest/avm/serialization/bytecode_serialization.d.ts +7 -8
  34. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  35. package/dest/avm/serialization/bytecode_serialization.js +86 -64
  36. package/dest/avm/serialization/instruction_serialization.d.ts +87 -64
  37. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  38. package/dest/avm/serialization/instruction_serialization.js +105 -67
  39. package/dest/public/hints_builder.d.ts +3 -4
  40. package/dest/public/hints_builder.d.ts.map +1 -1
  41. package/dest/public/hints_builder.js +2 -5
  42. package/dest/public/tail_phase_manager.d.ts.map +1 -1
  43. package/dest/public/tail_phase_manager.js +2 -3
  44. package/package.json +9 -9
  45. package/src/avm/avm_execution_environment.ts +3 -4
  46. package/src/avm/avm_gas.ts +84 -40
  47. package/src/avm/avm_memory_types.ts +4 -2
  48. package/src/avm/bytecode_utils.ts +4 -4
  49. package/src/avm/opcodes/arithmetic.ts +12 -41
  50. package/src/avm/opcodes/bitwise.ts +6 -6
  51. package/src/avm/opcodes/comparators.ts +3 -3
  52. package/src/avm/opcodes/control_flow.ts +5 -5
  53. package/src/avm/opcodes/external_calls.ts +11 -5
  54. package/src/avm/opcodes/instruction.ts +41 -19
  55. package/src/avm/opcodes/instruction_impl.ts +28 -12
  56. package/src/avm/opcodes/memory.ts +61 -67
  57. package/src/avm/serialization/bytecode_serialization.ts +96 -73
  58. package/src/avm/serialization/instruction_serialization.ts +64 -24
  59. package/src/public/hints_builder.ts +0 -11
  60. package/src/public/tail_phase_manager.ts +0 -7
@@ -57,21 +57,36 @@ export const GasDimensions = ['l2Gas', 'daGas'] as const;
57
57
 
58
58
  /** Base gas costs for each instruction. Additional gas cost may be added on top due to memory or storage accesses, etc. */
59
59
  const BaseGasCosts: Record<Opcode, Gas> = {
60
- [Opcode.ADD]: makeCost(c.AVM_ADD_BASE_L2_GAS, 0),
61
- [Opcode.SUB]: makeCost(c.AVM_SUB_BASE_L2_GAS, 0),
62
- [Opcode.MUL]: makeCost(c.AVM_MUL_BASE_L2_GAS, 0),
63
- [Opcode.DIV]: makeCost(c.AVM_DIV_BASE_L2_GAS, 0),
64
- [Opcode.FDIV]: makeCost(c.AVM_FDIV_BASE_L2_GAS, 0),
65
- [Opcode.EQ]: makeCost(c.AVM_EQ_BASE_L2_GAS, 0),
66
- [Opcode.LT]: makeCost(c.AVM_LT_BASE_L2_GAS, 0),
67
- [Opcode.LTE]: makeCost(c.AVM_LTE_BASE_L2_GAS, 0),
68
- [Opcode.AND]: makeCost(c.AVM_AND_BASE_L2_GAS, 0),
69
- [Opcode.OR]: makeCost(c.AVM_OR_BASE_L2_GAS, 0),
70
- [Opcode.XOR]: makeCost(c.AVM_XOR_BASE_L2_GAS, 0),
71
- [Opcode.NOT]: makeCost(c.AVM_NOT_BASE_L2_GAS, 0),
72
- [Opcode.SHL]: makeCost(c.AVM_SHL_BASE_L2_GAS, 0),
73
- [Opcode.SHR]: makeCost(c.AVM_SHR_BASE_L2_GAS, 0),
74
- [Opcode.CAST]: makeCost(c.AVM_CAST_BASE_L2_GAS, 0),
60
+ [Opcode.ADD_8]: makeCost(c.AVM_ADD_BASE_L2_GAS, 0),
61
+ [Opcode.ADD_16]: makeCost(c.AVM_ADD_BASE_L2_GAS, 0),
62
+ [Opcode.SUB_8]: makeCost(c.AVM_SUB_BASE_L2_GAS, 0),
63
+ [Opcode.SUB_16]: makeCost(c.AVM_SUB_BASE_L2_GAS, 0),
64
+ [Opcode.MUL_8]: makeCost(c.AVM_MUL_BASE_L2_GAS, 0),
65
+ [Opcode.MUL_16]: makeCost(c.AVM_MUL_BASE_L2_GAS, 0),
66
+ [Opcode.DIV_8]: makeCost(c.AVM_DIV_BASE_L2_GAS, 0),
67
+ [Opcode.DIV_16]: makeCost(c.AVM_DIV_BASE_L2_GAS, 0),
68
+ [Opcode.FDIV_8]: makeCost(c.AVM_FDIV_BASE_L2_GAS, 0),
69
+ [Opcode.FDIV_16]: makeCost(c.AVM_FDIV_BASE_L2_GAS, 0),
70
+ [Opcode.EQ_8]: makeCost(c.AVM_EQ_BASE_L2_GAS, 0),
71
+ [Opcode.EQ_16]: makeCost(c.AVM_EQ_BASE_L2_GAS, 0),
72
+ [Opcode.LT_8]: makeCost(c.AVM_LT_BASE_L2_GAS, 0),
73
+ [Opcode.LT_16]: makeCost(c.AVM_LT_BASE_L2_GAS, 0),
74
+ [Opcode.LTE_8]: makeCost(c.AVM_LTE_BASE_L2_GAS, 0),
75
+ [Opcode.LTE_16]: makeCost(c.AVM_LTE_BASE_L2_GAS, 0),
76
+ [Opcode.AND_8]: makeCost(c.AVM_AND_BASE_L2_GAS, 0),
77
+ [Opcode.AND_16]: makeCost(c.AVM_AND_BASE_L2_GAS, 0),
78
+ [Opcode.OR_8]: makeCost(c.AVM_OR_BASE_L2_GAS, 0),
79
+ [Opcode.OR_16]: makeCost(c.AVM_OR_BASE_L2_GAS, 0),
80
+ [Opcode.XOR_8]: makeCost(c.AVM_XOR_BASE_L2_GAS, 0),
81
+ [Opcode.XOR_16]: makeCost(c.AVM_XOR_BASE_L2_GAS, 0),
82
+ [Opcode.NOT_8]: makeCost(c.AVM_NOT_BASE_L2_GAS, 0),
83
+ [Opcode.NOT_16]: makeCost(c.AVM_NOT_BASE_L2_GAS, 0),
84
+ [Opcode.SHL_8]: makeCost(c.AVM_SHL_BASE_L2_GAS, 0),
85
+ [Opcode.SHL_16]: makeCost(c.AVM_SHL_BASE_L2_GAS, 0),
86
+ [Opcode.SHR_8]: makeCost(c.AVM_SHR_BASE_L2_GAS, 0),
87
+ [Opcode.SHR_16]: makeCost(c.AVM_SHR_BASE_L2_GAS, 0),
88
+ [Opcode.CAST_8]: makeCost(c.AVM_CAST_BASE_L2_GAS, 0),
89
+ [Opcode.CAST_16]: makeCost(c.AVM_CAST_BASE_L2_GAS, 0),
75
90
  [Opcode.ADDRESS]: makeCost(c.AVM_ADDRESS_BASE_L2_GAS, 0),
76
91
  [Opcode.STORAGEADDRESS]: makeCost(c.AVM_STORAGEADDRESS_BASE_L2_GAS, 0),
77
92
  [Opcode.SENDER]: makeCost(c.AVM_SENDER_BASE_L2_GAS, 0),
@@ -86,12 +101,18 @@ const BaseGasCosts: Record<Opcode, Gas> = {
86
101
  [Opcode.CALLDATACOPY]: makeCost(c.AVM_CALLDATACOPY_BASE_L2_GAS, 0),
87
102
  [Opcode.L2GASLEFT]: makeCost(c.AVM_L2GASLEFT_BASE_L2_GAS, 0),
88
103
  [Opcode.DAGASLEFT]: makeCost(c.AVM_DAGASLEFT_BASE_L2_GAS, 0),
89
- [Opcode.JUMP]: makeCost(c.AVM_JUMP_BASE_L2_GAS, 0),
90
- [Opcode.JUMPI]: makeCost(c.AVM_JUMPI_BASE_L2_GAS, 0),
104
+ [Opcode.JUMP_16]: makeCost(c.AVM_JUMP_BASE_L2_GAS, 0),
105
+ [Opcode.JUMPI_16]: makeCost(c.AVM_JUMPI_BASE_L2_GAS, 0),
91
106
  [Opcode.INTERNALCALL]: makeCost(c.AVM_INTERNALCALL_BASE_L2_GAS, 0),
92
107
  [Opcode.INTERNALRETURN]: makeCost(c.AVM_INTERNALRETURN_BASE_L2_GAS, 0),
93
- [Opcode.SET]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
94
- [Opcode.MOV]: makeCost(c.AVM_MOV_BASE_L2_GAS, 0),
108
+ [Opcode.SET_8]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
109
+ [Opcode.SET_16]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
110
+ [Opcode.SET_32]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
111
+ [Opcode.SET_64]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
112
+ [Opcode.SET_128]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
113
+ [Opcode.SET_FF]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
114
+ [Opcode.MOV_8]: makeCost(c.AVM_MOV_BASE_L2_GAS, 0),
115
+ [Opcode.MOV_16]: makeCost(c.AVM_MOV_BASE_L2_GAS, 0),
95
116
  [Opcode.CMOV]: makeCost(c.AVM_CMOV_BASE_L2_GAS, 0),
96
117
  [Opcode.SLOAD]: makeCost(c.AVM_SLOAD_BASE_L2_GAS, 0),
97
118
  [Opcode.SSTORE]: makeCost(c.AVM_SSTORE_BASE_L2_GAS, 0),
@@ -107,7 +128,8 @@ const BaseGasCosts: Record<Opcode, Gas> = {
107
128
  [Opcode.STATICCALL]: makeCost(c.AVM_STATICCALL_BASE_L2_GAS, 0),
108
129
  [Opcode.DELEGATECALL]: makeCost(c.AVM_DELEGATECALL_BASE_L2_GAS, 0),
109
130
  [Opcode.RETURN]: makeCost(c.AVM_RETURN_BASE_L2_GAS, 0),
110
- [Opcode.REVERT]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0),
131
+ [Opcode.REVERT_8]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0),
132
+ [Opcode.REVERT_16]: makeCost(c.AVM_REVERT_BASE_L2_GAS, 0),
111
133
  [Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_BASE_L2_GAS, 0),
112
134
  [Opcode.KECCAK]: makeCost(c.AVM_KECCAK_BASE_L2_GAS, 0),
113
135
  [Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_BASE_L2_GAS, 0),
@@ -122,21 +144,36 @@ const BaseGasCosts: Record<Opcode, Gas> = {
122
144
  };
123
145
 
124
146
  const DynamicGasCosts: Record<Opcode, Gas> = {
125
- [Opcode.ADD]: makeCost(c.AVM_ADD_DYN_L2_GAS, 0),
126
- [Opcode.SUB]: makeCost(c.AVM_SUB_DYN_L2_GAS, 0),
127
- [Opcode.MUL]: makeCost(c.AVM_MUL_DYN_L2_GAS, 0),
128
- [Opcode.DIV]: makeCost(c.AVM_DIV_DYN_L2_GAS, 0),
129
- [Opcode.FDIV]: makeCost(c.AVM_FDIV_DYN_L2_GAS, 0),
130
- [Opcode.EQ]: makeCost(c.AVM_EQ_DYN_L2_GAS, 0),
131
- [Opcode.LT]: makeCost(c.AVM_LT_DYN_L2_GAS, 0),
132
- [Opcode.LTE]: makeCost(c.AVM_LTE_DYN_L2_GAS, 0),
133
- [Opcode.AND]: makeCost(c.AVM_AND_DYN_L2_GAS, 0),
134
- [Opcode.OR]: makeCost(c.AVM_OR_DYN_L2_GAS, 0),
135
- [Opcode.XOR]: makeCost(c.AVM_XOR_DYN_L2_GAS, 0),
136
- [Opcode.NOT]: makeCost(c.AVM_NOT_DYN_L2_GAS, 0),
137
- [Opcode.SHL]: makeCost(c.AVM_SHL_DYN_L2_GAS, 0),
138
- [Opcode.SHR]: makeCost(c.AVM_SHR_DYN_L2_GAS, 0),
139
- [Opcode.CAST]: makeCost(c.AVM_CAST_DYN_L2_GAS, 0),
147
+ [Opcode.ADD_8]: makeCost(c.AVM_ADD_DYN_L2_GAS, 0),
148
+ [Opcode.ADD_16]: makeCost(c.AVM_ADD_DYN_L2_GAS, 0),
149
+ [Opcode.SUB_8]: makeCost(c.AVM_SUB_DYN_L2_GAS, 0),
150
+ [Opcode.SUB_16]: makeCost(c.AVM_SUB_DYN_L2_GAS, 0),
151
+ [Opcode.MUL_8]: makeCost(c.AVM_MUL_DYN_L2_GAS, 0),
152
+ [Opcode.MUL_16]: makeCost(c.AVM_MUL_DYN_L2_GAS, 0),
153
+ [Opcode.DIV_8]: makeCost(c.AVM_DIV_DYN_L2_GAS, 0),
154
+ [Opcode.DIV_16]: makeCost(c.AVM_DIV_DYN_L2_GAS, 0),
155
+ [Opcode.FDIV_8]: makeCost(c.AVM_FDIV_DYN_L2_GAS, 0),
156
+ [Opcode.FDIV_16]: makeCost(c.AVM_FDIV_DYN_L2_GAS, 0),
157
+ [Opcode.EQ_8]: makeCost(c.AVM_EQ_DYN_L2_GAS, 0),
158
+ [Opcode.EQ_16]: makeCost(c.AVM_EQ_DYN_L2_GAS, 0),
159
+ [Opcode.LT_8]: makeCost(c.AVM_LT_DYN_L2_GAS, 0),
160
+ [Opcode.LT_16]: makeCost(c.AVM_LT_DYN_L2_GAS, 0),
161
+ [Opcode.LTE_8]: makeCost(c.AVM_LTE_DYN_L2_GAS, 0),
162
+ [Opcode.LTE_16]: makeCost(c.AVM_LTE_DYN_L2_GAS, 0),
163
+ [Opcode.AND_8]: makeCost(c.AVM_AND_DYN_L2_GAS, 0),
164
+ [Opcode.AND_16]: makeCost(c.AVM_AND_DYN_L2_GAS, 0),
165
+ [Opcode.OR_8]: makeCost(c.AVM_OR_DYN_L2_GAS, 0),
166
+ [Opcode.OR_16]: makeCost(c.AVM_OR_DYN_L2_GAS, 0),
167
+ [Opcode.XOR_8]: makeCost(c.AVM_XOR_DYN_L2_GAS, 0),
168
+ [Opcode.XOR_16]: makeCost(c.AVM_XOR_DYN_L2_GAS, 0),
169
+ [Opcode.NOT_8]: makeCost(c.AVM_NOT_DYN_L2_GAS, 0),
170
+ [Opcode.NOT_16]: makeCost(c.AVM_NOT_DYN_L2_GAS, 0),
171
+ [Opcode.SHL_8]: makeCost(c.AVM_SHL_DYN_L2_GAS, 0),
172
+ [Opcode.SHL_16]: makeCost(c.AVM_SHL_DYN_L2_GAS, 0),
173
+ [Opcode.SHR_8]: makeCost(c.AVM_SHR_DYN_L2_GAS, 0),
174
+ [Opcode.SHR_16]: makeCost(c.AVM_SHR_DYN_L2_GAS, 0),
175
+ [Opcode.CAST_8]: makeCost(c.AVM_CAST_DYN_L2_GAS, 0),
176
+ [Opcode.CAST_16]: makeCost(c.AVM_CAST_DYN_L2_GAS, 0),
140
177
  [Opcode.ADDRESS]: makeCost(c.AVM_ADDRESS_DYN_L2_GAS, 0),
141
178
  [Opcode.STORAGEADDRESS]: makeCost(c.AVM_STORAGEADDRESS_DYN_L2_GAS, 0),
142
179
  [Opcode.SENDER]: makeCost(c.AVM_SENDER_DYN_L2_GAS, 0),
@@ -151,12 +188,18 @@ const DynamicGasCosts: Record<Opcode, Gas> = {
151
188
  [Opcode.CALLDATACOPY]: makeCost(c.AVM_CALLDATACOPY_DYN_L2_GAS, 0),
152
189
  [Opcode.L2GASLEFT]: makeCost(c.AVM_L2GASLEFT_DYN_L2_GAS, 0),
153
190
  [Opcode.DAGASLEFT]: makeCost(c.AVM_DAGASLEFT_DYN_L2_GAS, 0),
154
- [Opcode.JUMP]: makeCost(c.AVM_JUMP_DYN_L2_GAS, 0),
155
- [Opcode.JUMPI]: makeCost(c.AVM_JUMPI_DYN_L2_GAS, 0),
191
+ [Opcode.JUMP_16]: makeCost(c.AVM_JUMP_DYN_L2_GAS, 0),
192
+ [Opcode.JUMPI_16]: makeCost(c.AVM_JUMPI_DYN_L2_GAS, 0),
156
193
  [Opcode.INTERNALCALL]: makeCost(c.AVM_INTERNALCALL_DYN_L2_GAS, 0),
157
194
  [Opcode.INTERNALRETURN]: makeCost(c.AVM_INTERNALRETURN_DYN_L2_GAS, 0),
158
- [Opcode.SET]: makeCost(c.AVM_SET_DYN_L2_GAS, 0),
159
- [Opcode.MOV]: makeCost(c.AVM_MOV_DYN_L2_GAS, 0),
195
+ [Opcode.SET_8]: makeCost(c.AVM_SET_DYN_L2_GAS, 0),
196
+ [Opcode.SET_16]: makeCost(c.AVM_SET_DYN_L2_GAS, 0),
197
+ [Opcode.SET_32]: makeCost(c.AVM_SET_DYN_L2_GAS, 0),
198
+ [Opcode.SET_64]: makeCost(c.AVM_SET_DYN_L2_GAS, 0),
199
+ [Opcode.SET_128]: makeCost(c.AVM_SET_DYN_L2_GAS, 0),
200
+ [Opcode.SET_FF]: makeCost(c.AVM_SET_DYN_L2_GAS, 0),
201
+ [Opcode.MOV_8]: makeCost(c.AVM_MOV_DYN_L2_GAS, 0),
202
+ [Opcode.MOV_16]: makeCost(c.AVM_MOV_DYN_L2_GAS, 0),
160
203
  [Opcode.CMOV]: makeCost(c.AVM_CMOV_DYN_L2_GAS, 0),
161
204
  [Opcode.SLOAD]: makeCost(c.AVM_SLOAD_DYN_L2_GAS, 0),
162
205
  [Opcode.SSTORE]: makeCost(c.AVM_SSTORE_DYN_L2_GAS, 0),
@@ -172,7 +215,8 @@ const DynamicGasCosts: Record<Opcode, Gas> = {
172
215
  [Opcode.STATICCALL]: makeCost(c.AVM_STATICCALL_DYN_L2_GAS, 0),
173
216
  [Opcode.DELEGATECALL]: makeCost(c.AVM_DELEGATECALL_DYN_L2_GAS, 0),
174
217
  [Opcode.RETURN]: makeCost(c.AVM_RETURN_DYN_L2_GAS, 0),
175
- [Opcode.REVERT]: makeCost(c.AVM_REVERT_DYN_L2_GAS, 0),
218
+ [Opcode.REVERT_8]: makeCost(c.AVM_REVERT_DYN_L2_GAS, 0),
219
+ [Opcode.REVERT_16]: makeCost(c.AVM_REVERT_DYN_L2_GAS, 0),
176
220
  [Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_DYN_L2_GAS, 0),
177
221
  [Opcode.KECCAK]: makeCost(c.AVM_KECCAK_DYN_L2_GAS, 0),
178
222
  [Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_DYN_L2_GAS, 0),
@@ -350,7 +350,7 @@ export class TaggedMemory implements TaggedMemoryInterface {
350
350
  }
351
351
 
352
352
  // Truncates the value to fit the type.
353
- public static integralFromTag(v: bigint | number, tag: TypeTag): IntegralValue {
353
+ public static buildFromTagTruncating(v: bigint | number, tag: TypeTag): MemoryValue {
354
354
  v = BigInt(v);
355
355
  switch (tag) {
356
356
  case TypeTag.UINT8:
@@ -363,8 +363,10 @@ export class TaggedMemory implements TaggedMemoryInterface {
363
363
  return new Uint64(v & ((1n << 64n) - 1n));
364
364
  case TypeTag.UINT128:
365
365
  return new Uint128(v & ((1n << 128n) - 1n));
366
+ case TypeTag.FIELD:
367
+ return new Field(v);
366
368
  default:
367
- throw new Error(`${TypeTag[tag]} is not a valid integral type.`);
369
+ throw new Error(`${TypeTag[tag]} is not a valid tag.`);
368
370
  }
369
371
  }
370
372
 
@@ -1,13 +1,13 @@
1
1
  import { promisify } from 'util';
2
2
  import { gunzip } from 'zlib';
3
3
 
4
- import { Mov } from '../avm/opcodes/memory.js';
4
+ import { Opcode } from './serialization/instruction_serialization.js';
5
5
 
6
6
  const AVM_MAGIC_SUFFIX = Buffer.from([
7
- Mov.opcode, // opcode
7
+ Opcode.MOV_16, // opcode
8
8
  0x00, // indirect
9
- ...Buffer.from('000018ca', 'hex'), // srcOffset
10
- ...Buffer.from('000018ca', 'hex'), // dstOffset
9
+ ...Buffer.from('18ca', 'hex'), // srcOffset
10
+ ...Buffer.from('18ca', 'hex'), // dstOffset
11
11
  ]);
12
12
 
13
13
  export function markBytecodeAsAvm(bytecode: Buffer): Buffer {
@@ -1,8 +1,7 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
- import { type Field, type MemoryValue, TypeTag } from '../avm_memory_types.js';
3
- import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
2
+ import { type Field, type MemoryValue } from '../avm_memory_types.js';
3
+ import { Opcode } from '../serialization/instruction_serialization.js';
4
4
  import { Addressing } from './addressing_mode.js';
5
- import { Instruction } from './instruction.js';
6
5
  import { ThreeOperandInstruction } from './instruction_impl.js';
7
6
 
8
7
  export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInstruction {
@@ -32,7 +31,7 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
32
31
 
33
32
  export class Add extends ThreeOperandArithmeticInstruction {
34
33
  static readonly type: string = 'ADD';
35
- static readonly opcode = Opcode.ADD;
34
+ static readonly opcode = Opcode.ADD_8; // FIXME: needed for gas.
36
35
 
37
36
  protected compute(a: MemoryValue, b: MemoryValue): MemoryValue {
38
37
  return a.add(b);
@@ -41,7 +40,7 @@ export class Add extends ThreeOperandArithmeticInstruction {
41
40
 
42
41
  export class Sub extends ThreeOperandArithmeticInstruction {
43
42
  static readonly type: string = 'SUB';
44
- static readonly opcode = Opcode.SUB;
43
+ static readonly opcode = Opcode.SUB_8; // FIXME: needed for gas.
45
44
 
46
45
  protected compute(a: MemoryValue, b: MemoryValue): MemoryValue {
47
46
  return a.sub(b);
@@ -50,7 +49,7 @@ export class Sub extends ThreeOperandArithmeticInstruction {
50
49
 
51
50
  export class Mul extends ThreeOperandArithmeticInstruction {
52
51
  static type: string = 'MUL';
53
- static readonly opcode = Opcode.MUL;
52
+ static readonly opcode = Opcode.MUL_8; // FIXME: needed for gas.
54
53
 
55
54
  protected compute(a: MemoryValue, b: MemoryValue): MemoryValue {
56
55
  return a.mul(b);
@@ -59,48 +58,20 @@ export class Mul extends ThreeOperandArithmeticInstruction {
59
58
 
60
59
  export class Div extends ThreeOperandArithmeticInstruction {
61
60
  static type: string = 'DIV';
62
- static readonly opcode = Opcode.DIV;
61
+ static readonly opcode = Opcode.DIV_8; // FIXME: needed for gas.
63
62
 
64
63
  protected compute(a: MemoryValue, b: MemoryValue): MemoryValue {
65
64
  return a.div(b);
66
65
  }
67
66
  }
68
67
 
69
- export class FieldDiv extends Instruction {
68
+ // TODO: This class now temporarily has a tag, until all tags are removed.
69
+ export class FieldDiv extends ThreeOperandArithmeticInstruction {
70
70
  static type: string = 'FDIV';
71
- static readonly opcode = Opcode.FDIV;
72
-
73
- // Informs (de)serialization. See Instruction.deserialize.
74
- static readonly wireFormat: OperandType[] = [
75
- OperandType.UINT8,
76
- OperandType.UINT8,
77
- OperandType.UINT32,
78
- OperandType.UINT32,
79
- OperandType.UINT32,
80
- ];
81
-
82
- constructor(private indirect: number, private aOffset: number, private bOffset: number, private dstOffset: number) {
83
- super();
84
- }
85
-
86
- public async execute(context: AvmContext): Promise<void> {
87
- const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
88
- const memory = context.machineState.memory.track(this.type);
89
- context.machineState.consumeGas(this.gasCost(memoryOperations));
90
-
91
- const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
92
- [this.aOffset, this.bOffset, this.dstOffset],
93
- memory,
94
- );
95
- memory.checkTags(TypeTag.FIELD, aOffset, bOffset);
96
-
97
- const a = memory.getAs<Field>(aOffset);
98
- const b = memory.getAs<Field>(bOffset);
71
+ static readonly opcode = Opcode.FDIV_8; // FIXME: needed for gas.
99
72
 
100
- const dest = a.fdiv(b);
101
- memory.set(dstOffset, dest);
102
-
103
- memory.assert(memoryOperations);
104
- context.machineState.incrementPc();
73
+ protected compute(a: Field, b: Field): Field {
74
+ // return (a as Field).fdiv(b as Field);
75
+ return a.fdiv(b);
105
76
  }
106
77
  }
@@ -34,7 +34,7 @@ abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
34
34
 
35
35
  export class And extends ThreeOperandBitwiseInstruction {
36
36
  static readonly type: string = 'AND';
37
- static readonly opcode = Opcode.AND;
37
+ static readonly opcode = Opcode.AND_8; // FIXME: needed for gas.
38
38
 
39
39
  protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue {
40
40
  return a.and(b);
@@ -43,7 +43,7 @@ export class And extends ThreeOperandBitwiseInstruction {
43
43
 
44
44
  export class Or extends ThreeOperandBitwiseInstruction {
45
45
  static readonly type: string = 'OR';
46
- static readonly opcode = Opcode.OR;
46
+ static readonly opcode = Opcode.OR_8; // FIXME: needed for gas.
47
47
 
48
48
  protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue {
49
49
  return a.or(b);
@@ -52,7 +52,7 @@ export class Or extends ThreeOperandBitwiseInstruction {
52
52
 
53
53
  export class Xor extends ThreeOperandBitwiseInstruction {
54
54
  static readonly type: string = 'XOR';
55
- static readonly opcode = Opcode.XOR;
55
+ static readonly opcode = Opcode.XOR_8; // FIXME: needed for gas.
56
56
 
57
57
  protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue {
58
58
  return a.xor(b);
@@ -61,7 +61,7 @@ export class Xor extends ThreeOperandBitwiseInstruction {
61
61
 
62
62
  export class Shl extends ThreeOperandBitwiseInstruction {
63
63
  static readonly type: string = 'SHL';
64
- static readonly opcode = Opcode.SHL;
64
+ static readonly opcode = Opcode.SHL_8; // FIXME: needed for gas.
65
65
 
66
66
  protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue {
67
67
  return a.shl(b);
@@ -74,7 +74,7 @@ export class Shl extends ThreeOperandBitwiseInstruction {
74
74
 
75
75
  export class Shr extends ThreeOperandBitwiseInstruction {
76
76
  static readonly type: string = 'SHR';
77
- static readonly opcode = Opcode.SHR;
77
+ static readonly opcode = Opcode.SHR_8; // FIXME: needed for gas.
78
78
 
79
79
  protected override compute(a: IntegralValue, b: IntegralValue): IntegralValue {
80
80
  return a.shr(b);
@@ -87,7 +87,7 @@ export class Shr extends ThreeOperandBitwiseInstruction {
87
87
 
88
88
  export class Not extends TwoOperandInstruction {
89
89
  static readonly type: string = 'NOT';
90
- static readonly opcode = Opcode.NOT;
90
+ static readonly opcode = Opcode.NOT_8;
91
91
 
92
92
  constructor(indirect: number, inTag: number, aOffset: number, dstOffset: number) {
93
93
  super(indirect, inTag, aOffset, dstOffset);
@@ -31,7 +31,7 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction {
31
31
 
32
32
  export class Eq extends ComparatorInstruction {
33
33
  static readonly type: string = 'EQ';
34
- static readonly opcode = Opcode.EQ;
34
+ static readonly opcode = Opcode.EQ_8; // FIXME: needed for gas.
35
35
 
36
36
  protected compare(a: MemoryValue, b: MemoryValue): boolean {
37
37
  return a.equals(b);
@@ -40,7 +40,7 @@ export class Eq extends ComparatorInstruction {
40
40
 
41
41
  export class Lt extends ComparatorInstruction {
42
42
  static readonly type: string = 'LT';
43
- static readonly opcode = Opcode.LT;
43
+ static readonly opcode = Opcode.LT_8; // FIXME: needed for gas.
44
44
 
45
45
  protected compare(a: MemoryValue, b: MemoryValue): boolean {
46
46
  return a.lt(b);
@@ -49,7 +49,7 @@ export class Lt extends ComparatorInstruction {
49
49
 
50
50
  export class Lte extends ComparatorInstruction {
51
51
  static readonly type: string = 'LTE';
52
- static readonly opcode = Opcode.LTE;
52
+ static readonly opcode = Opcode.LTE_8; // FIXME: needed for gas.
53
53
 
54
54
  protected compare(a: MemoryValue, b: MemoryValue): boolean {
55
55
  return a.lt(b) || a.equals(b);
@@ -7,9 +7,9 @@ import { Instruction } from './instruction.js';
7
7
 
8
8
  export class Jump extends Instruction {
9
9
  static type: string = 'JUMP';
10
- static readonly opcode: Opcode = Opcode.JUMP;
10
+ static readonly opcode: Opcode = Opcode.JUMP_16;
11
11
  // Informs (de)serialization. See Instruction.deserialize.
12
- static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT32];
12
+ static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT16];
13
13
 
14
14
  constructor(private jumpOffset: number) {
15
15
  super();
@@ -26,14 +26,14 @@ export class Jump extends Instruction {
26
26
 
27
27
  export class JumpI extends Instruction {
28
28
  static type: string = 'JUMPI';
29
- static readonly opcode: Opcode = Opcode.JUMPI;
29
+ static readonly opcode: Opcode = Opcode.JUMPI_16;
30
30
 
31
31
  // Instruction wire format with opcode.
32
32
  static readonly wireFormat: OperandType[] = [
33
33
  OperandType.UINT8,
34
34
  OperandType.UINT8,
35
- OperandType.UINT32,
36
- OperandType.UINT32,
35
+ OperandType.UINT16,
36
+ OperandType.UINT16,
37
37
  ];
38
38
 
39
39
  constructor(private indirect: number, private loc: number, private condOffset: number) {
@@ -183,13 +183,19 @@ export class Return extends Instruction {
183
183
 
184
184
  export class Revert extends Instruction {
185
185
  static type: string = 'REVERT';
186
- static readonly opcode: Opcode = Opcode.REVERT;
187
- // Informs (de)serialization. See Instruction.deserialize.
188
- static readonly wireFormat: OperandType[] = [
186
+ static readonly opcode: Opcode = Opcode.REVERT_8;
187
+
188
+ static readonly wireFormat8: OperandType[] = [
189
189
  OperandType.UINT8,
190
190
  OperandType.UINT8,
191
- OperandType.UINT32,
192
- OperandType.UINT32,
191
+ OperandType.UINT8,
192
+ OperandType.UINT8,
193
+ ];
194
+ static readonly wireFormat16: OperandType[] = [
195
+ OperandType.UINT8,
196
+ OperandType.UINT8,
197
+ OperandType.UINT16,
198
+ OperandType.UINT16,
193
199
  ];
194
200
 
195
201
  constructor(private indirect: number, private returnOffset: number, private retSize: number) {
@@ -4,11 +4,11 @@ import type { AvmContext } from '../avm_context.js';
4
4
  import { getBaseGasCost, getDynamicGasCost, mulGas, sumGas } from '../avm_gas.js';
5
5
  import { type MemoryOperations } from '../avm_memory_types.js';
6
6
  import { type BufferCursor } from '../serialization/buffer_cursor.js';
7
- import { Opcode, type OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js';
7
+ import { type Serializable } from '../serialization/bytecode_serialization.js';
8
+ import { Opcode, type OperandType, deserialize, serializeAs } from '../serialization/instruction_serialization.js';
8
9
 
9
10
  type InstructionConstructor = {
10
11
  new (...args: any[]): Instruction;
11
- wireFormat?: OperandType[];
12
12
  };
13
13
 
14
14
  /**
@@ -37,29 +37,51 @@ export abstract class Instruction {
37
37
  return instructionStr;
38
38
  }
39
39
 
40
+ // Default deserialization which uses Class.opcode and Class.wireFormat.
41
+ public static deserialize(
42
+ this: InstructionConstructor & { wireFormat: OperandType[]; as: any },
43
+ buf: BufferCursor | Buffer,
44
+ ): Instruction {
45
+ return this.as(this.wireFormat).deserialize(buf);
46
+ }
47
+
48
+ // Default serialization which uses Class.opcode and Class.wireFormat.
49
+ public serialize(): Buffer {
50
+ const klass = this.constructor as any;
51
+ assert(klass.opcode !== undefined && klass.opcode !== null);
52
+ assert(klass.wireFormat !== undefined && klass.wireFormat !== null);
53
+ return this.as(klass.opcode, klass.wireFormat).serialize();
54
+ }
55
+
40
56
  /**
41
- * Serialize the instruction to a Buffer according to its wire format specified in its subclass.
42
- * If you want to use this, your subclass should specify a {@code static wireFormat: OperandType[]}.
43
- * @param this - The instruction to serialize.
44
- * @returns The serialized instruction.
57
+ * Returns a new instruction instance that can be serialized with the given opcode and wire format.
58
+ * @param opcode The opcode of the instruction.
59
+ * @param wireFormat The wire format of the instruction.
60
+ * @returns The new instruction instance.
45
61
  */
46
- public serialize(this: any): Buffer {
47
- assert(!!this.constructor.wireFormat, 'wireFormat must be defined on the class');
48
- return serialize(this.constructor.wireFormat, this);
62
+ public as(opcode: Opcode, wireFormat: OperandType[]): Instruction & Serializable {
63
+ return Object.defineProperty(this, 'serialize', {
64
+ value: (): Buffer => {
65
+ return serializeAs(wireFormat, opcode, this);
66
+ },
67
+ enumerable: false,
68
+ });
49
69
  }
50
70
 
51
71
  /**
52
- * Deserializes a subclass of Instruction from a Buffer.
53
- * If you want to use this, your subclass should specify a {@code static wireFormat: OperandType[]}.
54
- * @param this Class object to deserialize to.
55
- * @param buf Buffer to read from.
56
- * @returns Constructed instance of Class.
72
+ * Returns a new instruction class that can be deserialized with the given opcode and wire format.
73
+ * @param opcode The opcode of the instruction.
74
+ * @param wireFormat The wire format of the instruction.
75
+ * @returns The new instruction class.
57
76
  */
58
- public static deserialize(this: InstructionConstructor, buf: BufferCursor | Buffer): Instruction {
59
- assert(!!this.wireFormat, 'wireFormat must be defined on the instruction class');
60
- const res = deserialize(buf, this.wireFormat);
61
- const args = res.slice(1); // Remove opcode.
62
- return new this(...args);
77
+ public static as(this: InstructionConstructor, wireFormat: OperandType[]) {
78
+ return Object.assign(this, {
79
+ deserialize: (buf: BufferCursor | Buffer): Instruction => {
80
+ const res = deserialize(buf, wireFormat);
81
+ const args = res.slice(1); // Remove opcode.
82
+ return new this(...args);
83
+ },
84
+ });
63
85
  }
64
86
 
65
87
  /**
@@ -5,31 +5,47 @@ import { Addressing } from './addressing_mode.js';
5
5
  import { Instruction } from './instruction.js';
6
6
 
7
7
  /** Wire format that informs deserialization for instructions with two operands. */
8
- export const TwoOperandWireFormat = [
8
+ export const TwoOperandWireFormat8 = [
9
+ OperandType.UINT8,
10
+ OperandType.UINT8,
9
11
  OperandType.UINT8,
10
12
  OperandType.UINT8,
11
13
  OperandType.UINT8,
12
- OperandType.UINT32,
13
- OperandType.UINT32,
14
+ ];
15
+ export const TwoOperandWireFormat16 = [
16
+ OperandType.UINT8,
17
+ OperandType.UINT8,
18
+ OperandType.UINT8,
19
+ OperandType.UINT16,
20
+ OperandType.UINT16,
14
21
  ];
15
22
 
16
23
  /** Wire format that informs deserialization for instructions with three operands. */
17
- export const ThreeOperandWireFormat = [
24
+ export const ThreeOperandWireFormat8 = [
25
+ OperandType.UINT8,
26
+ OperandType.UINT8,
27
+ OperandType.UINT8,
18
28
  OperandType.UINT8,
19
29
  OperandType.UINT8,
20
30
  OperandType.UINT8,
21
- OperandType.UINT32,
22
- OperandType.UINT32,
23
- OperandType.UINT32,
31
+ ];
32
+ export const ThreeOperandWireFormat16 = [
33
+ OperandType.UINT8,
34
+ OperandType.UINT8,
35
+ OperandType.UINT8,
36
+ OperandType.UINT16,
37
+ OperandType.UINT16,
38
+ OperandType.UINT16,
24
39
  ];
25
40
 
26
41
  /**
27
42
  * Covers (de)serialization for an instruction with:
28
- * indirect, inTag, and two UINT32s.
43
+ * indirect, inTag, and two operands.
29
44
  */
30
45
  export abstract class TwoOperandInstruction extends Instruction {
31
46
  // Informs (de)serialization. See Instruction.deserialize.
32
- static readonly wireFormat: OperandType[] = TwoOperandWireFormat;
47
+ static readonly wireFormat8: OperandType[] = TwoOperandWireFormat8;
48
+ static readonly wireFormat16: OperandType[] = TwoOperandWireFormat16;
33
49
 
34
50
  constructor(
35
51
  protected indirect: number,
@@ -43,11 +59,11 @@ export abstract class TwoOperandInstruction extends Instruction {
43
59
 
44
60
  /**
45
61
  * Covers (de)serialization for an instruction with:
46
- * indirect, inTag, and three UINT32s.
62
+ * indirect, inTag, and three operands.
47
63
  */
48
64
  export abstract class ThreeOperandInstruction extends Instruction {
49
- // Informs (de)serialization. See Instruction.deserialize.
50
- static readonly wireFormat: OperandType[] = ThreeOperandWireFormat;
65
+ static readonly wireFormat8: OperandType[] = ThreeOperandWireFormat8;
66
+ static readonly wireFormat16: OperandType[] = ThreeOperandWireFormat16;
51
67
 
52
68
  constructor(
53
69
  protected indirect: number,