@fluffylabs/anan-as 1.2.0-ef04361 → 1.3.0-1ebcf8f

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 (85) hide show
  1. package/dist/bin/index.js +138 -5
  2. package/dist/bin/src/fuzz.js +2 -2
  3. package/dist/bin/src/test-json.js +2 -6
  4. package/dist/bin/src/trace-parse.js +1 -0
  5. package/dist/bin/src/trace-replay.js +14 -9
  6. package/dist/bin/src/tracer.js +16 -13
  7. package/dist/bin/src/utils.js +2 -2
  8. package/dist/build/compiler-inline.js +1 -1
  9. package/dist/build/compiler.d.ts +17 -13
  10. package/dist/build/compiler.js +13 -21
  11. package/dist/build/compiler.wasm +0 -0
  12. package/dist/build/debug-inline.js +1 -1
  13. package/dist/build/debug-raw-inline.js +1 -1
  14. package/dist/build/debug-raw.d.ts +34 -32
  15. package/dist/build/debug-raw.js +62 -69
  16. package/dist/build/debug-raw.wasm +0 -0
  17. package/dist/build/debug.d.ts +34 -32
  18. package/dist/build/debug.js +63 -70
  19. package/dist/build/debug.wasm +0 -0
  20. package/dist/build/js/assembly/api-debugger.d.ts +4 -4
  21. package/dist/build/js/assembly/api-debugger.js +6 -6
  22. package/dist/build/js/assembly/api-internal.d.ts +1 -1
  23. package/dist/build/js/assembly/api-internal.js +2 -3
  24. package/dist/build/js/assembly/api-types.d.ts +4 -4
  25. package/dist/build/js/assembly/api-types.js +3 -4
  26. package/dist/build/js/assembly/api-utils.d.ts +14 -6
  27. package/dist/build/js/assembly/api-utils.js +28 -13
  28. package/dist/build/js/assembly/arguments.d.ts +4 -4
  29. package/dist/build/js/assembly/arguments.js +10 -10
  30. package/dist/build/js/assembly/gas.d.ts +8 -13
  31. package/dist/build/js/assembly/gas.js +17 -7
  32. package/dist/build/js/assembly/instructions/bit.js +22 -22
  33. package/dist/build/js/assembly/instructions/branch.js +56 -56
  34. package/dist/build/js/assembly/instructions/jump.js +10 -10
  35. package/dist/build/js/assembly/instructions/load.js +41 -41
  36. package/dist/build/js/assembly/instructions/logic.js +20 -20
  37. package/dist/build/js/assembly/instructions/math.js +105 -105
  38. package/dist/build/js/assembly/instructions/misc.js +10 -10
  39. package/dist/build/js/assembly/instructions/mov.js +16 -16
  40. package/dist/build/js/assembly/instructions/outcome.d.ts +7 -7
  41. package/dist/build/js/assembly/instructions/outcome.js +63 -38
  42. package/dist/build/js/assembly/instructions/rot.js +18 -18
  43. package/dist/build/js/assembly/instructions/set.js +18 -18
  44. package/dist/build/js/assembly/instructions/shift.js +59 -59
  45. package/dist/build/js/assembly/instructions/store.js +29 -29
  46. package/dist/build/js/assembly/instructions/utils.d.ts +6 -4
  47. package/dist/build/js/assembly/instructions/utils.js +32 -16
  48. package/dist/build/js/assembly/instructions.d.ts +2 -3
  49. package/dist/build/js/assembly/instructions.js +4 -4
  50. package/dist/build/js/assembly/interpreter.d.ts +0 -1
  51. package/dist/build/js/assembly/interpreter.js +30 -38
  52. package/dist/build/js/assembly/math.d.ts +6 -8
  53. package/dist/build/js/assembly/math.js +21 -13
  54. package/dist/build/js/assembly/memory-page.d.ts +2 -4
  55. package/dist/build/js/assembly/memory-page.js +13 -7
  56. package/dist/build/js/assembly/memory.d.ts +1 -0
  57. package/dist/build/js/assembly/memory.js +119 -23
  58. package/dist/build/js/assembly/portable.js +1 -0
  59. package/dist/build/js/assembly/program-build.js +4 -4
  60. package/dist/build/js/assembly/program.d.ts +15 -8
  61. package/dist/build/js/assembly/program.js +95 -39
  62. package/dist/build/js/assembly/spi.d.ts +1 -1
  63. package/dist/build/js/assembly/spi.js +2 -2
  64. package/dist/build/js/portable/bootstrap.js +1 -0
  65. package/dist/build/js/portable-bundle.js +829 -641
  66. package/dist/build/release-inline.js +1 -1
  67. package/dist/build/release-mini-inline.js +1 -1
  68. package/dist/build/release-mini.d.ts +34 -32
  69. package/dist/build/release-mini.js +63 -70
  70. package/dist/build/release-mini.wasm +0 -0
  71. package/dist/build/release-stub-inline.js +1 -1
  72. package/dist/build/release-stub.d.ts +34 -32
  73. package/dist/build/release-stub.js +63 -70
  74. package/dist/build/release-stub.wasm +0 -0
  75. package/dist/build/release.d.ts +34 -32
  76. package/dist/build/release.js +63 -70
  77. package/dist/build/release.wasm +0 -0
  78. package/dist/build/test-inline.js +1 -1
  79. package/dist/build/test.wasm +0 -0
  80. package/dist/test/test-gas-cost.js +2 -3
  81. package/dist/test/test-trace-format.js +166 -0
  82. package/dist/test/test-w3f-common.js +1 -2
  83. package/package.json +14 -10
  84. package/dist/build/js/assembly/gas-costs.d.ts +0 -6
  85. package/dist/build/js/assembly/gas-costs.js +0 -39
@@ -1,7 +1,7 @@
1
1
  import { Args, Arguments, DECODERS, REQUIRED_BYTES } from "./arguments";
2
2
  import { Decoder } from "./codec";
3
3
  import { INSTRUCTIONS, MISSING_INSTRUCTION } from "./instructions";
4
- import { reg, u32SignExtend } from "./instructions/utils";
4
+ import { Inst } from "./instructions/utils";
5
5
  import { portable } from "./portable";
6
6
  const MAX_SKIP = 24;
7
7
  export class CodeAndMetadata {
@@ -24,16 +24,16 @@ export function liftBytes(data) {
24
24
  p.set(data, 0);
25
25
  return p;
26
26
  }
27
- /** Convert `Uint8Array` to `u8` */
27
+ /** Convert `Uint8Array` to `Code` (StaticArray<u8>) */
28
28
  export function lowerBytes(data) {
29
- const r = new Array(data.length);
29
+ const r = new StaticArray(data.length);
30
30
  for (let i = 0; i < data.length; i++) {
31
31
  r[i] = data[i];
32
32
  }
33
33
  return r;
34
34
  }
35
35
  /** https://graypaper.fluffylabs.dev/#/cc517d7/234f01234f01?v=0.6.5 */
36
- export function deblob(program) {
36
+ export function deblob(program, useBlockGas) {
37
37
  const decoder = new Decoder(program);
38
38
  // number of items in the jump table
39
39
  const jumpTableLength = decoder.varU32();
@@ -50,7 +50,8 @@ export function deblob(program) {
50
50
  const mask = new Mask(rawMask, codeLength);
51
51
  const jumpTable = new JumpTable(jumpTableItemLength, rawJumpTable);
52
52
  const basicBlocks = new BasicBlocks(rawCode, mask);
53
- return new Program(rawCode, mask, jumpTable, basicBlocks);
53
+ const gasCosts = new GasCosts(rawCode, mask, basicBlocks, useBlockGas);
54
+ return new Program(rawCode, mask, jumpTable, basicBlocks, gasCosts);
54
55
  }
55
56
  /**
56
57
  * https://graypaper.fluffylabs.dev/#/cc517d7/236e01236e01?v=0.6.5
@@ -100,6 +101,54 @@ export class Mask {
100
101
  return `${v}]`;
101
102
  }
102
103
  }
104
+ export class GasCosts {
105
+ constructor(code, mask, blocks, useBlockGasCost) {
106
+ const len = code.length;
107
+ const costs = new StaticArray(len);
108
+ for (let n = 0; n < len; n += 1) {
109
+ const isInstructionInMask = mask.isInstruction(n);
110
+ if (!isInstructionInMask) {
111
+ costs[n] = code[n];
112
+ continue;
113
+ }
114
+ const skipArgs = mask.skipBytesToNextInstruction(n);
115
+ const iData = code[n] >= INSTRUCTIONS.length ? MISSING_INSTRUCTION : INSTRUCTIONS[code[n]];
116
+ costs[n] = code[n] | (iData.gas << 8);
117
+ n += skipArgs;
118
+ }
119
+ // sum up costs per block
120
+ if (useBlockGasCost) {
121
+ let previousStart = 0;
122
+ let previousSum = 0;
123
+ for (let n = 0; n < len; n += 1) {
124
+ const currentGas = costs[n] >> 8;
125
+ costs[n] = code[n]; // reset to just opcode (gas=0)
126
+ if (blocks.isStart(n)) {
127
+ costs[previousStart] = code[previousStart] | (previousSum << 8);
128
+ previousSum = currentGas;
129
+ previousStart = n;
130
+ }
131
+ else {
132
+ previousSum += currentGas;
133
+ }
134
+ n += mask.skipBytesToNextInstruction(n);
135
+ }
136
+ // final assignment
137
+ costs[previousStart] = code[previousStart] | (previousSum << 8);
138
+ }
139
+ this.codeAndGas = costs;
140
+ }
141
+ toString() {
142
+ let v = "GasCosts[";
143
+ for (let i = 0; i < this.codeAndGas.length; i += 1) {
144
+ const gas = this.codeAndGas[i] >> 8;
145
+ if (gas !== 0) {
146
+ v += `${i} -> ${gas}, `;
147
+ }
148
+ }
149
+ return `${v}]`;
150
+ }
151
+ }
103
152
  export var BasicBlock;
104
153
  (function (BasicBlock) {
105
154
  BasicBlock[BasicBlock["NONE"] = 0] = "NONE";
@@ -185,26 +234,33 @@ export class JumpTable {
185
234
  }
186
235
  }
187
236
  export class Program {
188
- constructor(code, mask, jumpTable, basicBlocks) {
237
+ constructor(code, mask, jumpTable, basicBlocks, gasCosts) {
189
238
  this.code = code;
190
239
  this.mask = mask;
191
240
  this.jumpTable = jumpTable;
192
241
  this.basicBlocks = basicBlocks;
242
+ this.gasCosts = gasCosts;
193
243
  }
194
244
  toString() {
195
- return `Program { code: ${this.code}, mask: ${this.mask}, jumpTable: ${this.jumpTable}, basicBlocks: ${this.basicBlocks} }`;
245
+ return `Program { code: ${this.code}, mask: ${this.mask}, jumpTable: ${this.jumpTable}, basicBlocks: ${this.basicBlocks}, gasCosts: ${this.gasCosts} }`;
196
246
  }
197
247
  }
248
+ // Pre-allocated buffer for the rare case when code is shorter than needed.
249
+ // Max REQUIRED_BYTES is 9 (OneRegOneExtImm). We allocate 16 for safety.
250
+ const EXTENDED_BUF = new StaticArray(16);
198
251
  export function decodeArguments(args, kind, code, offset, lim) {
199
252
  if (code.length < offset + REQUIRED_BYTES[kind]) {
200
253
  // in case we have less data than needed we extend the data with zeros.
201
- const extended = new Array(REQUIRED_BYTES[kind]);
254
+ const reqBytes = unchecked(REQUIRED_BYTES[kind]);
255
+ for (let i = 0; i < reqBytes; i++) {
256
+ EXTENDED_BUF[i] = 0;
257
+ }
202
258
  for (let i = offset; i < code.length; i++) {
203
- extended[i - offset] = code[i];
259
+ EXTENDED_BUF[i - offset] = unchecked(code[i]);
204
260
  }
205
- return DECODERS[kind](args, extended, 0, lim);
261
+ return unchecked(DECODERS[kind])(args, EXTENDED_BUF, 0, lim);
206
262
  }
207
- return DECODERS[kind](args, code, offset, offset + lim);
263
+ return unchecked(DECODERS[kind])(args, code, offset, offset + lim);
208
264
  }
209
265
  class ResolvedArguments {
210
266
  constructor() {
@@ -226,57 +282,57 @@ export function resolveArguments(argsRes, kind, code, offset, lim, registers) {
226
282
  case Arguments.Zero:
227
283
  return resolved;
228
284
  case Arguments.OneImm:
229
- resolved.a = u32SignExtend(args.a);
285
+ resolved.a = Inst.u32SignExtend(args.a);
230
286
  return resolved;
231
287
  case Arguments.TwoImm:
232
- resolved.a = u32SignExtend(args.a);
233
- resolved.b = u32SignExtend(args.b);
288
+ resolved.a = Inst.u32SignExtend(args.a);
289
+ resolved.b = Inst.u32SignExtend(args.b);
234
290
  return resolved;
235
291
  case Arguments.OneOff:
236
- resolved.a = u32SignExtend(args.a);
292
+ resolved.a = Inst.u32SignExtend(args.a);
237
293
  return resolved;
238
294
  case Arguments.OneRegOneImm:
239
- resolved.a = registers[reg(u64(args.a))];
240
- resolved.b = u32SignExtend(args.b);
295
+ resolved.a = registers[Inst.reg(u64(args.a))];
296
+ resolved.b = Inst.u32SignExtend(args.b);
241
297
  return resolved;
242
298
  case Arguments.OneRegOneExtImm:
243
- resolved.a = registers[reg(u64(args.a))];
299
+ resolved.a = registers[Inst.reg(u64(args.a))];
244
300
  resolved.b = portable.u64_add(u64(args.a) << u64(32), u64(args.b));
245
301
  return resolved;
246
302
  case Arguments.OneRegTwoImm:
247
- resolved.a = registers[reg(u64(args.a))];
248
- resolved.b = u32SignExtend(args.b);
249
- resolved.c = u32SignExtend(args.c);
303
+ resolved.a = registers[Inst.reg(u64(args.a))];
304
+ resolved.b = Inst.u32SignExtend(args.b);
305
+ resolved.c = Inst.u32SignExtend(args.c);
250
306
  return resolved;
251
307
  case Arguments.OneRegOneImmOneOff:
252
- resolved.a = registers[reg(u64(args.a))];
253
- resolved.b = u32SignExtend(args.b);
254
- resolved.c = u32SignExtend(args.c);
308
+ resolved.a = registers[Inst.reg(u64(args.a))];
309
+ resolved.b = Inst.u32SignExtend(args.b);
310
+ resolved.c = Inst.u32SignExtend(args.c);
255
311
  return resolved;
256
312
  case Arguments.TwoReg:
257
- resolved.a = registers[reg(u64(args.a))];
258
- resolved.b = registers[reg(u64(args.b))];
313
+ resolved.a = registers[Inst.reg(u64(args.a))];
314
+ resolved.b = registers[Inst.reg(u64(args.b))];
259
315
  return resolved;
260
316
  case Arguments.TwoRegOneImm:
261
- resolved.a = registers[reg(u64(args.a))];
262
- resolved.b = registers[reg(u64(args.b))];
263
- resolved.c = u32SignExtend(args.c);
317
+ resolved.a = registers[Inst.reg(u64(args.a))];
318
+ resolved.b = registers[Inst.reg(u64(args.b))];
319
+ resolved.c = Inst.u32SignExtend(args.c);
264
320
  return resolved;
265
321
  case Arguments.TwoRegOneOff:
266
- resolved.a = registers[reg(u64(args.a))];
267
- resolved.b = registers[reg(u64(args.b))];
268
- resolved.c = u32SignExtend(args.c);
322
+ resolved.a = registers[Inst.reg(u64(args.a))];
323
+ resolved.b = registers[Inst.reg(u64(args.b))];
324
+ resolved.c = Inst.u32SignExtend(args.c);
269
325
  return resolved;
270
326
  case Arguments.TwoRegTwoImm:
271
- resolved.a = registers[reg(u64(args.a))];
272
- resolved.b = registers[reg(u64(args.b))];
273
- resolved.c = u32SignExtend(args.c);
274
- resolved.d = u32SignExtend(args.d);
327
+ resolved.a = registers[Inst.reg(u64(args.a))];
328
+ resolved.b = registers[Inst.reg(u64(args.b))];
329
+ resolved.c = Inst.u32SignExtend(args.c);
330
+ resolved.d = Inst.u32SignExtend(args.d);
275
331
  return resolved;
276
332
  case Arguments.ThreeReg:
277
- resolved.a = registers[reg(u64(args.a))];
278
- resolved.b = registers[reg(u64(args.b))];
279
- resolved.c = registers[reg(u64(args.c))];
333
+ resolved.a = registers[Inst.reg(u64(args.a))];
334
+ resolved.b = registers[Inst.reg(u64(args.b))];
335
+ resolved.c = registers[Inst.reg(u64(args.c))];
280
336
  return resolved;
281
337
  default:
282
338
  throw new Error(`Unhandled arguments kind: ${kind}`);
@@ -8,7 +8,7 @@ export declare const ARGS_SEGMENT_START: u32;
8
8
  /** https://graypaper.fluffylabs.dev/#/ab2cdbd/2d33022d3502?v=0.7.2 */
9
9
  export declare const STACK_SEGMENT_END: u32;
10
10
  /** https://graypaper.fluffylabs.dev/#/ab2cdbd/2da3002da300?v=0.7.2 */
11
- export declare function decodeSpi(data: Uint8Array, args: Uint8Array, preallocateMemoryPages?: u32): StandardProgram;
11
+ export declare function decodeSpi(data: Uint8Array, args: Uint8Array, preallocateMemoryPages?: u32, useBlockGas?: boolean): StandardProgram;
12
12
  /**
13
13
  * SPI Program with memory and registers.
14
14
  *
@@ -10,7 +10,7 @@ export const ARGS_SEGMENT_START = 2 ** 32 - SEGMENT_SIZE - MAX_ARGS_LEN;
10
10
  /** https://graypaper.fluffylabs.dev/#/ab2cdbd/2d33022d3502?v=0.7.2 */
11
11
  export const STACK_SEGMENT_END = ARGS_SEGMENT_START - SEGMENT_SIZE;
12
12
  /** https://graypaper.fluffylabs.dev/#/ab2cdbd/2da3002da300?v=0.7.2 */
13
- export function decodeSpi(data, args, preallocateMemoryPages = 0) {
13
+ export function decodeSpi(data, args, preallocateMemoryPages = 0, useBlockGas = false) {
14
14
  const argsLength = args.length;
15
15
  if (argsLength > MAX_ARGS_LEN) {
16
16
  throw new Error(`Arguments length is too big. Got: ${argsLength}, max: ${MAX_ARGS_LEN}`);
@@ -25,7 +25,7 @@ export function decodeSpi(data, args, preallocateMemoryPages = 0) {
25
25
  const codeLength = decoder.u32();
26
26
  const code = decoder.bytes(codeLength);
27
27
  decoder.finish();
28
- const program = deblob(code);
28
+ const program = deblob(code, useBlockGas);
29
29
  // building memory
30
30
  const builder = new MemoryBuilder(preallocateMemoryPages);
31
31
  const heapStart = 2 * SEGMENT_SIZE + alignToSegmentSize(roLength);
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  // Portable bootstrap for globals that must exist before assembly/portable executes.
2
3
  const g = globalThis;
3
4
  if (g.ASC_TARGET === undefined) {