@fluffylabs/anan-as 1.2.0 → 1.3.0-5cbd3aa

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 (110) 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 +50 -112
  15. package/dist/build/debug-raw.js +78 -139
  16. package/dist/build/debug-raw.wasm +0 -0
  17. package/dist/build/debug.d.ts +50 -112
  18. package/dist/build/debug.js +81 -147
  19. package/dist/build/debug.wasm +0 -0
  20. package/dist/build/js/assembly/api-debugger.d.ts +55 -0
  21. package/dist/build/js/assembly/api-debugger.js +245 -0
  22. package/dist/build/js/assembly/api-internal.d.ts +13 -0
  23. package/dist/build/js/assembly/api-internal.js +191 -0
  24. package/dist/build/js/assembly/api-types.d.ts +45 -0
  25. package/dist/build/js/assembly/api-types.js +52 -0
  26. package/dist/build/js/assembly/api-utils.d.ts +79 -0
  27. package/dist/build/js/assembly/api-utils.js +221 -0
  28. package/dist/build/js/assembly/arguments.d.ts +44 -0
  29. package/dist/build/js/assembly/arguments.js +164 -0
  30. package/dist/build/js/assembly/codec.d.ts +24 -0
  31. package/dist/build/js/assembly/codec.js +139 -0
  32. package/dist/build/js/assembly/gas.d.ts +11 -0
  33. package/dist/build/js/assembly/gas.js +33 -0
  34. package/dist/build/js/assembly/index-shared.d.ts +4 -0
  35. package/dist/build/js/assembly/index-shared.js +4 -0
  36. package/dist/build/js/assembly/instructions/bit.d.ts +11 -0
  37. package/dist/build/js/assembly/instructions/bit.js +53 -0
  38. package/dist/build/js/assembly/instructions/branch.d.ts +17 -0
  39. package/dist/build/js/assembly/instructions/branch.js +120 -0
  40. package/dist/build/js/assembly/instructions/jump.d.ts +5 -0
  41. package/dist/build/js/assembly/instructions/jump.js +21 -0
  42. package/dist/build/js/assembly/instructions/load.d.ts +17 -0
  43. package/dist/build/js/assembly/instructions/load.js +134 -0
  44. package/dist/build/js/assembly/instructions/logic.d.ts +10 -0
  45. package/dist/build/js/assembly/instructions/logic.js +47 -0
  46. package/dist/build/js/assembly/instructions/math.d.ts +28 -0
  47. package/dist/build/js/assembly/instructions/math.js +225 -0
  48. package/dist/build/js/assembly/instructions/misc.d.ts +6 -0
  49. package/dist/build/js/assembly/instructions/misc.js +22 -0
  50. package/dist/build/js/assembly/instructions/mov.d.ts +6 -0
  51. package/dist/build/js/assembly/instructions/mov.js +35 -0
  52. package/dist/build/js/assembly/instructions/outcome.d.ts +30 -0
  53. package/dist/build/js/assembly/instructions/outcome.js +88 -0
  54. package/dist/build/js/assembly/instructions/rot.d.ts +15 -0
  55. package/dist/build/js/assembly/instructions/rot.js +66 -0
  56. package/dist/build/js/assembly/instructions/set.d.ts +7 -0
  57. package/dist/build/js/assembly/instructions/set.js +36 -0
  58. package/dist/build/js/assembly/instructions/shift.d.ts +19 -0
  59. package/dist/build/js/assembly/instructions/shift.js +121 -0
  60. package/dist/build/js/assembly/instructions/store.d.ts +17 -0
  61. package/dist/build/js/assembly/instructions/store.js +101 -0
  62. package/dist/build/js/assembly/instructions/utils.d.ts +25 -0
  63. package/dist/build/js/assembly/instructions/utils.js +91 -0
  64. package/dist/build/js/assembly/instructions-exe.d.ts +2 -0
  65. package/dist/build/js/assembly/instructions-exe.js +245 -0
  66. package/dist/build/js/assembly/instructions.d.ts +10 -0
  67. package/dist/build/js/assembly/instructions.js +252 -0
  68. package/dist/build/js/assembly/interpreter.d.ts +28 -0
  69. package/dist/build/js/assembly/interpreter.js +221 -0
  70. package/dist/build/js/assembly/math.d.ts +6 -0
  71. package/dist/build/js/assembly/math.js +22 -0
  72. package/dist/build/js/assembly/memory-page.d.ts +36 -0
  73. package/dist/build/js/assembly/memory-page.js +74 -0
  74. package/dist/build/js/assembly/memory.d.ts +83 -0
  75. package/dist/build/js/assembly/memory.js +482 -0
  76. package/dist/build/js/assembly/portable.d.ts +24 -0
  77. package/dist/build/js/assembly/portable.js +363 -0
  78. package/dist/build/js/assembly/program-build.d.ts +2 -0
  79. package/dist/build/js/assembly/program-build.js +104 -0
  80. package/dist/build/js/assembly/program.d.ts +85 -0
  81. package/dist/build/js/assembly/program.js +340 -0
  82. package/dist/build/js/assembly/registers.d.ts +6 -0
  83. package/dist/build/js/assembly/registers.js +9 -0
  84. package/dist/build/js/assembly/spi.d.ts +92 -0
  85. package/dist/build/js/assembly/spi.js +152 -0
  86. package/dist/build/js/portable/bootstrap.d.ts +1 -0
  87. package/dist/build/js/portable/bootstrap.js +6 -0
  88. package/dist/build/js/portable/index.d.ts +4 -0
  89. package/dist/build/js/portable/index.js +6 -0
  90. package/dist/build/js/portable-bundle.js +4497 -0
  91. package/dist/build/release-inline.js +1 -1
  92. package/dist/build/release-mini-inline.js +1 -1
  93. package/dist/build/release-mini.d.ts +50 -112
  94. package/dist/build/release-mini.js +81 -147
  95. package/dist/build/release-mini.wasm +0 -0
  96. package/dist/build/release-stub-inline.js +1 -1
  97. package/dist/build/release-stub.d.ts +50 -112
  98. package/dist/build/release-stub.js +81 -147
  99. package/dist/build/release-stub.wasm +0 -0
  100. package/dist/build/release.d.ts +50 -112
  101. package/dist/build/release.js +81 -147
  102. package/dist/build/release.wasm +0 -0
  103. package/dist/build/test-inline.js +1 -1
  104. package/dist/build/test.wasm +0 -0
  105. package/dist/test/test-gas-cost.js +2 -3
  106. package/dist/test/test-trace-format.js +166 -0
  107. package/dist/test/test-w3f-common.js +125 -0
  108. package/dist/test/test-w3f-portable.js +5 -0
  109. package/dist/test/test-w3f.js +3 -120
  110. package/package.json +22 -11
Binary file
@@ -2,7 +2,7 @@
2
2
  import "json-bigint-patch";
3
3
  import * as assert from "node:assert";
4
4
  import { ERR, OK, read, run } from "../bin/src/test-json.js";
5
- import { disassemble, getGasCosts, HasMetadata, InputKind } from "../build/release.js";
5
+ import { disassemble, getBlockGasCosts, HasMetadata, InputKind } from "../build/release.js";
6
6
  // Run the CLI application
7
7
  main();
8
8
  // Main function
@@ -10,7 +10,6 @@ function main() {
10
10
  const options = {
11
11
  isDebug: false,
12
12
  isSilent: false,
13
- useSbrkGas: false,
14
13
  };
15
14
  run(processGasCost, options);
16
15
  }
@@ -29,7 +28,7 @@ function processGasCost(data, options, filePath) {
29
28
  console.info(assembly);
30
29
  console.info("\n^^^^^^^^^^^\n");
31
30
  }
32
- const result = asMap(getGasCosts(input.program, InputKind.Generic, HasMetadata.No));
31
+ const result = asMap(getBlockGasCosts(input.program, InputKind.Generic, HasMetadata.No));
33
32
  // silent mode - just put our vals into expected (comparison done externally)
34
33
  if (options.isSilent) {
35
34
  data.block_gas_costs = result;
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+ import * as assert from "node:assert";
3
+ import { parseTrace } from "../bin/src/trace-parse.js";
4
+ // Test: round-trip parse of a spec-compliant trace
5
+ {
6
+ const input = [
7
+ "program 0x0102aabbccddeeff",
8
+ "memwrite 0x00001000 len=8 <- 0x0000000000000001",
9
+ "start pc=0 gas=10000 r07=0x10 r09=0x10000",
10
+ "",
11
+ "ecalli=10 pc=42 gas=9980 r01=0x1 r03=0x1000",
12
+ "memread 0x00001000 len=4 -> 0x01020304",
13
+ "memread 0x00001020 len=8 -> 0x0000000000000040",
14
+ "memwrite 0x00002000 len=2 <- 0xffee",
15
+ "setreg r00 <- 0x100",
16
+ "setreg r02 <- 0x4",
17
+ "setgas <- 9950",
18
+ "",
19
+ "HALT pc=42 gas=9920 r00=0x100 r02=0x4",
20
+ ].join("\n");
21
+ const trace = parseTrace(input);
22
+ // Program
23
+ assert.deepStrictEqual(Array.from(trace.program), [0x01, 0x02, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff], "program bytes");
24
+ // Initial memwrite
25
+ assert.strictEqual(trace.initialMemWrites.length, 1, "one initial memwrite");
26
+ assert.strictEqual(trace.initialMemWrites[0].address, 0x00001000, "memwrite address");
27
+ assert.strictEqual(trace.initialMemWrites[0].data.length, 8, "memwrite data length");
28
+ // Start
29
+ assert.strictEqual(trace.start.pc, 0, "start pc");
30
+ assert.strictEqual(trace.start.gas, 10000n, "start gas");
31
+ assert.strictEqual(trace.start.registers.get(7), 0x10n, "start r07");
32
+ assert.strictEqual(trace.start.registers.get(9), 0x10000n, "start r09");
33
+ assert.strictEqual(trace.start.registers.has(0), false, "start r00 omitted (zero)");
34
+ // Ecalli
35
+ assert.strictEqual(trace.ecalliEntries.length, 1, "one ecalli");
36
+ const ecalli = trace.ecalliEntries[0];
37
+ assert.strictEqual(ecalli.index, 10, "ecalli index");
38
+ assert.strictEqual(ecalli.pc, 42, "ecalli pc");
39
+ assert.strictEqual(ecalli.gas, 9980n, "ecalli gas");
40
+ assert.strictEqual(ecalli.registers.get(1), 0x1n, "ecalli r01");
41
+ assert.strictEqual(ecalli.registers.get(3), 0x1000n, "ecalli r03");
42
+ // Memreads
43
+ assert.strictEqual(ecalli.memReads.length, 2, "two memreads");
44
+ assert.strictEqual(ecalli.memReads[0].address, 0x00001000, "memread 0 address");
45
+ assert.strictEqual(ecalli.memReads[0].data.length, 4, "memread 0 length");
46
+ assert.strictEqual(ecalli.memReads[1].address, 0x00001020, "memread 1 address");
47
+ // Memwrites
48
+ assert.strictEqual(ecalli.memWrites.length, 1, "one ecalli memwrite");
49
+ assert.strictEqual(ecalli.memWrites[0].address, 0x00002000, "ecalli memwrite address");
50
+ // Setregs
51
+ assert.strictEqual(ecalli.setRegs.length, 2, "two setregs");
52
+ assert.strictEqual(ecalli.setRegs[0].index, 0, "setreg 0 index");
53
+ assert.strictEqual(ecalli.setRegs[0].value, 0x100n, "setreg 0 value");
54
+ assert.strictEqual(ecalli.setRegs[1].index, 2, "setreg 1 index");
55
+ assert.strictEqual(ecalli.setRegs[1].value, 0x4n, "setreg 1 value");
56
+ // Setgas
57
+ assert.strictEqual(ecalli.setGas, 9950n, "setgas");
58
+ // Termination
59
+ assert.strictEqual(trace.termination.type, "HALT", "termination type");
60
+ assert.strictEqual(trace.termination.pc, 42, "termination pc");
61
+ assert.strictEqual(trace.termination.gas, 9920n, "termination gas");
62
+ assert.strictEqual(trace.termination.registers.get(0), 0x100n, "termination r00");
63
+ assert.strictEqual(trace.termination.registers.get(2), 0x4n, "termination r02");
64
+ console.log("PASS: spec example round-trip");
65
+ }
66
+ // Test: PANIC=0 (argument must always be present)
67
+ {
68
+ const input = ["program 0x00", "start pc=0 gas=100", "PANIC=0 pc=5 gas=50 r00=0x1"].join("\n");
69
+ const trace = parseTrace(input);
70
+ assert.strictEqual(trace.termination.type, "PANIC", "panic type");
71
+ assert.strictEqual(trace.termination.panicArg, 0, "panic arg is 0");
72
+ assert.strictEqual(trace.termination.pc, 5, "panic pc");
73
+ assert.strictEqual(trace.termination.gas, 50n, "panic gas");
74
+ console.log("PASS: PANIC=0");
75
+ }
76
+ // Test: PANIC with non-zero argument
77
+ {
78
+ const input = ["program 0x00", "start pc=0 gas=100", "PANIC=42 pc=10 gas=0"].join("\n");
79
+ const trace = parseTrace(input);
80
+ assert.strictEqual(trace.termination.panicArg, 42, "panic arg 42");
81
+ assert.strictEqual(trace.termination.registers.size, 0, "no registers");
82
+ console.log("PASS: PANIC=42");
83
+ }
84
+ // Test: OOG termination
85
+ {
86
+ const input = ["program 0x00", "start pc=0 gas=100", "OOG pc=99 gas=0"].join("\n");
87
+ const trace = parseTrace(input);
88
+ assert.strictEqual(trace.termination.type, "OOG", "OOG type");
89
+ assert.strictEqual(trace.termination.gas, 0n, "OOG gas is 0");
90
+ console.log("PASS: OOG");
91
+ }
92
+ // Test: lines with log prefixes are handled (extractPayload)
93
+ {
94
+ const input = [
95
+ "TRACE [ecalli] program 0xaa",
96
+ "TRACE [ecalli] start pc=0 gas=500 r00=0x1",
97
+ "TRACE [ecalli] HALT pc=10 gas=400",
98
+ ].join("\n");
99
+ const trace = parseTrace(input);
100
+ assert.deepStrictEqual(Array.from(trace.program), [0xaa], "prefixed program");
101
+ assert.strictEqual(trace.start.registers.get(0), 0x1n, "prefixed start r00");
102
+ assert.strictEqual(trace.termination.type, "HALT", "prefixed halt");
103
+ console.log("PASS: log-prefixed lines");
104
+ }
105
+ // Test: comment lines are ignored
106
+ {
107
+ const input = [
108
+ "comment implementation typeberry 0.8.3",
109
+ "comment chain-id fluffy-testnet",
110
+ "program 0xbb",
111
+ "comment accumulate",
112
+ "start pc=0 gas=100",
113
+ "HALT pc=5 gas=90",
114
+ ].join("\n");
115
+ const trace = parseTrace(input);
116
+ assert.deepStrictEqual(Array.from(trace.program), [0xbb], "comment lines ignored");
117
+ console.log("PASS: comment lines ignored");
118
+ }
119
+ // Test: zero-padded register indices in register dump
120
+ {
121
+ const input = ["program 0x00", "start pc=0 gas=100 r00=0xff r12=0x1", "HALT pc=5 gas=90 r00=0xff r12=0x1"].join("\n");
122
+ const trace = parseTrace(input);
123
+ assert.strictEqual(trace.start.registers.get(0), 0xffn, "r00 parsed");
124
+ assert.strictEqual(trace.start.registers.get(12), 0x1n, "r12 parsed");
125
+ console.log("PASS: zero-padded register indices");
126
+ }
127
+ // Test: empty register dump (all zeros)
128
+ {
129
+ const input = ["program 0x00", "start pc=0 gas=100", "HALT pc=5 gas=90"].join("\n");
130
+ const trace = parseTrace(input);
131
+ assert.strictEqual(trace.start.registers.size, 0, "empty register dump");
132
+ assert.strictEqual(trace.termination.registers.size, 0, "empty termination registers");
133
+ console.log("PASS: empty register dump");
134
+ }
135
+ // Test: multiple ecalli entries
136
+ {
137
+ const input = [
138
+ "program 0x00",
139
+ "start pc=0 gas=10000",
140
+ "ecalli=1 pc=10 gas=9000 r00=0x1",
141
+ "setreg r00 <- 0x2",
142
+ "ecalli=2 pc=20 gas=8000 r00=0x2",
143
+ "memwrite 0x00001000 len=1 <- 0xff",
144
+ "setgas <- 7900",
145
+ "HALT pc=30 gas=7800",
146
+ ].join("\n");
147
+ const trace = parseTrace(input);
148
+ assert.strictEqual(trace.ecalliEntries.length, 2, "two ecalli entries");
149
+ assert.strictEqual(trace.ecalliEntries[0].index, 1, "first ecalli index");
150
+ assert.strictEqual(trace.ecalliEntries[0].setRegs.length, 1, "first ecalli setregs");
151
+ assert.strictEqual(trace.ecalliEntries[0].setGas, undefined, "first ecalli no setgas");
152
+ assert.strictEqual(trace.ecalliEntries[1].index, 2, "second ecalli index");
153
+ assert.strictEqual(trace.ecalliEntries[1].memWrites.length, 1, "second ecalli memwrites");
154
+ assert.strictEqual(trace.ecalliEntries[1].setGas, 7900n, "second ecalli setgas");
155
+ console.log("PASS: multiple ecalli entries");
156
+ }
157
+ // Test: missing program throws
158
+ assert.throws(() => parseTrace("start pc=0 gas=100\nHALT pc=5 gas=90"), /Missing program/, "missing program");
159
+ console.log("PASS: missing program throws");
160
+ // Test: missing start throws
161
+ assert.throws(() => parseTrace("program 0x00\nHALT pc=5 gas=90"), /Missing start/, "missing start");
162
+ console.log("PASS: missing start throws");
163
+ // Test: missing termination throws
164
+ assert.throws(() => parseTrace("program 0x00\nstart pc=0 gas=100"), /Missing termination/, "missing termination");
165
+ console.log("PASS: missing termination throws");
166
+ console.log("\nAll trace format tests passed.");
@@ -0,0 +1,125 @@
1
+ import "json-bigint-patch";
2
+ import * as assert from "node:assert";
3
+ import { ERR, OK, read, run } from "../bin/src/test-json.js";
4
+ const ignored = [
5
+ "inst_load_u8_nok",
6
+ "inst_store_imm_indirect_u16_with_offset_nok",
7
+ "inst_store_imm_indirect_u32_with_offset_nok",
8
+ "inst_store_imm_indirect_u64_with_offset_nok",
9
+ "inst_store_imm_indirect_u8_with_offset_nok",
10
+ "inst_store_imm_u8_trap_inaccessible",
11
+ "inst_store_imm_u8_trap_read_only",
12
+ "inst_store_indirect_u16_with_offset_nok",
13
+ "inst_store_indirect_u32_with_offset_nok",
14
+ "inst_store_indirect_u64_with_offset_nok",
15
+ "inst_store_indirect_u8_with_offset_nok",
16
+ "inst_store_u8_trap_inaccessible",
17
+ "inst_store_u8_trap_read_only",
18
+ ];
19
+ export function runW3fTests(pvm) {
20
+ const options = {
21
+ isDebug: false,
22
+ isSilent: false,
23
+ };
24
+ run((data, opts, filePath) => processW3f(pvm, data, opts, filePath), options);
25
+ }
26
+ function processW3f(pvm, data, options, _filePath) {
27
+ if (options.isDebug) {
28
+ console.debug(`🤖 Running ${data.name}`);
29
+ }
30
+ if (ignored.includes(data.name)) {
31
+ if (options.isDebug) {
32
+ console.info(`⏭️ Skipping ${data.name}`);
33
+ }
34
+ return data;
35
+ }
36
+ // input
37
+ const input = {
38
+ registers: read(data, "initial-regs").map((x) => BigInt(x)),
39
+ pc: read(data, "initial-pc"),
40
+ pageMap: asPageMap(read(data, "initial-page-map")),
41
+ memory: asChunks(read(data, "initial-memory")),
42
+ gas: BigInt(read(data, "initial-gas")),
43
+ program: read(data, "program"),
44
+ };
45
+ if (options.isDebug) {
46
+ const assembly = pvm.disassemble(input.program, pvm.InputKind.Generic, pvm.HasMetadata.No);
47
+ console.info("===========");
48
+ console.info(assembly);
49
+ console.info("\n^^^^^^^^^^^\n");
50
+ }
51
+ const exe = pvm.prepareProgram(pvm.InputKind.Generic, pvm.HasMetadata.No, input.program, input.registers, input.pageMap, input.memory, [], 16);
52
+ const result = pvm.runProgram(exe, input.gas, input.pc, options.isDebug, true);
53
+ const status = statusAsString(result.status);
54
+ // Normalize registers to plain unsigned BigInt array for comparison.
55
+ // The portable build may store signed BigInts or plain numbers in registers.
56
+ result.registers = Array.from(result.registers).map((v) => typeof v === "bigint" ? BigInt.asUintN(64, v) : BigInt(v));
57
+ result.gas = typeof result.gas === "bigint" ? result.gas : BigInt(result.gas);
58
+ // Normalize memory chunks to plain objects for comparison.
59
+ // The portable build returns class instances; WASM returns plain objects.
60
+ result.memory = result.memory.map((chunk) => ({
61
+ address: chunk.address,
62
+ data: Array.from(chunk.data),
63
+ }));
64
+ // silent mode - just put our vals into expected (comparison done externally)
65
+ if (options.isSilent) {
66
+ data["expected-pc"] = result.pc;
67
+ data["expected-gas"] = result.gas;
68
+ data["expected-status"] = status;
69
+ data["expected-regs"] = result.registers;
70
+ data["expected-page-fault-address"] = result.exitCode;
71
+ return data;
72
+ }
73
+ // compare with expected values
74
+ const expected = {
75
+ // just copy JAM-output result field
76
+ result: result.result,
77
+ status: read(data, "expected-status"),
78
+ registers: read(data, "expected-regs").map((x) => BigInt(x)),
79
+ pc: read(data, "expected-pc"),
80
+ memory: asChunks(read(data, "expected-memory")),
81
+ gas: BigInt(read(data, "expected-gas")),
82
+ exitCode: read(data, "expected-page-fault-address", 0),
83
+ };
84
+ try {
85
+ assert.deepStrictEqual({
86
+ ...result,
87
+ status,
88
+ }, expected);
89
+ console.log(`${OK} ${data.name}`);
90
+ }
91
+ catch (e) {
92
+ console.log(`${ERR} ${data.name}`);
93
+ throw e;
94
+ }
95
+ return data;
96
+ }
97
+ function asChunks(chunks) {
98
+ return chunks.map((chunk) => {
99
+ chunk.data = read(chunk, "contents");
100
+ delete chunk.contents;
101
+ return chunk;
102
+ });
103
+ }
104
+ var Access;
105
+ (function (Access) {
106
+ Access[Access["Read"] = 1] = "Read";
107
+ Access[Access["Write"] = 2] = "Write";
108
+ })(Access || (Access = {}));
109
+ function asPageMap(pages) {
110
+ return pages.map((page) => {
111
+ page.access = read(page, "is-writable") ? Access.Write : Access.Read;
112
+ return page;
113
+ });
114
+ }
115
+ function statusAsString(status) {
116
+ const map = {
117
+ 255: "ok",
118
+ 0: "halt",
119
+ 1: "panic",
120
+ 2: "page-fault",
121
+ 3: "host",
122
+ 4: "oog",
123
+ };
124
+ return map[status] || `unknown(${status})`;
125
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ // @ts-expect-error: portable bundle has no TS declarations for direct import
3
+ import * as pvm from "../dist/build/js/portable-bundle.js";
4
+ import { runW3fTests } from "./test-w3f-common.js";
5
+ runW3fTests(pvm);
@@ -1,121 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "json-bigint-patch";
3
- import * as assert from "node:assert";
4
- import { ERR, OK, read, run } from "../bin/src/test-json.js";
5
- import { disassemble, HasMetadata, InputKind, prepareProgram, runProgram } from "../build/release.js";
6
- const ignored = [
7
- "inst_load_u8_nok",
8
- "inst_store_imm_indirect_u16_with_offset_nok",
9
- "inst_store_imm_indirect_u32_with_offset_nok",
10
- "inst_store_imm_indirect_u64_with_offset_nok",
11
- "inst_store_imm_indirect_u8_with_offset_nok",
12
- "inst_store_imm_u8_trap_inaccessible",
13
- "inst_store_imm_u8_trap_read_only",
14
- "inst_store_indirect_u16_with_offset_nok",
15
- "inst_store_indirect_u32_with_offset_nok",
16
- "inst_store_indirect_u64_with_offset_nok",
17
- "inst_store_indirect_u8_with_offset_nok",
18
- "inst_store_u8_trap_inaccessible",
19
- "inst_store_u8_trap_read_only",
20
- ];
21
- // Run the CLI application
22
- main();
23
- // Main function
24
- function main() {
25
- const options = {
26
- isDebug: false,
27
- isSilent: false,
28
- useSbrkGas: false,
29
- };
30
- run(processW3f, options);
31
- }
32
- function processW3f(data, options) {
33
- if (options.isDebug) {
34
- console.debug(`🤖 Running ${data.name}`);
35
- }
36
- if (ignored.includes(data.name)) {
37
- if (options.isDebug) {
38
- console.info(`⏭️ Skipping ${data.name}`);
39
- }
40
- return data;
41
- }
42
- // input
43
- const input = {
44
- registers: read(data, "initial-regs").map((x) => BigInt(x)),
45
- pc: read(data, "initial-pc"),
46
- pageMap: asPageMap(read(data, "initial-page-map")),
47
- memory: asChunks(read(data, "initial-memory")),
48
- gas: BigInt(read(data, "initial-gas")),
49
- program: read(data, "program"),
50
- };
51
- if (options.isDebug) {
52
- const assembly = disassemble(input.program, InputKind.Generic, HasMetadata.No);
53
- console.info("===========");
54
- console.info(assembly);
55
- console.info("\n^^^^^^^^^^^\n");
56
- }
57
- const exe = prepareProgram(InputKind.Generic, HasMetadata.No, input.program, input.registers, input.pageMap, input.memory, [], 16);
58
- const result = runProgram(exe, input.gas, input.pc, options.isDebug, options.useSbrkGas, true);
59
- const status = statusAsString(result.status);
60
- // silent mode - just put our vals into expected (comparison done externally)
61
- if (options.isSilent) {
62
- data["expected-pc"] = result.pc;
63
- data["expected-gas"] = result.gas;
64
- data["expected-status"] = status;
65
- data["expected-regs"] = result.registers;
66
- data["expected-page-fault-address"] = result.exitCode;
67
- return data;
68
- }
69
- // compare with expected values
70
- const expected = {
71
- // just copy JAM-output result field
72
- result: result.result,
73
- status: read(data, "expected-status"),
74
- registers: read(data, "expected-regs").map((x) => BigInt(x)),
75
- pc: read(data, "expected-pc"),
76
- memory: asChunks(read(data, "expected-memory")),
77
- gas: BigInt(read(data, "expected-gas")),
78
- exitCode: read(data, "expected-page-fault-address", 0),
79
- };
80
- try {
81
- assert.deepStrictEqual({
82
- ...result,
83
- status,
84
- }, expected);
85
- console.log(`${OK} ${data.name}`);
86
- }
87
- catch (e) {
88
- console.log(`${ERR} ${data.name}`);
89
- throw e;
90
- }
91
- return data;
92
- }
93
- function asChunks(chunks) {
94
- return chunks.map((chunk) => {
95
- chunk.data = read(chunk, "contents");
96
- delete chunk.contents;
97
- return chunk;
98
- });
99
- }
100
- var Access;
101
- (function (Access) {
102
- Access[Access["Read"] = 1] = "Read";
103
- Access[Access["Write"] = 2] = "Write";
104
- })(Access || (Access = {}));
105
- function asPageMap(pages) {
106
- return pages.map((page) => {
107
- page.access = read(page, "is-writable") ? Access.Write : Access.Read;
108
- return page;
109
- });
110
- }
111
- function statusAsString(status) {
112
- const map = {
113
- 255: "ok",
114
- 0: "halt",
115
- 1: "panic",
116
- 2: "page-fault",
117
- 3: "host",
118
- 4: "oog",
119
- };
120
- return map[status] || `unknown(${status})`;
121
- }
2
+ import * as pvm from "../build/release.js";
3
+ import { runW3fTests } from "./test-w3f-common.js";
4
+ runW3fTests(pvm);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fluffylabs/anan-as",
3
3
  "description": "AssemblyScript PVM interpreter.",
4
- "version": "1.2.0",
4
+ "version": "1.3.0-5cbd3aa",
5
5
  "main": "./dist/bin/index.js",
6
6
  "bin": {
7
7
  "anan-as": "./dist/bin/index.js"
@@ -32,12 +32,18 @@
32
32
  "qa": "biome ci",
33
33
  "qa-fix": "npm run format; npm run lint",
34
34
  "start": "tsx ./bin/index.ts",
35
- "test": "npm run asbuild:test && tsx ./test/test-as.ts && tsx ./test/test-trace-replay.ts",
36
- "tsbuild": "tsc",
35
+ "test": "npm run asbuild:test && tsx ./test/test-as.ts && tsx ./test/test-trace-format.ts && tsx ./test/test-trace-replay.ts",
36
+ "tsbuild": "tsc && npm run tsbuild:portable",
37
+ "tsbuild:portable": "tsc --project portable/tsconfig.json && esbuild dist/build/js/portable/index.js --bundle --format=esm --platform=node --outfile=dist/build/js/portable-bundle.js",
37
38
  "test:w3f": "tsx ./test/test-w3f.ts",
39
+ "test:w3f-portable": "tsx ./test/test-w3f-portable.ts",
38
40
  "test:gas-cost": "tsx ./test/test-gas-cost.ts",
39
41
  "update-version": "tsx ./web/bump-version.ts $GITHUB_SHA",
40
- "web": "npx live-server ./web"
42
+ "web": "npx live-server ./web",
43
+ "bench": "tsx bench/run.ts --traces ./bench/traces --iterations 5 --warmup 1",
44
+ "bench:ci": "tsx bench/run.ts --traces ./bench/traces --iterations 5 --warmup 1 --output ./bench/results.json",
45
+ "bench:baseline": "tsx bench/run.ts --traces ./bench/traces --iterations 5 --warmup 1 --output ./bench/baseline.json",
46
+ "bench:compare": "tsx bench/compare.ts"
41
47
  },
42
48
  "type": "module",
43
49
  "keywords": [],
@@ -47,13 +53,14 @@
47
53
  "node": ">=18.3.0"
48
54
  },
49
55
  "devDependencies": {
50
- "@biomejs/biome": "^2.3.11",
51
- "@typeberry/lib": "^0.5.1",
52
- "@types/node": "^25.0.0",
53
- "assemblyscript": "^0.28.8",
56
+ "@biomejs/biome": "^2.4.10",
57
+ "@typeberry/lib": "^0.5.8",
58
+ "@types/node": "^25.3.3",
59
+ "assemblyscript": "^0.28.9",
60
+ "esbuild": "^0.28.0",
54
61
  "json-bigint-patch": "^0.0.8",
55
- "tsx": "^4.20.6",
56
- "typescript": "^5.9.3"
62
+ "tsx": "^4.21.0",
63
+ "typescript": "^6.0.2"
57
64
  },
58
65
  "files": [
59
66
  "dist/**/*.wasm",
@@ -111,6 +118,10 @@
111
118
  "./release.wasm": "./dist/build/release.wasm",
112
119
  "./release-mini.wasm": "./dist/build/release-mini.wasm",
113
120
  "./release-stub.wasm": "./dist/build/release-stub.wasm",
114
- "./compiler.wasm": "./dist/build/compiler.wasm"
121
+ "./compiler.wasm": "./dist/build/compiler.wasm",
122
+ "./js": {
123
+ "import": "./dist/build/js/portable-bundle.js",
124
+ "types": "./dist/build/js/portable/index.d.ts"
125
+ }
115
126
  }
116
127
  }