@fluffylabs/anan-as 1.2.0-41e43f6 → 1.2.0-5196d29
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 +3 -2
- package/dist/bin/src/fuzz.js +1 -1
- package/dist/bin/src/test-json.js +2 -6
- package/dist/bin/src/trace-replay.js +8 -4
- package/dist/build/compiler-inline.js +1 -1
- package/dist/build/compiler.d.ts +2 -13
- package/dist/build/compiler.js +1 -25
- 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 +27 -25
- package/dist/build/debug-raw.js +58 -57
- package/dist/build/debug-raw.wasm +0 -0
- package/dist/build/debug.d.ts +27 -25
- package/dist/build/debug.js +59 -58
- package/dist/build/debug.wasm +0 -0
- package/dist/build/js/assembly/api-debugger.d.ts +3 -3
- 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 +0 -1
- package/dist/build/js/assembly/api-types.js +0 -1
- package/dist/build/js/assembly/api-utils.d.ts +12 -5
- 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 +1 -1
- package/dist/build/js/assembly/gas.js +3 -2
- 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 -36
- 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 +15 -22
- 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.js +9 -7
- 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 +90 -40
- package/dist/build/js/assembly/spi.d.ts +1 -1
- package/dist/build/js/assembly/spi.js +2 -2
- package/dist/build/js/portable-bundle.js +666 -579
- package/dist/build/release-inline.js +1 -1
- package/dist/build/release-mini-inline.js +1 -1
- package/dist/build/release-mini.d.ts +27 -25
- package/dist/build/release-mini.js +59 -58
- package/dist/build/release-mini.wasm +0 -0
- package/dist/build/release-stub-inline.js +1 -1
- package/dist/build/release-stub.d.ts +27 -25
- package/dist/build/release-stub.js +59 -58
- package/dist/build/release-stub.wasm +0 -0
- package/dist/build/release.d.ts +27 -25
- package/dist/build/release.js +59 -58
- 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-w3f-common.js +1 -2
- package/package.json +7 -7
- package/dist/build/js/assembly/gas-costs.d.ts +0 -6
- package/dist/build/js/assembly/gas-costs.js +0 -39
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { OutcomeData } from "./outcome";
|
|
2
|
+
import { Inst } from "./utils";
|
|
3
3
|
const MAX_SHIFT_64 = 64;
|
|
4
4
|
const MAX_SHIFT_32 = 32;
|
|
5
5
|
// SHLO_L_IMM_32
|
|
6
6
|
export const shlo_l_imm_32 = (r, args, registers) => {
|
|
7
7
|
const shift = u32(args.c % MAX_SHIFT_32);
|
|
8
|
-
const value = u32(registers[reg(args.a)]);
|
|
9
|
-
registers[reg(args.b)] = u32SignExtend(value << shift);
|
|
10
|
-
return ok(r);
|
|
8
|
+
const value = u32(registers[Inst.reg(args.a)]);
|
|
9
|
+
registers[Inst.reg(args.b)] = Inst.u32SignExtend(value << shift);
|
|
10
|
+
return OutcomeData.ok(r);
|
|
11
11
|
};
|
|
12
12
|
// SHLO_R_IMM_32
|
|
13
13
|
export const shlo_r_imm_32 = (r, args, registers) => {
|
|
14
14
|
const shift = u32(args.c % MAX_SHIFT_32);
|
|
15
|
-
const value = u32(registers[reg(args.a)]);
|
|
16
|
-
registers[reg(args.b)] = u32SignExtend(value >>> shift);
|
|
17
|
-
return ok(r);
|
|
15
|
+
const value = u32(registers[Inst.reg(args.a)]);
|
|
16
|
+
registers[Inst.reg(args.b)] = Inst.u32SignExtend(value >>> shift);
|
|
17
|
+
return OutcomeData.ok(r);
|
|
18
18
|
};
|
|
19
19
|
// SHAR_R_IMM_32
|
|
20
20
|
export const shar_r_imm_32 = (r, args, registers) => {
|
|
21
21
|
const shift = u32(args.c % MAX_SHIFT_32);
|
|
22
|
-
const value = u32SignExtend(u32(registers[reg(args.a)]));
|
|
23
|
-
registers[reg(args.b)] = u64(i64(value) >> i64(shift));
|
|
24
|
-
return ok(r);
|
|
22
|
+
const value = Inst.u32SignExtend(u32(registers[Inst.reg(args.a)]));
|
|
23
|
+
registers[Inst.reg(args.b)] = u64(i64(value) >> i64(shift));
|
|
24
|
+
return OutcomeData.ok(r);
|
|
25
25
|
};
|
|
26
26
|
// SHLO_L_IMM_ALT_32
|
|
27
27
|
export const shlo_l_imm_alt_32 = (r, args, registers) => {
|
|
28
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
29
|
-
registers[reg(args.b)] = u32SignExtend(args.c << shift);
|
|
30
|
-
return ok(r);
|
|
28
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_32));
|
|
29
|
+
registers[Inst.reg(args.b)] = Inst.u32SignExtend(args.c << shift);
|
|
30
|
+
return OutcomeData.ok(r);
|
|
31
31
|
};
|
|
32
32
|
// SHLO_R_IMM_ALT_32
|
|
33
33
|
export const shlo_r_imm_alt_32 = (r, args, registers) => {
|
|
34
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
35
|
-
registers[reg(args.b)] = u32SignExtend(args.c >>> shift);
|
|
36
|
-
return ok(r);
|
|
34
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_32));
|
|
35
|
+
registers[Inst.reg(args.b)] = Inst.u32SignExtend(args.c >>> shift);
|
|
36
|
+
return OutcomeData.ok(r);
|
|
37
37
|
};
|
|
38
38
|
// SHAR_R_IMM_ALT_32
|
|
39
39
|
export const shar_r_imm_alt_32 = (r, args, registers) => {
|
|
40
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
41
|
-
const imm = u32SignExtend(args.c);
|
|
42
|
-
registers[reg(args.b)] = u32SignExtend(u32(i64(imm) >> i64(shift)));
|
|
43
|
-
return ok(r);
|
|
40
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_32));
|
|
41
|
+
const imm = Inst.u32SignExtend(args.c);
|
|
42
|
+
registers[Inst.reg(args.b)] = Inst.u32SignExtend(u32(i64(imm) >> i64(shift)));
|
|
43
|
+
return OutcomeData.ok(r);
|
|
44
44
|
};
|
|
45
45
|
// SHLO_L_IMM
|
|
46
46
|
export const shlo_l_imm = (r, args, registers) => {
|
|
47
47
|
const shift = u32(args.c % MAX_SHIFT_64);
|
|
48
|
-
registers[reg(args.b)] = u64(registers[reg(args.a)] << u64(shift));
|
|
49
|
-
return ok(r);
|
|
48
|
+
registers[Inst.reg(args.b)] = u64(registers[Inst.reg(args.a)] << u64(shift));
|
|
49
|
+
return OutcomeData.ok(r);
|
|
50
50
|
};
|
|
51
51
|
// SHLO_R_IMM
|
|
52
52
|
export const shlo_r_imm = (r, args, registers) => {
|
|
53
53
|
const shift = u32(args.c % MAX_SHIFT_64);
|
|
54
|
-
registers[reg(args.b)] = registers[reg(args.a)] >> u64(shift);
|
|
55
|
-
return ok(r);
|
|
54
|
+
registers[Inst.reg(args.b)] = registers[Inst.reg(args.a)] >> u64(shift);
|
|
55
|
+
return OutcomeData.ok(r);
|
|
56
56
|
};
|
|
57
57
|
// SHAR_R_IMM
|
|
58
58
|
export const shar_r_imm = (r, args, registers) => {
|
|
59
59
|
const shift = u32(args.c % MAX_SHIFT_64);
|
|
60
|
-
const value = i64(registers[reg(args.a)]);
|
|
61
|
-
registers[reg(args.b)] = u64(value >> i64(shift));
|
|
62
|
-
return ok(r);
|
|
60
|
+
const value = i64(registers[Inst.reg(args.a)]);
|
|
61
|
+
registers[Inst.reg(args.b)] = u64(value >> i64(shift));
|
|
62
|
+
return OutcomeData.ok(r);
|
|
63
63
|
};
|
|
64
64
|
// SHLO_L_IMM_ALT
|
|
65
65
|
export const shlo_l_imm_alt = (r, args, registers) => {
|
|
66
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
67
|
-
registers[reg(args.b)] = u64(u32SignExtend(args.c) << i64(shift));
|
|
68
|
-
return ok(r);
|
|
66
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_64));
|
|
67
|
+
registers[Inst.reg(args.b)] = u64(Inst.u32SignExtend(args.c) << i64(shift));
|
|
68
|
+
return OutcomeData.ok(r);
|
|
69
69
|
};
|
|
70
70
|
// SHLO_R_IMM_ALT
|
|
71
71
|
export const shlo_r_imm_alt = (r, args, registers) => {
|
|
72
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
73
|
-
registers[reg(args.b)] = u64(u32SignExtend(args.c)) >> u64(shift);
|
|
74
|
-
return ok(r);
|
|
72
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_64));
|
|
73
|
+
registers[Inst.reg(args.b)] = u64(Inst.u32SignExtend(args.c)) >> u64(shift);
|
|
74
|
+
return OutcomeData.ok(r);
|
|
75
75
|
};
|
|
76
76
|
// SHAR_R_IMM_ALT
|
|
77
77
|
export const shar_r_imm_alt = (r, args, registers) => {
|
|
78
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
79
|
-
const value = u32SignExtend(args.c);
|
|
80
|
-
registers[reg(args.b)] = u32SignExtend(u32(value >> i64(shift)));
|
|
81
|
-
return ok(r);
|
|
78
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_64));
|
|
79
|
+
const value = Inst.u32SignExtend(args.c);
|
|
80
|
+
registers[Inst.reg(args.b)] = Inst.u32SignExtend(u32(value >> i64(shift)));
|
|
81
|
+
return OutcomeData.ok(r);
|
|
82
82
|
};
|
|
83
83
|
// SHLO_L_32
|
|
84
84
|
export const shlo_l_32 = (r, args, registers) => {
|
|
85
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
86
|
-
const value = u32(registers[reg(args.b)]);
|
|
87
|
-
registers[reg(args.c)] = u32SignExtend(value << shift);
|
|
88
|
-
return ok(r);
|
|
85
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_32));
|
|
86
|
+
const value = u32(registers[Inst.reg(args.b)]);
|
|
87
|
+
registers[Inst.reg(args.c)] = Inst.u32SignExtend(value << shift);
|
|
88
|
+
return OutcomeData.ok(r);
|
|
89
89
|
};
|
|
90
90
|
// SHLO_R_32
|
|
91
91
|
export const shlo_r_32 = (r, args, registers) => {
|
|
92
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
93
|
-
const value = u32(registers[reg(args.b)]);
|
|
94
|
-
registers[reg(args.c)] = u32SignExtend(value >>> shift);
|
|
95
|
-
return ok(r);
|
|
92
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_32));
|
|
93
|
+
const value = u32(registers[Inst.reg(args.b)]);
|
|
94
|
+
registers[Inst.reg(args.c)] = Inst.u32SignExtend(value >>> shift);
|
|
95
|
+
return OutcomeData.ok(r);
|
|
96
96
|
};
|
|
97
97
|
// SHAR_R_32
|
|
98
98
|
export const shar_r_32 = (r, args, registers) => {
|
|
99
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_32));
|
|
100
|
-
const regValue = u32SignExtend(u32(registers[reg(args.b)]));
|
|
101
|
-
registers[reg(args.c)] = u32SignExtend(u32(i64(regValue) >> i64(shift)));
|
|
102
|
-
return ok(r);
|
|
99
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_32));
|
|
100
|
+
const regValue = Inst.u32SignExtend(u32(registers[Inst.reg(args.b)]));
|
|
101
|
+
registers[Inst.reg(args.c)] = Inst.u32SignExtend(u32(i64(regValue) >> i64(shift)));
|
|
102
|
+
return OutcomeData.ok(r);
|
|
103
103
|
};
|
|
104
104
|
// SHLO_L
|
|
105
105
|
export const shlo_l = (r, args, registers) => {
|
|
106
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
107
|
-
registers[reg(args.c)] = u64(registers[reg(args.b)] << u64(shift));
|
|
108
|
-
return ok(r);
|
|
106
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_64));
|
|
107
|
+
registers[Inst.reg(args.c)] = u64(registers[Inst.reg(args.b)] << u64(shift));
|
|
108
|
+
return OutcomeData.ok(r);
|
|
109
109
|
};
|
|
110
110
|
// SHLO_R
|
|
111
111
|
export const shlo_r = (r, args, registers) => {
|
|
112
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
113
|
-
registers[reg(args.c)] = registers[reg(args.b)] >> u64(shift);
|
|
114
|
-
return ok(r);
|
|
112
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_64));
|
|
113
|
+
registers[Inst.reg(args.c)] = registers[Inst.reg(args.b)] >> u64(shift);
|
|
114
|
+
return OutcomeData.ok(r);
|
|
115
115
|
};
|
|
116
116
|
// SHAR_R
|
|
117
117
|
export const shar_r = (r, args, registers) => {
|
|
118
|
-
const shift = u32(registers[reg(args.a)] % u64(MAX_SHIFT_64));
|
|
119
|
-
registers[reg(args.c)] = u64(i64(registers[reg(args.b)]) >> i64(shift));
|
|
120
|
-
return ok(r);
|
|
118
|
+
const shift = u32(registers[Inst.reg(args.a)] % u64(MAX_SHIFT_64));
|
|
119
|
+
registers[Inst.reg(args.c)] = u64(i64(registers[Inst.reg(args.b)]) >> i64(shift));
|
|
120
|
+
return OutcomeData.ok(r);
|
|
121
121
|
};
|
|
@@ -1,101 +1,101 @@
|
|
|
1
1
|
import { MaybePageFault } from "../memory";
|
|
2
2
|
import { portable } from "../portable";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { OutcomeData } from "./outcome";
|
|
4
|
+
import { Inst } from "./utils";
|
|
5
5
|
const faultRes = new MaybePageFault();
|
|
6
6
|
// Helper function to compute effective address from base register and signed 32-bit offset
|
|
7
7
|
function effectiveAddress(registers, baseReg, offset) {
|
|
8
|
-
return u32(portable.u64_add(registers[reg(u64(baseReg))], u32SignExtend(offset)));
|
|
8
|
+
return u32(portable.u64_add(registers[Inst.reg(u64(baseReg))], Inst.u32SignExtend(offset)));
|
|
9
9
|
}
|
|
10
10
|
// STORE_IMM_U8
|
|
11
11
|
export const store_imm_u8 = (r, args, _registers, memory) => {
|
|
12
12
|
const address = args.a;
|
|
13
13
|
memory.setU8(faultRes, address, (args.b & 0xff));
|
|
14
|
-
return okOrFault(r, faultRes);
|
|
14
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
15
15
|
};
|
|
16
16
|
// STORE_IMM_U16
|
|
17
17
|
export const store_imm_u16 = (r, args, _registers, memory) => {
|
|
18
18
|
const address = args.a;
|
|
19
19
|
memory.setU16(faultRes, address, (args.b & 65535));
|
|
20
|
-
return okOrFault(r, faultRes);
|
|
20
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
21
21
|
};
|
|
22
22
|
// STORE_IMM_U32
|
|
23
23
|
export const store_imm_u32 = (r, args, _registers, memory) => {
|
|
24
24
|
const address = args.a;
|
|
25
25
|
memory.setU32(faultRes, address, args.b);
|
|
26
|
-
return okOrFault(r, faultRes);
|
|
26
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
27
27
|
};
|
|
28
28
|
// STORE_IMM_U64
|
|
29
29
|
export const store_imm_u64 = (r, args, _registers, memory) => {
|
|
30
30
|
const address = args.a;
|
|
31
|
-
memory.setU64(faultRes, address, u32SignExtend(args.b));
|
|
32
|
-
return okOrFault(r, faultRes);
|
|
31
|
+
memory.setU64(faultRes, address, Inst.u32SignExtend(args.b));
|
|
32
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
33
33
|
};
|
|
34
34
|
// STORE_U8
|
|
35
35
|
export const store_u8 = (r, args, registers, memory) => {
|
|
36
|
-
memory.setU8(faultRes, args.b, (registers[reg(args.a)] & u64(0xff)));
|
|
37
|
-
return okOrFault(r, faultRes);
|
|
36
|
+
memory.setU8(faultRes, args.b, (registers[Inst.reg(args.a)] & u64(0xff)));
|
|
37
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
38
38
|
};
|
|
39
39
|
// STORE_U16
|
|
40
40
|
export const store_u16 = (r, args, registers, memory) => {
|
|
41
|
-
memory.setU16(faultRes, args.b, (registers[reg(args.a)] & u64(65535)));
|
|
42
|
-
return okOrFault(r, faultRes);
|
|
41
|
+
memory.setU16(faultRes, args.b, (registers[Inst.reg(args.a)] & u64(65535)));
|
|
42
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
43
43
|
};
|
|
44
44
|
// STORE_U32
|
|
45
45
|
export const store_u32 = (r, args, registers, memory) => {
|
|
46
|
-
memory.setU32(faultRes, args.b, u32(registers[reg(args.a)]));
|
|
47
|
-
return okOrFault(r, faultRes);
|
|
46
|
+
memory.setU32(faultRes, args.b, u32(registers[Inst.reg(args.a)]));
|
|
47
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
48
48
|
};
|
|
49
49
|
// STORE_U64
|
|
50
50
|
export const store_u64 = (r, args, registers, memory) => {
|
|
51
|
-
memory.setU64(faultRes, args.b, registers[reg(args.a)]);
|
|
52
|
-
return okOrFault(r, faultRes);
|
|
51
|
+
memory.setU64(faultRes, args.b, registers[Inst.reg(args.a)]);
|
|
52
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
53
53
|
};
|
|
54
54
|
// STORE_IMM_IND_U8
|
|
55
55
|
export const store_imm_ind_u8 = (r, args, registers, memory) => {
|
|
56
56
|
const address = effectiveAddress(registers, args.a, args.b);
|
|
57
57
|
memory.setU8(faultRes, address, (args.c & 0xff));
|
|
58
|
-
return okOrFault(r, faultRes);
|
|
58
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
59
59
|
};
|
|
60
60
|
// STORE_IMM_IND_U16
|
|
61
61
|
export const store_imm_ind_u16 = (r, args, registers, memory) => {
|
|
62
62
|
const address = effectiveAddress(registers, args.a, args.b);
|
|
63
63
|
memory.setU16(faultRes, address, (args.c & 65535));
|
|
64
|
-
return okOrFault(r, faultRes);
|
|
64
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
65
65
|
};
|
|
66
66
|
// STORE_IMM_IND_U32
|
|
67
67
|
export const store_imm_ind_u32 = (r, args, registers, memory) => {
|
|
68
68
|
const address = effectiveAddress(registers, args.a, args.b);
|
|
69
69
|
memory.setU32(faultRes, address, args.c);
|
|
70
|
-
return okOrFault(r, faultRes);
|
|
70
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
71
71
|
};
|
|
72
72
|
// STORE_IMM_IND_U64
|
|
73
73
|
export const store_imm_ind_u64 = (r, args, registers, memory) => {
|
|
74
74
|
const address = effectiveAddress(registers, args.a, args.b);
|
|
75
|
-
memory.setU64(faultRes, address, u32SignExtend(args.c));
|
|
76
|
-
return okOrFault(r, faultRes);
|
|
75
|
+
memory.setU64(faultRes, address, Inst.u32SignExtend(args.c));
|
|
76
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
77
77
|
};
|
|
78
78
|
// STORE_IND_U8
|
|
79
79
|
export const store_ind_u8 = (r, args, registers, memory) => {
|
|
80
80
|
const address = effectiveAddress(registers, args.a, args.c);
|
|
81
|
-
memory.setU8(faultRes, address, (registers[reg(args.b)] & u64(0xff)));
|
|
82
|
-
return okOrFault(r, faultRes);
|
|
81
|
+
memory.setU8(faultRes, address, (registers[Inst.reg(args.b)] & u64(0xff)));
|
|
82
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
83
83
|
};
|
|
84
84
|
// STORE_IND_U16
|
|
85
85
|
export const store_ind_u16 = (r, args, registers, memory) => {
|
|
86
86
|
const address = effectiveAddress(registers, args.a, args.c);
|
|
87
|
-
memory.setU16(faultRes, address, (registers[reg(args.b)] & u64(65535)));
|
|
88
|
-
return okOrFault(r, faultRes);
|
|
87
|
+
memory.setU16(faultRes, address, (registers[Inst.reg(args.b)] & u64(65535)));
|
|
88
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
89
89
|
};
|
|
90
90
|
// STORE_IND_U32
|
|
91
91
|
export const store_ind_u32 = (r, args, registers, memory) => {
|
|
92
92
|
const address = effectiveAddress(registers, args.a, args.c);
|
|
93
|
-
memory.setU32(faultRes, address, u32(registers[reg(args.b)]));
|
|
94
|
-
return okOrFault(r, faultRes);
|
|
93
|
+
memory.setU32(faultRes, address, u32(registers[Inst.reg(args.b)]));
|
|
94
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
95
95
|
};
|
|
96
96
|
// STORE_IND_U64
|
|
97
97
|
export const store_ind_u64 = (r, args, registers, memory) => {
|
|
98
98
|
const address = effectiveAddress(registers, args.a, args.c);
|
|
99
|
-
memory.setU64(faultRes, address, registers[reg(args.b)]);
|
|
100
|
-
return okOrFault(r, faultRes);
|
|
99
|
+
memory.setU64(faultRes, address, registers[Inst.reg(args.b)]);
|
|
100
|
+
return OutcomeData.okOrFault(r, faultRes);
|
|
101
101
|
};
|
|
@@ -17,7 +17,9 @@ export declare function mulUpperUnsigned(a: u64, b: u64): u64;
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function mulUpperSigned(a: i64, b: i64): u64;
|
|
19
19
|
export declare function mulUpperSignedUnsigned(a: i64, b: u64): u64;
|
|
20
|
-
export declare
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
export declare class Inst {
|
|
21
|
+
static u8SignExtend(v: u8): i64;
|
|
22
|
+
static u16SignExtend(v: u16): i64;
|
|
23
|
+
static u32SignExtend(v: u32): i64;
|
|
24
|
+
static reg(v: u64): u32;
|
|
25
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
1
7
|
import { portable } from "../portable";
|
|
2
8
|
import { NO_OF_REGISTERS } from "../registers";
|
|
3
9
|
/**
|
|
@@ -56,20 +62,30 @@ export function mulUpperSignedUnsigned(a, b) {
|
|
|
56
62
|
}
|
|
57
63
|
return mulUpperUnsigned(a, b);
|
|
58
64
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
export function reg(v) {
|
|
74
|
-
return v >= u64(NO_OF_REGISTERS) ? NO_OF_REGISTERS - 1 : u32(v);
|
|
65
|
+
export class Inst {
|
|
66
|
+
static u8SignExtend(v) {
|
|
67
|
+
// u64 wrap ensures unsigned representation in JS BigInt (no-op in AS)
|
|
68
|
+
return u64(i64(i32(i16(i8(v)))));
|
|
69
|
+
}
|
|
70
|
+
static u16SignExtend(v) {
|
|
71
|
+
return u64(i64(i32(i16(v))));
|
|
72
|
+
}
|
|
73
|
+
static u32SignExtend(v) {
|
|
74
|
+
return u64(i64(i32(v)));
|
|
75
|
+
}
|
|
76
|
+
static reg(v) {
|
|
77
|
+
return v >= u64(NO_OF_REGISTERS) ? NO_OF_REGISTERS - 1 : u32(v);
|
|
78
|
+
}
|
|
75
79
|
}
|
|
80
|
+
__decorate([
|
|
81
|
+
inline
|
|
82
|
+
], Inst, "u8SignExtend", null);
|
|
83
|
+
__decorate([
|
|
84
|
+
inline
|
|
85
|
+
], Inst, "u16SignExtend", null);
|
|
86
|
+
__decorate([
|
|
87
|
+
inline
|
|
88
|
+
], Inst, "u32SignExtend", null);
|
|
89
|
+
__decorate([
|
|
90
|
+
inline
|
|
91
|
+
], Inst, "reg", null);
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Arguments } from "./arguments";
|
|
2
|
-
import { Gas } from "./gas";
|
|
3
2
|
export declare class Instruction {
|
|
4
3
|
name: string;
|
|
5
4
|
kind: Arguments;
|
|
6
|
-
gas:
|
|
5
|
+
gas: u32;
|
|
7
6
|
isTerminating: boolean;
|
|
8
7
|
}
|
|
9
8
|
export declare const MISSING_INSTRUCTION: Instruction;
|
|
10
9
|
export declare const SBRK: Instruction;
|
|
11
|
-
export declare const INSTRUCTIONS: Instruction
|
|
10
|
+
export declare const INSTRUCTIONS: StaticArray<Instruction>;
|
|
@@ -3,7 +3,7 @@ export class Instruction {
|
|
|
3
3
|
constructor() {
|
|
4
4
|
this.name = "";
|
|
5
5
|
this.kind = Arguments.Zero;
|
|
6
|
-
this.gas =
|
|
6
|
+
this.gas = u32(0);
|
|
7
7
|
this.isTerminating = false;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -11,13 +11,13 @@ function instruction(name, kind, gas, isTerminating = false) {
|
|
|
11
11
|
const i = new Instruction();
|
|
12
12
|
i.name = name;
|
|
13
13
|
i.kind = kind;
|
|
14
|
-
i.gas =
|
|
14
|
+
i.gas = u32(gas);
|
|
15
15
|
i.isTerminating = isTerminating;
|
|
16
16
|
return i;
|
|
17
17
|
}
|
|
18
18
|
export const MISSING_INSTRUCTION = instruction("INVALID", Arguments.Zero, 1, false);
|
|
19
19
|
export const SBRK = instruction("SBRK", Arguments.TwoReg, 1);
|
|
20
|
-
export const INSTRUCTIONS = [
|
|
20
|
+
export const INSTRUCTIONS = StaticArray.fromArray([
|
|
21
21
|
/* 000 */ instruction("TRAP", Arguments.Zero, 1, true),
|
|
22
22
|
/* 001 */ instruction("FALLTHROUGH", Arguments.Zero, 1, true),
|
|
23
23
|
MISSING_INSTRUCTION,
|
|
@@ -249,4 +249,4 @@ export const INSTRUCTIONS = [
|
|
|
249
249
|
/* 228 */ instruction("MAX_U", Arguments.ThreeReg, 1),
|
|
250
250
|
/* 229 */ instruction("MIN", Arguments.ThreeReg, 1),
|
|
251
251
|
/* 230 */ instruction("MIN_U", Arguments.ThreeReg, 1),
|
|
252
|
-
];
|
|
252
|
+
]);
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Args } from "./arguments";
|
|
2
2
|
import { gasCounter } from "./gas";
|
|
3
|
-
import { INSTRUCTIONS, MISSING_INSTRUCTION
|
|
3
|
+
import { INSTRUCTIONS, MISSING_INSTRUCTION } from "./instructions";
|
|
4
4
|
import { Outcome, OutcomeData, Result } from "./instructions/outcome";
|
|
5
|
-
import { reg } from "./instructions/utils";
|
|
6
5
|
import { RUN } from "./instructions-exe";
|
|
7
6
|
import { MemoryBuilder } from "./memory";
|
|
8
|
-
import {
|
|
7
|
+
import { RESERVED_MEMORY } from "./memory-page";
|
|
9
8
|
import { portable } from "./portable";
|
|
10
9
|
import { decodeArguments } from "./program";
|
|
11
10
|
export var Status;
|
|
@@ -51,7 +50,6 @@ export class Interpreter {
|
|
|
51
50
|
this.status = Status.OK;
|
|
52
51
|
this.exitCode = 0;
|
|
53
52
|
this.nextPc = 0;
|
|
54
|
-
this.useSbrkGas = false;
|
|
55
53
|
}
|
|
56
54
|
nextSteps(nSteps = 1) {
|
|
57
55
|
// resuming after host call
|
|
@@ -72,9 +70,11 @@ export class Interpreter {
|
|
|
72
70
|
this.nextPc = -1;
|
|
73
71
|
return true;
|
|
74
72
|
}
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
const
|
|
73
|
+
const code = this.program.code;
|
|
74
|
+
const mask = this.program.mask;
|
|
75
|
+
const gasCosts = this.program.gasCosts.codeAndGas;
|
|
76
|
+
const basicBlocks = this.program.basicBlocks;
|
|
77
|
+
const jumpTable = this.program.jumpTable;
|
|
78
78
|
const argsRes = this.argsRes;
|
|
79
79
|
const outcomeRes = this.outcomeRes;
|
|
80
80
|
for (let i = 0; i < nSteps; i++) {
|
|
@@ -94,10 +94,12 @@ export class Interpreter {
|
|
|
94
94
|
}
|
|
95
95
|
return false;
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
// check gas via pre-computed cost table (per-instruction or per-block)
|
|
98
|
+
const codeAndGas = portable.staticArrayAt(gasCosts, pc);
|
|
99
|
+
const instruction = codeAndGas & 0xff;
|
|
100
|
+
const gasCost = codeAndGas >> 8;
|
|
98
101
|
const iData = instruction < INSTRUCTIONS.length ? unchecked(INSTRUCTIONS[instruction]) : MISSING_INSTRUCTION;
|
|
99
|
-
|
|
100
|
-
if (this.gas.sub(iData.gas)) {
|
|
102
|
+
if (gasCost > 0 && this.gas.sub(gasCost)) {
|
|
101
103
|
this.status = Status.OOG;
|
|
102
104
|
return false;
|
|
103
105
|
}
|
|
@@ -108,15 +110,6 @@ export class Interpreter {
|
|
|
108
110
|
// get args and invoke instruction
|
|
109
111
|
const skipBytes = mask.skipBytesToNextInstruction(pc);
|
|
110
112
|
const args = decodeArguments(argsRes, iData.kind, code, pc + 1, skipBytes);
|
|
111
|
-
// additional gas cost of sbrk
|
|
112
|
-
if (iData === SBRK && this.useSbrkGas) {
|
|
113
|
-
const alloc = u64(u32(this.registers[reg(u64(args.a))]));
|
|
114
|
-
const gas = portable.u64_mul(portable.u64_sub(portable.u64_add(alloc, u64(PAGE_SIZE)), u64(1)) >> u64(PAGE_SIZE_SHIFT), u64(16));
|
|
115
|
-
if (this.gas.sub(gas)) {
|
|
116
|
-
this.status = Status.OOG;
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
113
|
const exe = unchecked(RUN[instruction]);
|
|
121
114
|
const outcome = exe(outcomeRes, args, this.registers, this.memory);
|
|
122
115
|
// Fast path: Ok is the most common outcome (~70%+ of instructions)
|
|
@@ -126,7 +119,7 @@ export class Interpreter {
|
|
|
126
119
|
}
|
|
127
120
|
switch (outcome.outcome) {
|
|
128
121
|
case Outcome.StaticJump: {
|
|
129
|
-
const branchResult = branch(this.branchRes,
|
|
122
|
+
const branchResult = branch(this.branchRes, basicBlocks, pc, outcome.staticJump);
|
|
130
123
|
if (!branchResult.isOkay) {
|
|
131
124
|
this.status = Status.PANIC;
|
|
132
125
|
return false;
|
|
@@ -135,7 +128,7 @@ export class Interpreter {
|
|
|
135
128
|
continue;
|
|
136
129
|
}
|
|
137
130
|
case Outcome.DynamicJump: {
|
|
138
|
-
const res = dJump(this.djumpRes,
|
|
131
|
+
const res = dJump(this.djumpRes, jumpTable, outcome.dJump);
|
|
139
132
|
if (res.status === DjumpStatus.HALT) {
|
|
140
133
|
this.status = Status.HALT;
|
|
141
134
|
return false;
|
|
@@ -144,7 +137,7 @@ export class Interpreter {
|
|
|
144
137
|
this.status = Status.PANIC;
|
|
145
138
|
return false;
|
|
146
139
|
}
|
|
147
|
-
const branchResult = branch(this.branchRes,
|
|
140
|
+
const branchResult = branch(this.branchRes, basicBlocks, res.newPc, 0);
|
|
148
141
|
if (!branchResult.isOkay) {
|
|
149
142
|
this.status = Status.PANIC;
|
|
150
143
|
return false;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*/
|
|
8
|
-
export declare function minU32(a: u32, b: u32): u32;
|
|
1
|
+
export declare class IntMath {
|
|
2
|
+
/** Integer minimum of two i32 values. */
|
|
3
|
+
static minI32(a: i32, b: i32): i32;
|
|
4
|
+
/** Unsigned integer minimum of two u32 values. */
|
|
5
|
+
static minU32(a: u32, b: u32): u32;
|
|
6
|
+
}
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
export class IntMath {
|
|
8
|
+
/** Integer minimum of two i32 values. */
|
|
9
|
+
static minI32(a, b) {
|
|
10
|
+
return a < b ? a : b;
|
|
11
|
+
}
|
|
12
|
+
/** Unsigned integer minimum of two u32 values. */
|
|
13
|
+
static minU32(a, b) {
|
|
14
|
+
return a < b ? a : b;
|
|
15
|
+
}
|
|
14
16
|
}
|
|
17
|
+
__decorate([
|
|
18
|
+
inline
|
|
19
|
+
], IntMath, "minI32", null);
|
|
20
|
+
__decorate([
|
|
21
|
+
inline
|
|
22
|
+
], IntMath, "minU32", null);
|
|
@@ -4,8 +4,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { Inst } from "./instructions/utils";
|
|
8
|
+
import { IntMath } from "./math";
|
|
9
9
|
import { Access, Arena, PAGE_SIZE, PAGE_SIZE_SHIFT, Page, RawPage, RESERVED_MEMORY, RESERVED_PAGES, } from "./memory-page";
|
|
10
10
|
import { portable } from "./portable";
|
|
11
11
|
// @unmanaged
|
|
@@ -223,6 +223,7 @@ export class Memory {
|
|
|
223
223
|
this.sbrkAddress = u32(newSbrk);
|
|
224
224
|
const pageIdx = i32(portable.u64_sub(newSbrk, u64(1)) >> u64(PAGE_SIZE_SHIFT));
|
|
225
225
|
if (pageIdx === this.lastAllocatedPage) {
|
|
226
|
+
faultRes.isFault = false;
|
|
226
227
|
return freeMemoryStart;
|
|
227
228
|
}
|
|
228
229
|
for (let i = this.lastAllocatedPage + 1; i <= pageIdx; i++) {
|
|
@@ -232,6 +233,7 @@ export class Memory {
|
|
|
232
233
|
this.cache.insert(i, page);
|
|
233
234
|
}
|
|
234
235
|
this.lastAllocatedPage = pageIdx;
|
|
236
|
+
faultRes.isFault = false;
|
|
235
237
|
return freeMemoryStart;
|
|
236
238
|
}
|
|
237
239
|
getU8(faultRes, address) {
|
|
@@ -247,13 +249,13 @@ export class Memory {
|
|
|
247
249
|
return portable.bswap_u64(this.getBytesReversed(faultRes, Access.Read, address, 8));
|
|
248
250
|
}
|
|
249
251
|
getI8(faultRes, address) {
|
|
250
|
-
return u8SignExtend(u8(this.getU8(faultRes, address)));
|
|
252
|
+
return Inst.u8SignExtend(u8(this.getU8(faultRes, address)));
|
|
251
253
|
}
|
|
252
254
|
getI16(faultRes, address) {
|
|
253
|
-
return u16SignExtend(u16(this.getU16(faultRes, address)));
|
|
255
|
+
return Inst.u16SignExtend(u16(this.getU16(faultRes, address)));
|
|
254
256
|
}
|
|
255
257
|
getI32(faultRes, address) {
|
|
256
|
-
return u32SignExtend(u32(this.getU32(faultRes, address)));
|
|
258
|
+
return Inst.u32SignExtend(u32(this.getU32(faultRes, address)));
|
|
257
259
|
}
|
|
258
260
|
setU8(faultRes, address, value) {
|
|
259
261
|
this.setBytes(faultRes, address, value, 1);
|
|
@@ -443,7 +445,7 @@ export class Memory {
|
|
|
443
445
|
}
|
|
444
446
|
let bytesLeft = u64(value);
|
|
445
447
|
// write to first page
|
|
446
|
-
const firstPageEnd = minU32(PAGE_SIZE, r.firstPageOffset + bytes);
|
|
448
|
+
const firstPageEnd = IntMath.minU32(PAGE_SIZE, r.firstPageOffset + bytes);
|
|
447
449
|
for (let i = r.firstPageOffset; i < firstPageEnd; i++) {
|
|
448
450
|
r.firstPageData[i] = u8(bytesLeft);
|
|
449
451
|
bytesLeft >>= u64(8);
|
|
@@ -461,7 +463,7 @@ export class Memory {
|
|
|
461
463
|
}
|
|
462
464
|
// result (bytes in reverse order)
|
|
463
465
|
let r = u64(0);
|
|
464
|
-
const firstPageEnd = minU32(PAGE_SIZE, this.chunksResult.firstPageOffset + bytes);
|
|
466
|
+
const firstPageEnd = IntMath.minU32(PAGE_SIZE, this.chunksResult.firstPageOffset + bytes);
|
|
465
467
|
// read from first page
|
|
466
468
|
for (let i = this.chunksResult.firstPageOffset; i < firstPageEnd; i++) {
|
|
467
469
|
r = (r << u64(8)) | u64(this.chunksResult.firstPageData[i]);
|