@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.
- package/dist/bin/index.js +138 -5
- package/dist/bin/src/fuzz.js +2 -2
- package/dist/bin/src/test-json.js +2 -6
- package/dist/bin/src/trace-parse.js +1 -0
- package/dist/bin/src/trace-replay.js +14 -9
- package/dist/bin/src/tracer.js +16 -13
- package/dist/bin/src/utils.js +2 -2
- package/dist/build/compiler-inline.js +1 -1
- package/dist/build/compiler.d.ts +17 -13
- package/dist/build/compiler.js +13 -21
- package/dist/build/compiler.wasm +0 -0
- package/dist/build/debug-inline.js +1 -1
- package/dist/build/debug-raw-inline.js +1 -1
- package/dist/build/debug-raw.d.ts +34 -32
- package/dist/build/debug-raw.js +62 -69
- package/dist/build/debug-raw.wasm +0 -0
- package/dist/build/debug.d.ts +34 -32
- package/dist/build/debug.js +63 -70
- package/dist/build/debug.wasm +0 -0
- package/dist/build/js/assembly/api-debugger.d.ts +4 -4
- package/dist/build/js/assembly/api-debugger.js +6 -6
- package/dist/build/js/assembly/api-internal.d.ts +1 -1
- package/dist/build/js/assembly/api-internal.js +2 -3
- package/dist/build/js/assembly/api-types.d.ts +4 -4
- package/dist/build/js/assembly/api-types.js +3 -4
- package/dist/build/js/assembly/api-utils.d.ts +14 -6
- package/dist/build/js/assembly/api-utils.js +28 -13
- package/dist/build/js/assembly/arguments.d.ts +4 -4
- package/dist/build/js/assembly/arguments.js +10 -10
- package/dist/build/js/assembly/gas.d.ts +8 -13
- package/dist/build/js/assembly/gas.js +17 -7
- package/dist/build/js/assembly/instructions/bit.js +22 -22
- package/dist/build/js/assembly/instructions/branch.js +56 -56
- package/dist/build/js/assembly/instructions/jump.js +10 -10
- package/dist/build/js/assembly/instructions/load.js +41 -41
- package/dist/build/js/assembly/instructions/logic.js +20 -20
- package/dist/build/js/assembly/instructions/math.js +105 -105
- package/dist/build/js/assembly/instructions/misc.js +10 -10
- package/dist/build/js/assembly/instructions/mov.js +16 -16
- package/dist/build/js/assembly/instructions/outcome.d.ts +7 -7
- package/dist/build/js/assembly/instructions/outcome.js +63 -38
- package/dist/build/js/assembly/instructions/rot.js +18 -18
- package/dist/build/js/assembly/instructions/set.js +18 -18
- package/dist/build/js/assembly/instructions/shift.js +59 -59
- package/dist/build/js/assembly/instructions/store.js +29 -29
- package/dist/build/js/assembly/instructions/utils.d.ts +6 -4
- package/dist/build/js/assembly/instructions/utils.js +32 -16
- package/dist/build/js/assembly/instructions.d.ts +2 -3
- package/dist/build/js/assembly/instructions.js +4 -4
- package/dist/build/js/assembly/interpreter.d.ts +0 -1
- package/dist/build/js/assembly/interpreter.js +30 -38
- package/dist/build/js/assembly/math.d.ts +6 -8
- package/dist/build/js/assembly/math.js +21 -13
- package/dist/build/js/assembly/memory-page.d.ts +2 -4
- package/dist/build/js/assembly/memory-page.js +13 -7
- package/dist/build/js/assembly/memory.d.ts +1 -0
- package/dist/build/js/assembly/memory.js +119 -23
- package/dist/build/js/assembly/portable.js +1 -0
- package/dist/build/js/assembly/program-build.js +4 -4
- package/dist/build/js/assembly/program.d.ts +15 -8
- package/dist/build/js/assembly/program.js +95 -39
- package/dist/build/js/assembly/spi.d.ts +1 -1
- package/dist/build/js/assembly/spi.js +2 -2
- package/dist/build/js/portable/bootstrap.js +1 -0
- package/dist/build/js/portable-bundle.js +829 -641
- package/dist/build/release-inline.js +1 -1
- package/dist/build/release-mini-inline.js +1 -1
- package/dist/build/release-mini.d.ts +34 -32
- package/dist/build/release-mini.js +63 -70
- package/dist/build/release-mini.wasm +0 -0
- package/dist/build/release-stub-inline.js +1 -1
- package/dist/build/release-stub.d.ts +34 -32
- package/dist/build/release-stub.js +63 -70
- package/dist/build/release-stub.wasm +0 -0
- package/dist/build/release.d.ts +34 -32
- package/dist/build/release.js +63 -70
- package/dist/build/release.wasm +0 -0
- package/dist/build/test-inline.js +1 -1
- package/dist/build/test.wasm +0 -0
- package/dist/test/test-gas-cost.js +2 -3
- package/dist/test/test-trace-format.js +166 -0
- package/dist/test/test-w3f-common.js +1 -2
- package/package.json +14 -10
- package/dist/build/js/assembly/gas-costs.d.ts +0 -6
- 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 {
|
|
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 `
|
|
27
|
+
/** Convert `Uint8Array` to `Code` (StaticArray<u8>) */
|
|
28
28
|
export function lowerBytes(data) {
|
|
29
|
-
const r = new
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
259
|
+
EXTENDED_BUF[i - offset] = unchecked(code[i]);
|
|
204
260
|
}
|
|
205
|
-
return DECODERS[kind](args,
|
|
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);
|