@typeberry/lib 0.2.0-c96e8ef → 0.2.0-eae807e
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/index.cjs +2500 -1911
- package/index.d.ts +1956 -1864
- package/index.js +2498 -1909
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var assert = require('node:assert');
|
|
4
4
|
var fs = require('node:fs');
|
|
5
5
|
var os = require('node:os');
|
|
6
|
+
var node_url = require('node:url');
|
|
6
7
|
|
|
7
8
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
8
9
|
var GpVersion;
|
|
@@ -10,44 +11,40 @@ var GpVersion;
|
|
|
10
11
|
GpVersion["V0_6_7"] = "0.6.7";
|
|
11
12
|
GpVersion["V0_7_0"] = "0.7.0";
|
|
12
13
|
GpVersion["V0_7_1"] = "0.7.1";
|
|
13
|
-
GpVersion["V0_7_2"] = "0.7.2
|
|
14
|
+
GpVersion["V0_7_2"] = "0.7.2";
|
|
14
15
|
})(GpVersion || (GpVersion = {}));
|
|
15
16
|
var TestSuite;
|
|
16
17
|
(function (TestSuite) {
|
|
17
18
|
TestSuite["W3F_DAVXY"] = "w3f-davxy";
|
|
18
19
|
TestSuite["JAMDUNA"] = "jamduna";
|
|
19
20
|
})(TestSuite || (TestSuite = {}));
|
|
21
|
+
const ALL_VERSIONS_IN_ORDER = [GpVersion.V0_6_7, GpVersion.V0_7_0, GpVersion.V0_7_1, GpVersion.V0_7_2];
|
|
20
22
|
const DEFAULT_SUITE = TestSuite.W3F_DAVXY;
|
|
21
|
-
const DEFAULT_VERSION = GpVersion.
|
|
23
|
+
const DEFAULT_VERSION = GpVersion.V0_7_2;
|
|
22
24
|
const env$1 = typeof process === "undefined" ? {} : process.env;
|
|
23
25
|
let CURRENT_VERSION = parseCurrentVersion(env$1.GP_VERSION) ?? DEFAULT_VERSION;
|
|
24
26
|
let CURRENT_SUITE = parseCurrentSuite(env$1.TEST_SUITE) ?? DEFAULT_SUITE;
|
|
25
|
-
const ALL_VERSIONS_IN_ORDER = [GpVersion.V0_6_7, GpVersion.V0_7_0, GpVersion.V0_7_1, GpVersion.V0_7_2];
|
|
26
27
|
function parseCurrentVersion(env) {
|
|
27
28
|
if (env === undefined) {
|
|
28
29
|
return undefined;
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
case GpVersion.V0_7_2:
|
|
35
|
-
return env;
|
|
36
|
-
default:
|
|
37
|
-
throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
|
|
31
|
+
for (const v of Object.values(GpVersion)) {
|
|
32
|
+
if (env === v) {
|
|
33
|
+
return v;
|
|
34
|
+
}
|
|
38
35
|
}
|
|
36
|
+
throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
|
|
39
37
|
}
|
|
40
38
|
function parseCurrentSuite(env) {
|
|
41
39
|
if (env === undefined) {
|
|
42
40
|
return undefined;
|
|
43
41
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
default:
|
|
49
|
-
throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`);
|
|
42
|
+
for (const s of Object.values(TestSuite)) {
|
|
43
|
+
if (env === s) {
|
|
44
|
+
return s;
|
|
45
|
+
}
|
|
50
46
|
}
|
|
47
|
+
throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`);
|
|
51
48
|
}
|
|
52
49
|
class Compatibility {
|
|
53
50
|
static override(version) {
|
|
@@ -5174,6 +5171,17 @@ class Bootnode {
|
|
|
5174
5171
|
}
|
|
5175
5172
|
}
|
|
5176
5173
|
|
|
5174
|
+
/** Implemented PVM Backends names in THE SAME ORDER as enum. */
|
|
5175
|
+
const PvmBackendNames = ["built-in", "ananas"];
|
|
5176
|
+
/** Implemented PVM Backends to choose from. */
|
|
5177
|
+
var PvmBackend;
|
|
5178
|
+
(function (PvmBackend) {
|
|
5179
|
+
/** Built-in aka. Typeberry 🫐 interpreter. */
|
|
5180
|
+
PvmBackend[PvmBackend["BuiltIn"] = 0] = "BuiltIn";
|
|
5181
|
+
/** Ananas 🍍 interpreter. */
|
|
5182
|
+
PvmBackend[PvmBackend["Ananas"] = 1] = "Ananas";
|
|
5183
|
+
})(PvmBackend || (PvmBackend = {}));
|
|
5184
|
+
|
|
5177
5185
|
var index$m = /*#__PURE__*/Object.freeze({
|
|
5178
5186
|
__proto__: null,
|
|
5179
5187
|
Bootnode: Bootnode,
|
|
@@ -5183,6 +5191,8 @@ var index$m = /*#__PURE__*/Object.freeze({
|
|
|
5183
5191
|
EST_EPOCH_LENGTH: EST_EPOCH_LENGTH,
|
|
5184
5192
|
EST_VALIDATORS: EST_VALIDATORS,
|
|
5185
5193
|
EST_VALIDATORS_SUPER_MAJORITY: EST_VALIDATORS_SUPER_MAJORITY,
|
|
5194
|
+
get PvmBackend () { return PvmBackend; },
|
|
5195
|
+
PvmBackendNames: PvmBackendNames,
|
|
5186
5196
|
fullChainSpec: fullChainSpec,
|
|
5187
5197
|
tinyChainSpec: tinyChainSpec
|
|
5188
5198
|
});
|
|
@@ -7731,6 +7741,7 @@ const DEFAULT_CONFIG = "default";
|
|
|
7731
7741
|
const NODE_DEFAULTS = {
|
|
7732
7742
|
name: isBrowser() ? "browser" : os.hostname(),
|
|
7733
7743
|
config: DEFAULT_CONFIG,
|
|
7744
|
+
pvm: PvmBackend.BuiltIn,
|
|
7734
7745
|
};
|
|
7735
7746
|
/** Chain spec chooser. */
|
|
7736
7747
|
var KnownChainSpec;
|
|
@@ -10930,6 +10941,13 @@ class StateEntries {
|
|
|
10930
10941
|
[TEST_COMPARE_USING]() {
|
|
10931
10942
|
return Object.fromEntries(this.entries);
|
|
10932
10943
|
}
|
|
10944
|
+
/** Dump state entries to JSON string (format compatible with stf vectors). */
|
|
10945
|
+
toString() {
|
|
10946
|
+
return JSON.stringify(Array.from(this.entries.entries()).map(([key, value]) => ({
|
|
10947
|
+
key,
|
|
10948
|
+
value,
|
|
10949
|
+
})), null, 2);
|
|
10950
|
+
}
|
|
10933
10951
|
[Symbol.iterator]() {
|
|
10934
10952
|
return this.entries[Symbol.iterator]();
|
|
10935
10953
|
}
|
|
@@ -12273,18 +12291,41 @@ class PendingTransfer {
|
|
|
12273
12291
|
}
|
|
12274
12292
|
}
|
|
12275
12293
|
|
|
12294
|
+
/** Attempt to convert given number into U32 gas representation. */
|
|
12295
|
+
const tryAsSmallGas = (v) => asOpaqueType(tryAsU32(v));
|
|
12296
|
+
/** Attempt to convert given number into U64 gas representation. */
|
|
12297
|
+
const tryAsBigGas = (v) => asOpaqueType(tryAsU64(v));
|
|
12298
|
+
/** Attempt to convert given number into gas. */
|
|
12299
|
+
const tryAsGas = (v) => typeof v === "number" && v < 2 ** 32 ? tryAsSmallGas(v) : tryAsBigGas(v);
|
|
12300
|
+
|
|
12301
|
+
const MAX_MEMORY_INDEX = 0xffff_ffff;
|
|
12302
|
+
const MEMORY_SIZE = MAX_MEMORY_INDEX + 1;
|
|
12303
|
+
const PAGE_SIZE_SHIFT$1 = 12;
|
|
12304
|
+
function getPageStartAddress(address) {
|
|
12305
|
+
return tryAsU32(((address >>> PAGE_SIZE_SHIFT$1) << PAGE_SIZE_SHIFT$1) >>> 0);
|
|
12306
|
+
}
|
|
12307
|
+
|
|
12308
|
+
const NO_OF_REGISTERS$1 = 13;
|
|
12309
|
+
const REGISTER_BYTE_SIZE = 8;
|
|
12310
|
+
|
|
12276
12311
|
/**
|
|
12277
|
-
*
|
|
12312
|
+
* Result codes for the PVM execution.
|
|
12278
12313
|
*
|
|
12279
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
12314
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/2e43002e4300?v=0.7.2
|
|
12280
12315
|
*/
|
|
12281
12316
|
var Status;
|
|
12282
12317
|
(function (Status) {
|
|
12318
|
+
/** Continue */
|
|
12283
12319
|
Status[Status["OK"] = 255] = "OK";
|
|
12320
|
+
/** Finished */
|
|
12284
12321
|
Status[Status["HALT"] = 0] = "HALT";
|
|
12322
|
+
/** Panic */
|
|
12285
12323
|
Status[Status["PANIC"] = 1] = "PANIC";
|
|
12324
|
+
/** Page-fault */
|
|
12286
12325
|
Status[Status["FAULT"] = 2] = "FAULT";
|
|
12326
|
+
/** Host-call */
|
|
12287
12327
|
Status[Status["HOST"] = 3] = "HOST";
|
|
12328
|
+
/** Out of gas */
|
|
12288
12329
|
Status[Status["OOG"] = 4] = "OOG";
|
|
12289
12330
|
})(Status || (Status = {}));
|
|
12290
12331
|
|
|
@@ -12681,6 +12722,9 @@ function writeServiceIdAsLeBytes(serviceId, destination) {
|
|
|
12681
12722
|
function clampU64ToU32(value) {
|
|
12682
12723
|
return value > MAX_U32_BIG_INT ? MAX_U32 : tryAsU32(Number(value));
|
|
12683
12724
|
}
|
|
12725
|
+
function emptyRegistersBuffer() {
|
|
12726
|
+
return safeAllocUint8Array(NO_OF_REGISTERS$1 * REGISTER_BYTE_SIZE);
|
|
12727
|
+
}
|
|
12684
12728
|
|
|
12685
12729
|
var index$9 = /*#__PURE__*/Object.freeze({
|
|
12686
12730
|
__proto__: null,
|
|
@@ -12709,6 +12753,7 @@ var index$9 = /*#__PURE__*/Object.freeze({
|
|
|
12709
12753
|
get UpdatePrivilegesError () { return UpdatePrivilegesError; },
|
|
12710
12754
|
get ZeroVoidError () { return ZeroVoidError; },
|
|
12711
12755
|
clampU64ToU32: clampU64ToU32,
|
|
12756
|
+
emptyRegistersBuffer: emptyRegistersBuffer,
|
|
12712
12757
|
getServiceId: getServiceId,
|
|
12713
12758
|
getServiceIdOrCurrent: getServiceIdOrCurrent,
|
|
12714
12759
|
slotsToPreimageStatus: slotsToPreimageStatus,
|
|
@@ -12840,8 +12885,7 @@ var index$8 = /*#__PURE__*/Object.freeze({
|
|
|
12840
12885
|
MerkleMountainRange: MerkleMountainRange
|
|
12841
12886
|
});
|
|
12842
12887
|
|
|
12843
|
-
const
|
|
12844
|
-
const REGISTER_SIZE_SHIFT = 3;
|
|
12888
|
+
const REGISTER_SIZE_SHIFT = 3; // x << 3 === x * 8
|
|
12845
12889
|
const tryAsRegisterIndex = (index) => {
|
|
12846
12890
|
check `${index >= 0 && index < NO_OF_REGISTERS$1} Incorrect register index: ${index}!`;
|
|
12847
12891
|
return asOpaqueType(index);
|
|
@@ -12856,6 +12900,13 @@ class Registers {
|
|
|
12856
12900
|
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
12857
12901
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
12858
12902
|
}
|
|
12903
|
+
getAllEncoded() {
|
|
12904
|
+
return this.bytes;
|
|
12905
|
+
}
|
|
12906
|
+
setAllEncoded(bytes) {
|
|
12907
|
+
check `${bytes.length === this.bytes.length} Incorrect size of input registers. Got: ${bytes.length}, need: ${this.bytes.length}`;
|
|
12908
|
+
this.bytes.set(bytes, 0);
|
|
12909
|
+
}
|
|
12859
12910
|
static fromBytes(bytes) {
|
|
12860
12911
|
check `${bytes.length === NO_OF_REGISTERS$1 << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
12861
12912
|
return new Registers(bytes);
|
|
@@ -12864,9 +12915,6 @@ class Registers {
|
|
|
12864
12915
|
const offset = index << REGISTER_SIZE_SHIFT;
|
|
12865
12916
|
return this.bytes.subarray(offset, offset + len);
|
|
12866
12917
|
}
|
|
12867
|
-
getAllBytesAsLittleEndian() {
|
|
12868
|
-
return this.bytes;
|
|
12869
|
-
}
|
|
12870
12918
|
copyFrom(regs) {
|
|
12871
12919
|
const array = regs instanceof BigUint64Array ? regs : regs.asUnsigned;
|
|
12872
12920
|
this.asUnsigned.set(array);
|
|
@@ -12938,20 +12986,222 @@ function traceRegisters(...regs) {
|
|
|
12938
12986
|
return regs.map(tryAsRegisterIndex);
|
|
12939
12987
|
}
|
|
12940
12988
|
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12989
|
+
class HostCallMemory {
|
|
12990
|
+
memory;
|
|
12991
|
+
constructor(memory) {
|
|
12992
|
+
this.memory = memory;
|
|
12993
|
+
}
|
|
12994
|
+
/**
|
|
12995
|
+
* Save some bytes into memory under given address.
|
|
12996
|
+
*
|
|
12997
|
+
* NOTE: Given address is U64 (pure register value),
|
|
12998
|
+
* but we use only lower 32-bits.
|
|
12999
|
+
*/
|
|
13000
|
+
storeFrom(regAddress, bytes) {
|
|
13001
|
+
if (bytes.length === 0) {
|
|
13002
|
+
return Result$1.ok(OK);
|
|
13003
|
+
}
|
|
13004
|
+
// NOTE: We always take lower 32 bits from register value.
|
|
13005
|
+
//
|
|
13006
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
13007
|
+
const address = tryAsU32(Number(regAddress & 0xffffffffn));
|
|
13008
|
+
return this.memory.store(address, bytes);
|
|
13009
|
+
}
|
|
13010
|
+
/**
|
|
13011
|
+
* Read some bytes from memory under given address.
|
|
13012
|
+
*
|
|
13013
|
+
* NOTE: Given address is U64 (pure register value),
|
|
13014
|
+
* but we use only lower 32-bits.
|
|
13015
|
+
*/
|
|
13016
|
+
loadInto(output, regAddress) {
|
|
13017
|
+
if (output.length === 0) {
|
|
13018
|
+
return Result$1.ok(OK);
|
|
13019
|
+
}
|
|
13020
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
13021
|
+
//
|
|
13022
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
13023
|
+
const address = tryAsU32(Number(regAddress & 0xffffffffn));
|
|
13024
|
+
return this.memory.read(address, output);
|
|
13025
|
+
}
|
|
13026
|
+
}
|
|
13027
|
+
|
|
13028
|
+
class HostCallRegisters {
|
|
13029
|
+
bytes;
|
|
13030
|
+
registers;
|
|
13031
|
+
constructor(bytes) {
|
|
13032
|
+
this.bytes = bytes;
|
|
13033
|
+
this.registers = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
13034
|
+
}
|
|
13035
|
+
/** Get U64 register value. */
|
|
13036
|
+
get(registerIndex) {
|
|
13037
|
+
return tryAsU64(this.registers.getBigUint64(registerIndex * REGISTER_BYTE_SIZE, true));
|
|
13038
|
+
}
|
|
13039
|
+
/** Set U64 register value. */
|
|
13040
|
+
set(registerIndex, value) {
|
|
13041
|
+
this.registers.setBigUint64(registerIndex * REGISTER_BYTE_SIZE, value, true);
|
|
13042
|
+
}
|
|
13043
|
+
/** Get all registers encoded into little-endian bytes. */
|
|
13044
|
+
getEncoded() {
|
|
13045
|
+
return this.bytes;
|
|
13046
|
+
}
|
|
13047
|
+
}
|
|
13048
|
+
|
|
13049
|
+
class ReturnValue {
|
|
13050
|
+
consumedGas;
|
|
13051
|
+
status;
|
|
13052
|
+
memorySlice;
|
|
13053
|
+
constructor(consumedGas, status, memorySlice) {
|
|
13054
|
+
this.consumedGas = consumedGas;
|
|
13055
|
+
this.status = status;
|
|
13056
|
+
this.memorySlice = memorySlice;
|
|
13057
|
+
check `
|
|
13058
|
+
${(status === null && memorySlice !== null) || (status !== null && memorySlice === null)}
|
|
13059
|
+
'status' and 'memorySlice' must not both be null or both be non-null — exactly one must be provided
|
|
13060
|
+
`;
|
|
13061
|
+
}
|
|
13062
|
+
static fromStatus(consumedGas, status) {
|
|
13063
|
+
return new ReturnValue(consumedGas, status, null);
|
|
13064
|
+
}
|
|
13065
|
+
static fromMemorySlice(consumedGas, memorySlice) {
|
|
13066
|
+
return new ReturnValue(consumedGas, null, memorySlice);
|
|
13067
|
+
}
|
|
13068
|
+
hasMemorySlice() {
|
|
13069
|
+
return this.memorySlice instanceof Uint8Array && this.status === null;
|
|
13070
|
+
}
|
|
13071
|
+
hasStatus() {
|
|
13072
|
+
return !this.hasMemorySlice();
|
|
13073
|
+
}
|
|
13074
|
+
}
|
|
13075
|
+
class HostCalls {
|
|
13076
|
+
pvmInstanceManager;
|
|
13077
|
+
hostCalls;
|
|
13078
|
+
constructor(pvmInstanceManager, hostCalls) {
|
|
13079
|
+
this.pvmInstanceManager = pvmInstanceManager;
|
|
13080
|
+
this.hostCalls = hostCalls;
|
|
13081
|
+
}
|
|
13082
|
+
getReturnValue(status, pvmInstance) {
|
|
13083
|
+
const gasConsumed = pvmInstance.gas.used();
|
|
13084
|
+
if (status === Status.OOG) {
|
|
13085
|
+
return ReturnValue.fromStatus(gasConsumed, status);
|
|
13086
|
+
}
|
|
13087
|
+
if (status === Status.HALT) {
|
|
13088
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
13089
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
13090
|
+
const address = regs.get(7);
|
|
13091
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
13092
|
+
const length = Number(regs.get(8) & 0xffffffffn);
|
|
13093
|
+
const result = safeAllocUint8Array(length);
|
|
13094
|
+
const loadResult = memory.loadInto(result, address);
|
|
13095
|
+
if (loadResult.isError) {
|
|
13096
|
+
return ReturnValue.fromMemorySlice(gasConsumed, new Uint8Array());
|
|
13097
|
+
}
|
|
13098
|
+
return ReturnValue.fromMemorySlice(gasConsumed, result);
|
|
13099
|
+
}
|
|
13100
|
+
return ReturnValue.fromStatus(gasConsumed, Status.PANIC);
|
|
13101
|
+
}
|
|
13102
|
+
async execute(pvmInstance) {
|
|
13103
|
+
pvmInstance.runProgram();
|
|
13104
|
+
for (;;) {
|
|
13105
|
+
let status = pvmInstance.getStatus();
|
|
13106
|
+
if (status !== Status.HOST) {
|
|
13107
|
+
return this.getReturnValue(status, pvmInstance);
|
|
13108
|
+
}
|
|
13109
|
+
check `
|
|
13110
|
+
${pvmInstance.getExitParam() !== null}
|
|
13111
|
+
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
13112
|
+
`;
|
|
13113
|
+
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
13114
|
+
const gas = pvmInstance.gas;
|
|
13115
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
13116
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
13117
|
+
const index = tryAsHostCallIndex(hostCallIndex);
|
|
13118
|
+
const hostCall = this.hostCalls.get(index);
|
|
13119
|
+
const gasBefore = gas.get();
|
|
13120
|
+
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
13121
|
+
const basicGasCost = typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
13122
|
+
const underflow = gas.sub(basicGasCost);
|
|
13123
|
+
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
13124
|
+
if (underflow) {
|
|
13125
|
+
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
13126
|
+
return ReturnValue.fromStatus(gas.used(), Status.OOG);
|
|
13127
|
+
}
|
|
13128
|
+
this.hostCalls.traceHostCall(`${pcLog} Invoking`, index, hostCall, regs, gasBefore);
|
|
13129
|
+
const result = await hostCall.execute(gas, regs, memory);
|
|
13130
|
+
this.hostCalls.traceHostCall(result === undefined ? `${pcLog} Result` : `${pcLog} Status(${PvmExecution[result]})`, index, hostCall, regs, gas.get());
|
|
13131
|
+
pvmInstance.registers.setAllEncoded(regs.getEncoded());
|
|
13132
|
+
if (result === PvmExecution.Halt) {
|
|
13133
|
+
status = Status.HALT;
|
|
13134
|
+
return this.getReturnValue(status, pvmInstance);
|
|
13135
|
+
}
|
|
13136
|
+
if (result === PvmExecution.Panic) {
|
|
13137
|
+
status = Status.PANIC;
|
|
13138
|
+
return this.getReturnValue(status, pvmInstance);
|
|
13139
|
+
}
|
|
13140
|
+
if (result === PvmExecution.OOG) {
|
|
13141
|
+
status = Status.OOG;
|
|
13142
|
+
return this.getReturnValue(status, pvmInstance);
|
|
13143
|
+
}
|
|
13144
|
+
if (result === undefined) {
|
|
13145
|
+
pvmInstance.runProgram();
|
|
13146
|
+
status = pvmInstance.getStatus();
|
|
13147
|
+
continue;
|
|
13148
|
+
}
|
|
13149
|
+
assertNever(result);
|
|
13150
|
+
}
|
|
13151
|
+
}
|
|
13152
|
+
async runProgram(program, args, initialPc, initialGas) {
|
|
13153
|
+
const pvmInstance = await this.pvmInstanceManager.getInstance();
|
|
13154
|
+
pvmInstance.resetJam(program, args, initialPc, initialGas);
|
|
13155
|
+
try {
|
|
13156
|
+
return await this.execute(pvmInstance);
|
|
13157
|
+
}
|
|
13158
|
+
finally {
|
|
13159
|
+
this.pvmInstanceManager.releaseInstance(pvmInstance);
|
|
13160
|
+
}
|
|
13161
|
+
}
|
|
13162
|
+
}
|
|
13163
|
+
|
|
13164
|
+
const logger$3 = Logger.new(undefined, "host-calls-pvm");
|
|
13165
|
+
/** Container for all available host calls. */
|
|
13166
|
+
class HostCallsManager {
|
|
13167
|
+
hostCalls = new Map();
|
|
13168
|
+
missing;
|
|
13169
|
+
constructor({ missing, handlers = [], }) {
|
|
13170
|
+
this.missing = missing;
|
|
13171
|
+
for (const handler of handlers) {
|
|
13172
|
+
check `${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
13173
|
+
this.hostCalls.set(handler.index, handler);
|
|
13174
|
+
}
|
|
13175
|
+
}
|
|
13176
|
+
/** Get a host call by index. */
|
|
13177
|
+
get(hostCallIndex) {
|
|
13178
|
+
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
13179
|
+
}
|
|
13180
|
+
traceHostCall(context, hostCallIndex, hostCallHandler, registers, gas) {
|
|
13181
|
+
const { currentServiceId } = hostCallHandler;
|
|
13182
|
+
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
13183
|
+
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
13184
|
+
const registerValues = hostCallHandler.tracedRegisters
|
|
13185
|
+
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)])
|
|
13186
|
+
.filter((v) => v[1] !== 0n)
|
|
13187
|
+
.map(([idx, value]) => {
|
|
13188
|
+
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
13189
|
+
})
|
|
13190
|
+
.join(", ");
|
|
13191
|
+
logger$3.insane `[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
13192
|
+
}
|
|
13193
|
+
}
|
|
13194
|
+
|
|
12947
13195
|
/** Create a new gas counter instance depending on the gas value. */
|
|
12948
13196
|
function gasCounter(gas) {
|
|
12949
13197
|
return new GasCounterU64(tryAsU64(gas));
|
|
12950
13198
|
}
|
|
12951
13199
|
class GasCounterU64 {
|
|
12952
13200
|
gas;
|
|
13201
|
+
initialGas;
|
|
12953
13202
|
constructor(gas) {
|
|
12954
13203
|
this.gas = gas;
|
|
13204
|
+
this.initialGas = tryAsGas(gas);
|
|
12955
13205
|
}
|
|
12956
13206
|
set(g) {
|
|
12957
13207
|
this.gas = tryAsU64(g);
|
|
@@ -12968,1593 +13218,1788 @@ class GasCounterU64 {
|
|
|
12968
13218
|
this.gas = tryAsU64(0n);
|
|
12969
13219
|
return true;
|
|
12970
13220
|
}
|
|
13221
|
+
used() {
|
|
13222
|
+
const gasConsumed = tryAsU64(this.initialGas) - this.gas;
|
|
13223
|
+
// In we have less than zero left we assume that all gas has been consumed.
|
|
13224
|
+
if (gasConsumed < 0) {
|
|
13225
|
+
return this.initialGas;
|
|
13226
|
+
}
|
|
13227
|
+
return tryAsGas(gasConsumed);
|
|
13228
|
+
}
|
|
12971
13229
|
}
|
|
12972
13230
|
|
|
13231
|
+
const tryAsMemoryIndex = (index) => {
|
|
13232
|
+
check `${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
13233
|
+
return asOpaqueType(index);
|
|
13234
|
+
};
|
|
13235
|
+
const tryAsSbrkIndex = (index) => {
|
|
13236
|
+
check `${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
13237
|
+
return asOpaqueType(index);
|
|
13238
|
+
};
|
|
13239
|
+
|
|
13240
|
+
const PAGE_SIZE_SHIFT = 12;
|
|
13241
|
+
// PAGE_SIZE has to be a power of 2
|
|
13242
|
+
const PAGE_SIZE$1 = 1 << PAGE_SIZE_SHIFT;
|
|
13243
|
+
const MIN_ALLOCATION_SHIFT = (() => {
|
|
13244
|
+
const MIN_ALLOCATION_SHIFT = 7;
|
|
13245
|
+
check `${MIN_ALLOCATION_SHIFT < PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
13246
|
+
return MIN_ALLOCATION_SHIFT;
|
|
13247
|
+
})();
|
|
13248
|
+
const MIN_ALLOCATION_LENGTH = PAGE_SIZE$1 >> MIN_ALLOCATION_SHIFT;
|
|
13249
|
+
const LAST_PAGE_NUMBER = (MEMORY_SIZE - PAGE_SIZE$1) / PAGE_SIZE$1;
|
|
13250
|
+
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
13251
|
+
const RESERVED_NUMBER_OF_PAGES = 16;
|
|
13252
|
+
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
13253
|
+
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE / PAGE_SIZE$1;
|
|
13254
|
+
|
|
13255
|
+
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
13256
|
+
const tryAsPageIndex = (index) => {
|
|
13257
|
+
check `${index >= 0 && index < PAGE_SIZE$1}, Incorect page index: ${index}!`;
|
|
13258
|
+
return asOpaqueType(index);
|
|
13259
|
+
};
|
|
13260
|
+
/** Ensure that given `index` represents an index of one of the pages. */
|
|
13261
|
+
const tryAsPageNumber = (index) => {
|
|
13262
|
+
check `${index >= 0 && index <= LAST_PAGE_NUMBER}, Incorect page number: ${index}!`;
|
|
13263
|
+
return asOpaqueType(index);
|
|
13264
|
+
};
|
|
12973
13265
|
/**
|
|
12974
|
-
*
|
|
12975
|
-
*/
|
|
12976
|
-
const MAX_INSTRUCTION_DISTANCE = 25;
|
|
12977
|
-
/**
|
|
12978
|
-
* Mask class is an implementation of skip function defined in GP.
|
|
13266
|
+
* Get the next page number and wrap the result if it is bigger than LAST_PAGE_NUMBER
|
|
12979
13267
|
*
|
|
12980
|
-
*
|
|
13268
|
+
* GP references:
|
|
13269
|
+
* 1. The modulo subscription operator is used in all load/store instructions, for example:
|
|
13270
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/25af0125af01
|
|
13271
|
+
*
|
|
13272
|
+
* 2. Here is the definition of the modulo subscription operator:
|
|
13273
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/073a00073a00
|
|
12981
13274
|
*/
|
|
12982
|
-
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
|
|
13275
|
+
function getNextPageNumber(pageNumber) {
|
|
13276
|
+
const newPageNumber = pageNumber === LAST_PAGE_NUMBER ? 0 : pageNumber + 1;
|
|
13277
|
+
return tryAsPageNumber(newPageNumber);
|
|
13278
|
+
}
|
|
13279
|
+
|
|
13280
|
+
function alignToPageSize$1(length) {
|
|
13281
|
+
return PAGE_SIZE$1 * Math.ceil(length / PAGE_SIZE$1);
|
|
13282
|
+
}
|
|
13283
|
+
function getPageNumber(address) {
|
|
13284
|
+
return tryAsPageNumber(address >>> PAGE_SIZE_SHIFT);
|
|
13285
|
+
}
|
|
13286
|
+
function getStartPageIndex(address) {
|
|
13287
|
+
return tryAsMemoryIndex((address >>> PAGE_SIZE_SHIFT) << PAGE_SIZE_SHIFT);
|
|
13288
|
+
}
|
|
13289
|
+
function getStartPageIndexFromPageNumber(pageNumber) {
|
|
13290
|
+
// >>> 0 is needed to avoid changing sign of the number
|
|
13291
|
+
return tryAsMemoryIndex((pageNumber << PAGE_SIZE_SHIFT) >>> 0);
|
|
13292
|
+
}
|
|
13293
|
+
|
|
13294
|
+
class PageFault {
|
|
13295
|
+
address;
|
|
13296
|
+
isAccessFault;
|
|
13297
|
+
constructor(address, isAccessFault = true) {
|
|
13298
|
+
this.address = address;
|
|
13299
|
+
this.isAccessFault = isAccessFault;
|
|
12997
13300
|
}
|
|
12998
|
-
|
|
12999
|
-
|
|
13301
|
+
static fromPageNumber(maybePageNumber, isAccessFault = false) {
|
|
13302
|
+
const pageNumber = tryAsPageNumber(maybePageNumber);
|
|
13303
|
+
const startPageIndex = getStartPageIndexFromPageNumber(pageNumber);
|
|
13304
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
13000
13305
|
}
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13306
|
+
static fromMemoryIndex(maybeMemoryIndex, isAccessFault = false) {
|
|
13307
|
+
const memoryIndex = tryAsMemoryIndex(maybeMemoryIndex % MEMORY_SIZE);
|
|
13308
|
+
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
13309
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
13004
13310
|
}
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
if (mask.isSet(i)) {
|
|
13010
|
-
lastInstructionOffset = 0;
|
|
13011
|
-
}
|
|
13012
|
-
else {
|
|
13013
|
-
lastInstructionOffset++;
|
|
13014
|
-
}
|
|
13015
|
-
table[i] = lastInstructionOffset;
|
|
13016
|
-
}
|
|
13017
|
-
return table;
|
|
13311
|
+
}
|
|
13312
|
+
class IncorrectSbrkIndex extends Error {
|
|
13313
|
+
constructor() {
|
|
13314
|
+
super("Space between sbrk index and max heap index should be empty!");
|
|
13018
13315
|
}
|
|
13019
|
-
|
|
13020
|
-
|
|
13316
|
+
}
|
|
13317
|
+
class FinalizedBuilderModification extends Error {
|
|
13318
|
+
constructor() {
|
|
13319
|
+
super("MemoryBuilder was finalized and cannot be changed!");
|
|
13021
13320
|
}
|
|
13022
13321
|
}
|
|
13023
|
-
|
|
13024
|
-
var ArgumentType;
|
|
13025
|
-
(function (ArgumentType) {
|
|
13026
|
-
ArgumentType[ArgumentType["NO_ARGUMENTS"] = 0] = "NO_ARGUMENTS";
|
|
13027
|
-
ArgumentType[ArgumentType["ONE_IMMEDIATE"] = 1] = "ONE_IMMEDIATE";
|
|
13028
|
-
ArgumentType[ArgumentType["TWO_IMMEDIATES"] = 2] = "TWO_IMMEDIATES";
|
|
13029
|
-
ArgumentType[ArgumentType["ONE_OFFSET"] = 3] = "ONE_OFFSET";
|
|
13030
|
-
ArgumentType[ArgumentType["ONE_REGISTER_ONE_IMMEDIATE"] = 4] = "ONE_REGISTER_ONE_IMMEDIATE";
|
|
13031
|
-
ArgumentType[ArgumentType["ONE_REGISTER_TWO_IMMEDIATES"] = 5] = "ONE_REGISTER_TWO_IMMEDIATES";
|
|
13032
|
-
ArgumentType[ArgumentType["ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET"] = 6] = "ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET";
|
|
13033
|
-
ArgumentType[ArgumentType["TWO_REGISTERS"] = 7] = "TWO_REGISTERS";
|
|
13034
|
-
ArgumentType[ArgumentType["TWO_REGISTERS_ONE_IMMEDIATE"] = 8] = "TWO_REGISTERS_ONE_IMMEDIATE";
|
|
13035
|
-
ArgumentType[ArgumentType["TWO_REGISTERS_ONE_OFFSET"] = 9] = "TWO_REGISTERS_ONE_OFFSET";
|
|
13036
|
-
ArgumentType[ArgumentType["TWO_REGISTERS_TWO_IMMEDIATES"] = 10] = "TWO_REGISTERS_TWO_IMMEDIATES";
|
|
13037
|
-
ArgumentType[ArgumentType["THREE_REGISTERS"] = 11] = "THREE_REGISTERS";
|
|
13038
|
-
ArgumentType[ArgumentType["ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE"] = 12] = "ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE";
|
|
13039
|
-
})(ArgumentType || (ArgumentType = {}));
|
|
13040
|
-
|
|
13041
|
-
const BUFFER_SIZE = 8;
|
|
13042
|
-
const IMMEDIATE_SIZE$1 = 4;
|
|
13043
|
-
const U32_INDEX = 0;
|
|
13044
|
-
const U64_INDEX = 0;
|
|
13045
|
-
class ImmediateDecoder {
|
|
13046
|
-
u32;
|
|
13047
|
-
i32;
|
|
13048
|
-
u64;
|
|
13049
|
-
i64;
|
|
13050
|
-
view;
|
|
13051
|
-
bytes;
|
|
13322
|
+
class ReservedMemoryFault extends Error {
|
|
13052
13323
|
constructor() {
|
|
13053
|
-
|
|
13054
|
-
this.u32 = new Uint32Array(buffer);
|
|
13055
|
-
this.i32 = new Int32Array(buffer);
|
|
13056
|
-
this.u64 = new BigUint64Array(buffer);
|
|
13057
|
-
this.i64 = new BigInt64Array(buffer);
|
|
13058
|
-
this.view = new DataView(buffer);
|
|
13059
|
-
this.bytes = new Uint8Array(buffer);
|
|
13324
|
+
super("You are trying to access reserved memory!");
|
|
13060
13325
|
}
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
|
|
13068
|
-
|
|
13069
|
-
|
|
13070
|
-
this.view.setUint8(i, prefix);
|
|
13071
|
-
}
|
|
13326
|
+
}
|
|
13327
|
+
class PageNotExist extends Error {
|
|
13328
|
+
constructor() {
|
|
13329
|
+
super("You try to fill data on memory page that does not exist!");
|
|
13330
|
+
}
|
|
13331
|
+
}
|
|
13332
|
+
class OutOfMemory extends Error {
|
|
13333
|
+
constructor() {
|
|
13334
|
+
super("Out of memory");
|
|
13072
13335
|
}
|
|
13336
|
+
}
|
|
13337
|
+
|
|
13338
|
+
/**
|
|
13339
|
+
* A representation of open-ended range of consecutive indices in memory,
|
|
13340
|
+
* possibly empty or wrapping around.
|
|
13341
|
+
*
|
|
13342
|
+
* `[start, start + length)`
|
|
13343
|
+
*/
|
|
13344
|
+
class MemoryRange {
|
|
13345
|
+
start;
|
|
13346
|
+
length;
|
|
13073
13347
|
/**
|
|
13074
|
-
*
|
|
13348
|
+
* Exclusive end index of the range.
|
|
13349
|
+
*
|
|
13350
|
+
* NOTE: The index may be wrapped around and smaller than `start`!
|
|
13075
13351
|
*/
|
|
13076
|
-
|
|
13077
|
-
return this.u32[U32_INDEX];
|
|
13078
|
-
}
|
|
13352
|
+
end;
|
|
13079
13353
|
/**
|
|
13080
|
-
*
|
|
13354
|
+
* Inclusive last index of the range (present unless the range is empty).
|
|
13355
|
+
*
|
|
13356
|
+
* NOTE: the index may be wrapped around and smaller than `start`!
|
|
13081
13357
|
*/
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
|
|
13086
|
-
|
|
13358
|
+
lastIndex = null;
|
|
13359
|
+
constructor(start, length) {
|
|
13360
|
+
this.start = start;
|
|
13361
|
+
this.length = length;
|
|
13362
|
+
this.end = tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
13363
|
+
if (length > 0) {
|
|
13364
|
+
this.lastIndex = tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
13365
|
+
}
|
|
13087
13366
|
}
|
|
13088
|
-
|
|
13089
|
-
|
|
13367
|
+
/** Creates a memory range from given starting point and length */
|
|
13368
|
+
static fromStartAndLength(start, length) {
|
|
13369
|
+
if (!Number.isInteger(length) || length < 0 || length > MEMORY_SIZE) {
|
|
13370
|
+
throw new TypeError(`length must be a non-negative integer and less than ${MEMORY_SIZE}, got ${length}`);
|
|
13371
|
+
}
|
|
13372
|
+
return new MemoryRange(start, length);
|
|
13090
13373
|
}
|
|
13091
|
-
|
|
13092
|
-
|
|
13374
|
+
/** Checks if a range is empty (`length === 0`) */
|
|
13375
|
+
isEmpty() {
|
|
13376
|
+
return this.length === 0;
|
|
13093
13377
|
}
|
|
13094
|
-
|
|
13095
|
-
|
|
13378
|
+
/** Returns true if the range is wrapped (`start` >= `end`) and is not empty */
|
|
13379
|
+
isWrapped() {
|
|
13380
|
+
return this.start >= this.end && !this.isEmpty();
|
|
13096
13381
|
}
|
|
13097
|
-
|
|
13098
|
-
|
|
13382
|
+
/** Checks if given memory address is within the range */
|
|
13383
|
+
isInRange(address) {
|
|
13384
|
+
if (this.isWrapped()) {
|
|
13385
|
+
return address >= this.start || address < this.end;
|
|
13386
|
+
}
|
|
13387
|
+
return address >= this.start && address < this.end;
|
|
13099
13388
|
}
|
|
13100
|
-
|
|
13101
|
-
|
|
13389
|
+
/** Checks if this range overlaps with another range */
|
|
13390
|
+
overlapsWith(other) {
|
|
13391
|
+
if (this.lastIndex === null || other.lastIndex === null) {
|
|
13392
|
+
return false;
|
|
13393
|
+
}
|
|
13394
|
+
return (this.isInRange(other.start) ||
|
|
13395
|
+
this.isInRange(other.lastIndex) ||
|
|
13396
|
+
other.isInRange(this.start) ||
|
|
13397
|
+
other.isInRange(this.lastIndex));
|
|
13102
13398
|
}
|
|
13103
13399
|
}
|
|
13400
|
+
/**
|
|
13401
|
+
* The first 16 pages of memory are reserved.
|
|
13402
|
+
*
|
|
13403
|
+
* https://graypaper.fluffylabs.dev/#/cc517d7/24d00024d000?v=0.6.5
|
|
13404
|
+
*
|
|
13405
|
+
* it should be in `memory-consts` but it cannot be there because of circular dependency
|
|
13406
|
+
*/
|
|
13407
|
+
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(tryAsMemoryIndex(0), RESERVED_NUMBER_OF_PAGES * PAGE_SIZE$1);
|
|
13104
13408
|
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
|
|
13108
|
-
|
|
13109
|
-
|
|
13110
|
-
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13409
|
+
/**
|
|
13410
|
+
* A half-open range of memory pages. Similarly to [`MemoryRange`], can be empty
|
|
13411
|
+
* or wrapped around the memory.
|
|
13412
|
+
*/
|
|
13413
|
+
class PageRange {
|
|
13414
|
+
start;
|
|
13415
|
+
length;
|
|
13416
|
+
/**
|
|
13417
|
+
* Exclusive end of the page range.
|
|
13418
|
+
*
|
|
13419
|
+
* NOTE: it may be smaller than `start` in case the range is wrapped.
|
|
13420
|
+
*/
|
|
13421
|
+
end;
|
|
13422
|
+
constructor(start, length) {
|
|
13423
|
+
this.start = start;
|
|
13424
|
+
this.length = length;
|
|
13425
|
+
this.end = tryAsPageNumber((this.start + this.length) % MAX_NUMBER_OF_PAGES);
|
|
13117
13426
|
}
|
|
13118
|
-
|
|
13119
|
-
|
|
13427
|
+
/**
|
|
13428
|
+
* Creates range of pages that includes all indices in a given memory range.
|
|
13429
|
+
*
|
|
13430
|
+
* Example: For memory range `[PAGE_SIZE, MEMORY_SIZE - PAGE_SIZE)`
|
|
13431
|
+
* we will get `[1, MAX_NUMBER_OF_PAGES - 1)` page range.
|
|
13432
|
+
*/
|
|
13433
|
+
static fromMemoryRange(range) {
|
|
13434
|
+
const startPage = getPageNumber(range.start);
|
|
13435
|
+
if (range.isEmpty()) {
|
|
13436
|
+
return new PageRange(startPage, 0);
|
|
13437
|
+
}
|
|
13438
|
+
// lastIndex is not null because we just ensured that the range is not empty
|
|
13439
|
+
const pageWithLastIndex = getPageNumber(range.lastIndex ?? range.end);
|
|
13440
|
+
const endPage = getNextPageNumber(pageWithLastIndex);
|
|
13441
|
+
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length > PAGE_SIZE$1) {
|
|
13442
|
+
// full range
|
|
13443
|
+
return new PageRange(startPage, MAX_NUMBER_OF_PAGES);
|
|
13444
|
+
}
|
|
13445
|
+
const length = startPage < endPage ? endPage - startPage : MAX_NUMBER_OF_PAGES - startPage + endPage;
|
|
13446
|
+
return PageRange.fromStartAndLength(startPage, length);
|
|
13120
13447
|
}
|
|
13121
|
-
|
|
13122
|
-
|
|
13448
|
+
/** Creates a page range from given starting point and length */
|
|
13449
|
+
static fromStartAndLength(start, length) {
|
|
13450
|
+
if (!Number.isInteger(length) || length < 0 || length > MAX_NUMBER_OF_PAGES) {
|
|
13451
|
+
throw new TypeError(`length must be a non-negative integer and less than ${MAX_NUMBER_OF_PAGES}, got ${length}`);
|
|
13452
|
+
}
|
|
13453
|
+
return new PageRange(start, length);
|
|
13123
13454
|
}
|
|
13124
|
-
|
|
13125
|
-
|
|
13455
|
+
/** Returns true if the page range is wrapped (`start` >= `end`) and is not empty */
|
|
13456
|
+
isWrapped() {
|
|
13457
|
+
return this.start >= this.end && !this.isEmpty();
|
|
13126
13458
|
}
|
|
13127
|
-
|
|
13128
|
-
|
|
13459
|
+
/** Checks if given page number is within the range */
|
|
13460
|
+
isInRange(page) {
|
|
13461
|
+
if (this.isWrapped()) {
|
|
13462
|
+
return page >= this.start || page < this.end;
|
|
13463
|
+
}
|
|
13464
|
+
return page >= this.start && page < this.end;
|
|
13129
13465
|
}
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
class ArgsDecoder {
|
|
13134
|
-
nibblesDecoder = new NibblesDecoder();
|
|
13135
|
-
offsetDecoder = new ImmediateDecoder();
|
|
13136
|
-
code = new Uint8Array();
|
|
13137
|
-
mask = Mask.empty();
|
|
13138
|
-
reset(code, mask) {
|
|
13139
|
-
this.code = code;
|
|
13140
|
-
this.mask = mask;
|
|
13466
|
+
/** Checks if a range is empty (`length === 0`) */
|
|
13467
|
+
isEmpty() {
|
|
13468
|
+
return this.length === 0;
|
|
13141
13469
|
}
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13145
|
-
switch (result.type) {
|
|
13146
|
-
case ArgumentType.NO_ARGUMENTS:
|
|
13147
|
-
break;
|
|
13148
|
-
case ArgumentType.ONE_IMMEDIATE: {
|
|
13149
|
-
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
13150
|
-
const argsStartIndex = pc + 1;
|
|
13151
|
-
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
13152
|
-
break;
|
|
13153
|
-
}
|
|
13154
|
-
case ArgumentType.THREE_REGISTERS: {
|
|
13155
|
-
const firstByte = this.code[pc + 1];
|
|
13156
|
-
const secondByte = this.code[pc + 2];
|
|
13157
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13158
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13159
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
13160
|
-
this.nibblesDecoder.setByte(secondByte);
|
|
13161
|
-
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13162
|
-
break;
|
|
13163
|
-
}
|
|
13164
|
-
case ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE: {
|
|
13165
|
-
const firstByte = this.code[pc + 1];
|
|
13166
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13167
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13168
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
13169
|
-
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
13170
|
-
const immediateStartIndex = pc + 2;
|
|
13171
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
13172
|
-
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
13173
|
-
break;
|
|
13174
|
-
}
|
|
13175
|
-
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET: {
|
|
13176
|
-
const firstByte = this.code[pc + 1];
|
|
13177
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13178
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13179
|
-
const immediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
13180
|
-
const immediateStartIndex = pc + 2;
|
|
13181
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
13182
|
-
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
13183
|
-
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2 - immediateLength));
|
|
13184
|
-
const offsetStartIndex = pc + 2 + immediateLength;
|
|
13185
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
13186
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
13187
|
-
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
13188
|
-
break;
|
|
13189
|
-
}
|
|
13190
|
-
case ArgumentType.TWO_REGISTERS_ONE_OFFSET: {
|
|
13191
|
-
const firstByte = this.code[pc + 1];
|
|
13192
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13193
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13194
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
13195
|
-
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
13196
|
-
const offsetStartIndex = pc + 2;
|
|
13197
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
13198
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
13199
|
-
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
13200
|
-
break;
|
|
13201
|
-
}
|
|
13202
|
-
case ArgumentType.TWO_REGISTERS: {
|
|
13203
|
-
const firstByte = this.code[pc + 1];
|
|
13204
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13205
|
-
result.firstRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
13206
|
-
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13207
|
-
break;
|
|
13208
|
-
}
|
|
13209
|
-
case ArgumentType.ONE_OFFSET: {
|
|
13210
|
-
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
13211
|
-
const offsetStartIndex = pc + 1;
|
|
13212
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
13213
|
-
const offsetBytes = this.code.subarray(offsetStartIndex, offsetEndIndex);
|
|
13214
|
-
this.offsetDecoder.setBytes(offsetBytes);
|
|
13215
|
-
const offsetValue = this.offsetDecoder.getSigned();
|
|
13216
|
-
result.nextPc = pc + offsetValue;
|
|
13217
|
-
break;
|
|
13218
|
-
}
|
|
13219
|
-
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE: {
|
|
13220
|
-
const firstByte = this.code[pc + 1];
|
|
13221
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13222
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13223
|
-
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
13224
|
-
const immediateStartIndex = pc + 2;
|
|
13225
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
13226
|
-
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
13227
|
-
result.immediateDecoder.setBytes(immediateBytes);
|
|
13228
|
-
break;
|
|
13229
|
-
}
|
|
13230
|
-
case ArgumentType.TWO_IMMEDIATES: {
|
|
13231
|
-
const firstByte = this.code[pc + 1];
|
|
13232
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13233
|
-
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
13234
|
-
const firstImmediateStartIndex = pc + 2;
|
|
13235
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
13236
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
13237
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
13238
|
-
const secondImmediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2 - firstImmediateLength));
|
|
13239
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
13240
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
13241
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
13242
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
13243
|
-
break;
|
|
13244
|
-
}
|
|
13245
|
-
case ArgumentType.ONE_REGISTER_TWO_IMMEDIATES: {
|
|
13246
|
-
const firstByte = this.code[pc + 1];
|
|
13247
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13248
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13249
|
-
const firstImmediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
13250
|
-
const firstImmediateStartIndex = pc + 2;
|
|
13251
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
13252
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
13253
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
13254
|
-
const secondImmediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2 - firstImmediateLength));
|
|
13255
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
13256
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
13257
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
13258
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
13259
|
-
break;
|
|
13260
|
-
}
|
|
13261
|
-
case ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES: {
|
|
13262
|
-
const firstByte = this.code[pc + 1];
|
|
13263
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13264
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13265
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
13266
|
-
const secondByte = this.code[pc + 2];
|
|
13267
|
-
this.nibblesDecoder.setByte(secondByte);
|
|
13268
|
-
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
13269
|
-
const firstImmediateStartIndex = pc + 3;
|
|
13270
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
13271
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
13272
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
13273
|
-
const secondImmediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 3 - firstImmediateLength));
|
|
13274
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
13275
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
13276
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
13277
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
13278
|
-
break;
|
|
13279
|
-
}
|
|
13280
|
-
case ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE: {
|
|
13281
|
-
const firstByte = this.code[pc + 1];
|
|
13282
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
13283
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
13284
|
-
const immediateStartIndex = pc + 2;
|
|
13285
|
-
const immediateEndIndex = immediateStartIndex + 8;
|
|
13286
|
-
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
13287
|
-
result.immediateDecoder.setBytes(immediateBytes);
|
|
13288
|
-
break;
|
|
13289
|
-
}
|
|
13470
|
+
*[Symbol.iterator]() {
|
|
13471
|
+
if (this.isEmpty()) {
|
|
13472
|
+
return;
|
|
13290
13473
|
}
|
|
13474
|
+
const end = this.end;
|
|
13475
|
+
let i = this.start;
|
|
13476
|
+
do {
|
|
13477
|
+
yield i;
|
|
13478
|
+
i = getNextPageNumber(i);
|
|
13479
|
+
} while (i !== end);
|
|
13291
13480
|
}
|
|
13292
13481
|
}
|
|
13293
13482
|
|
|
13294
|
-
|
|
13295
|
-
|
|
13296
|
-
|
|
13297
|
-
|
|
13298
|
-
constructor() {
|
|
13299
|
-
const buffer = new ArrayBuffer(IMMEDIATE_SIZE);
|
|
13300
|
-
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
13301
|
-
this.bytes = new Uint8Array(buffer);
|
|
13483
|
+
class MemoryPage {
|
|
13484
|
+
start;
|
|
13485
|
+
constructor(pageNumber) {
|
|
13486
|
+
this.start = getStartPageIndexFromPageNumber(pageNumber);
|
|
13302
13487
|
}
|
|
13303
|
-
|
|
13304
|
-
|
|
13305
|
-
|
|
13306
|
-
|
|
13307
|
-
|
|
13308
|
-
|
|
13309
|
-
|
|
13488
|
+
}
|
|
13489
|
+
|
|
13490
|
+
class ReadablePage extends MemoryPage {
|
|
13491
|
+
data;
|
|
13492
|
+
constructor(pageNumber, data) {
|
|
13493
|
+
super(pageNumber);
|
|
13494
|
+
this.data = data;
|
|
13495
|
+
}
|
|
13496
|
+
loadInto(result, startIndex, length) {
|
|
13497
|
+
const endIndex = startIndex + length;
|
|
13498
|
+
if (endIndex > PAGE_SIZE$1) {
|
|
13499
|
+
return Result$1.error(PageFault.fromMemoryIndex(this.start + PAGE_SIZE$1), () => `Page fault: read beyond page boundary at ${this.start + PAGE_SIZE$1}`);
|
|
13310
13500
|
}
|
|
13501
|
+
const bytes = this.data.subarray(startIndex, endIndex);
|
|
13502
|
+
// we zero the bytes, since data might not yet be initialized at `endIndex`.
|
|
13503
|
+
result.fill(0, bytes.length, length);
|
|
13504
|
+
result.set(bytes);
|
|
13505
|
+
return Result$1.ok(OK);
|
|
13311
13506
|
}
|
|
13312
|
-
|
|
13313
|
-
return this.
|
|
13507
|
+
storeFrom(_address, _data) {
|
|
13508
|
+
return Result$1.error(PageFault.fromMemoryIndex(this.start, true), () => `Page fault: attempted to write to read-only page at ${this.start}`);
|
|
13314
13509
|
}
|
|
13315
|
-
|
|
13316
|
-
|
|
13510
|
+
setData(pageIndex, data) {
|
|
13511
|
+
this.data.set(data, pageIndex);
|
|
13512
|
+
}
|
|
13513
|
+
isWriteable() {
|
|
13514
|
+
return false;
|
|
13515
|
+
}
|
|
13516
|
+
getPageDump() {
|
|
13517
|
+
return this.data;
|
|
13317
13518
|
}
|
|
13318
13519
|
}
|
|
13319
13520
|
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
|
|
13336
|
-
|
|
13337
|
-
|
|
13338
|
-
|
|
13339
|
-
|
|
13340
|
-
|
|
13341
|
-
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
}
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
|
|
13355
|
-
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
}
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
|
|
13364
|
-
|
|
13365
|
-
|
|
13366
|
-
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE] = {
|
|
13367
|
-
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE,
|
|
13368
|
-
noOfBytesToSkip: 1,
|
|
13369
|
-
registerIndex: 0,
|
|
13370
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
13371
|
-
};
|
|
13372
|
-
results[ArgumentType.ONE_REGISTER_TWO_IMMEDIATES] = {
|
|
13373
|
-
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES,
|
|
13374
|
-
noOfBytesToSkip: 1,
|
|
13375
|
-
registerIndex: 0,
|
|
13376
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
13377
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
13378
|
-
};
|
|
13379
|
-
results[ArgumentType.ONE_OFFSET] = {
|
|
13380
|
-
type: ArgumentType.ONE_OFFSET,
|
|
13381
|
-
noOfBytesToSkip: 1,
|
|
13382
|
-
nextPc: 0,
|
|
13383
|
-
};
|
|
13384
|
-
results[ArgumentType.TWO_IMMEDIATES] = {
|
|
13385
|
-
type: ArgumentType.TWO_IMMEDIATES,
|
|
13386
|
-
noOfBytesToSkip: 1,
|
|
13387
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
13388
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
13389
|
-
};
|
|
13390
|
-
results[ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES] = {
|
|
13391
|
-
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES,
|
|
13392
|
-
noOfBytesToSkip: 1,
|
|
13393
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
13394
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
13395
|
-
firstRegisterIndex: 0,
|
|
13396
|
-
secondRegisterIndex: 0,
|
|
13397
|
-
};
|
|
13398
|
-
results[ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE] = {
|
|
13399
|
-
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE,
|
|
13400
|
-
noOfBytesToSkip: 9,
|
|
13401
|
-
registerIndex: 0,
|
|
13402
|
-
immediateDecoder: new ExtendedWitdthImmediateDecoder(),
|
|
13403
|
-
};
|
|
13404
|
-
return results;
|
|
13405
|
-
};
|
|
13521
|
+
class WriteablePage extends MemoryPage {
|
|
13522
|
+
buffer;
|
|
13523
|
+
view;
|
|
13524
|
+
constructor(pageNumber, initialData) {
|
|
13525
|
+
super(pageNumber);
|
|
13526
|
+
const dataLength = initialData?.length ?? 0;
|
|
13527
|
+
const initialPageLength = Math.min(PAGE_SIZE$1, Math.max(dataLength, MIN_ALLOCATION_LENGTH));
|
|
13528
|
+
this.buffer = new ArrayBuffer(initialPageLength, { maxByteLength: PAGE_SIZE$1 });
|
|
13529
|
+
this.view = new Uint8Array(this.buffer);
|
|
13530
|
+
if (initialData !== undefined) {
|
|
13531
|
+
this.view.set(initialData);
|
|
13532
|
+
}
|
|
13533
|
+
}
|
|
13534
|
+
loadInto(result, startIndex, length) {
|
|
13535
|
+
const endIndex = startIndex + length;
|
|
13536
|
+
if (endIndex > PAGE_SIZE$1) {
|
|
13537
|
+
return Result$1.error(PageFault.fromMemoryIndex(this.start + PAGE_SIZE$1), () => `Page fault: read beyond page boundary at ${this.start + PAGE_SIZE$1}`);
|
|
13538
|
+
}
|
|
13539
|
+
const bytes = this.view.subarray(startIndex, endIndex);
|
|
13540
|
+
// we zero the bytes, since the view might not yet be initialized at `endIndex`.
|
|
13541
|
+
result.fill(0, bytes.length, length);
|
|
13542
|
+
result.set(bytes);
|
|
13543
|
+
return Result$1.ok(OK);
|
|
13544
|
+
}
|
|
13545
|
+
storeFrom(startIndex, bytes) {
|
|
13546
|
+
if (this.buffer.byteLength < startIndex + bytes.length && this.buffer.byteLength < PAGE_SIZE$1) {
|
|
13547
|
+
const newLength = Math.min(PAGE_SIZE$1, Math.max(MIN_ALLOCATION_LENGTH, startIndex + bytes.length));
|
|
13548
|
+
this.buffer.resize(newLength);
|
|
13549
|
+
}
|
|
13550
|
+
this.view.set(bytes, startIndex);
|
|
13551
|
+
return Result$1.ok(OK);
|
|
13552
|
+
}
|
|
13553
|
+
setData(pageIndex, data) {
|
|
13554
|
+
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength < PAGE_SIZE$1) {
|
|
13555
|
+
const newLength = Math.min(PAGE_SIZE$1, Math.max(MIN_ALLOCATION_LENGTH, pageIndex + data.length));
|
|
13556
|
+
this.buffer.resize(newLength);
|
|
13557
|
+
}
|
|
13558
|
+
this.view.set(data, pageIndex);
|
|
13559
|
+
}
|
|
13560
|
+
isWriteable() {
|
|
13561
|
+
return true;
|
|
13562
|
+
}
|
|
13563
|
+
getPageDump() {
|
|
13564
|
+
return this.view;
|
|
13565
|
+
}
|
|
13566
|
+
}
|
|
13406
13567
|
|
|
13407
|
-
var
|
|
13408
|
-
(function (
|
|
13409
|
-
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
|
|
13419
|
-
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
|
|
13427
|
-
|
|
13428
|
-
|
|
13429
|
-
|
|
13430
|
-
|
|
13431
|
-
|
|
13432
|
-
|
|
13433
|
-
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13446
|
-
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
|
|
13513
|
-
|
|
13514
|
-
|
|
13515
|
-
Instruction[Instruction["SHLO_R_32"] = 198] = "SHLO_R_32";
|
|
13516
|
-
Instruction[Instruction["SHAR_R_32"] = 199] = "SHAR_R_32";
|
|
13517
|
-
Instruction[Instruction["ADD_64"] = 200] = "ADD_64";
|
|
13518
|
-
Instruction[Instruction["SUB_64"] = 201] = "SUB_64";
|
|
13519
|
-
Instruction[Instruction["MUL_64"] = 202] = "MUL_64";
|
|
13520
|
-
Instruction[Instruction["DIV_U_64"] = 203] = "DIV_U_64";
|
|
13521
|
-
Instruction[Instruction["DIV_S_64"] = 204] = "DIV_S_64";
|
|
13522
|
-
Instruction[Instruction["REM_U_64"] = 205] = "REM_U_64";
|
|
13523
|
-
Instruction[Instruction["REM_S_64"] = 206] = "REM_S_64";
|
|
13524
|
-
Instruction[Instruction["SHLO_L_64"] = 207] = "SHLO_L_64";
|
|
13525
|
-
Instruction[Instruction["SHLO_R_64"] = 208] = "SHLO_R_64";
|
|
13526
|
-
Instruction[Instruction["SHAR_R_64"] = 209] = "SHAR_R_64";
|
|
13527
|
-
Instruction[Instruction["AND"] = 210] = "AND";
|
|
13528
|
-
Instruction[Instruction["XOR"] = 211] = "XOR";
|
|
13529
|
-
Instruction[Instruction["OR"] = 212] = "OR";
|
|
13530
|
-
Instruction[Instruction["MUL_UPPER_S_S"] = 213] = "MUL_UPPER_S_S";
|
|
13531
|
-
Instruction[Instruction["MUL_UPPER_U_U"] = 214] = "MUL_UPPER_U_U";
|
|
13532
|
-
Instruction[Instruction["MUL_UPPER_S_U"] = 215] = "MUL_UPPER_S_U";
|
|
13533
|
-
Instruction[Instruction["SET_LT_U"] = 216] = "SET_LT_U";
|
|
13534
|
-
Instruction[Instruction["SET_LT_S"] = 217] = "SET_LT_S";
|
|
13535
|
-
Instruction[Instruction["CMOV_IZ"] = 218] = "CMOV_IZ";
|
|
13536
|
-
Instruction[Instruction["CMOV_NZ"] = 219] = "CMOV_NZ";
|
|
13537
|
-
Instruction[Instruction["ROT_L_64"] = 220] = "ROT_L_64";
|
|
13538
|
-
Instruction[Instruction["ROT_L_32"] = 221] = "ROT_L_32";
|
|
13539
|
-
Instruction[Instruction["ROT_R_64"] = 222] = "ROT_R_64";
|
|
13540
|
-
Instruction[Instruction["ROT_R_32"] = 223] = "ROT_R_32";
|
|
13541
|
-
Instruction[Instruction["AND_INV"] = 224] = "AND_INV";
|
|
13542
|
-
Instruction[Instruction["OR_INV"] = 225] = "OR_INV";
|
|
13543
|
-
Instruction[Instruction["XNOR"] = 226] = "XNOR";
|
|
13544
|
-
Instruction[Instruction["MAX"] = 227] = "MAX";
|
|
13545
|
-
Instruction[Instruction["MAX_U"] = 228] = "MAX_U";
|
|
13546
|
-
Instruction[Instruction["MIN"] = 229] = "MIN";
|
|
13547
|
-
Instruction[Instruction["MIN_U"] = 230] = "MIN_U";
|
|
13548
|
-
})(Instruction || (Instruction = {}));
|
|
13549
|
-
const HIGHEST_INSTRUCTION_NUMBER = Instruction.MIN_U;
|
|
13550
|
-
|
|
13551
|
-
const instructionArgumentTypeMap = (() => {
|
|
13552
|
-
const instructionArgumentTypeMap = new Array(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
13553
|
-
instructionArgumentTypeMap[Instruction.TRAP] = ArgumentType.NO_ARGUMENTS;
|
|
13554
|
-
instructionArgumentTypeMap[Instruction.FALLTHROUGH] = ArgumentType.NO_ARGUMENTS;
|
|
13555
|
-
instructionArgumentTypeMap[Instruction.ECALLI] = ArgumentType.ONE_IMMEDIATE;
|
|
13556
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM_64] = ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
13557
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U8] = ArgumentType.TWO_IMMEDIATES;
|
|
13558
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U16] = ArgumentType.TWO_IMMEDIATES;
|
|
13559
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U32] = ArgumentType.TWO_IMMEDIATES;
|
|
13560
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U64] = ArgumentType.TWO_IMMEDIATES;
|
|
13561
|
-
instructionArgumentTypeMap[Instruction.JUMP] = ArgumentType.ONE_OFFSET;
|
|
13562
|
-
instructionArgumentTypeMap[Instruction.JUMP_IND] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13563
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13564
|
-
instructionArgumentTypeMap[Instruction.LOAD_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13565
|
-
instructionArgumentTypeMap[Instruction.LOAD_I8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13566
|
-
instructionArgumentTypeMap[Instruction.LOAD_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13567
|
-
instructionArgumentTypeMap[Instruction.LOAD_I16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13568
|
-
instructionArgumentTypeMap[Instruction.LOAD_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13569
|
-
instructionArgumentTypeMap[Instruction.LOAD_I32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13570
|
-
instructionArgumentTypeMap[Instruction.LOAD_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13571
|
-
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13572
|
-
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13573
|
-
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13574
|
-
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
13575
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U8] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
13576
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U16] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
13577
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
13578
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
13579
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13580
|
-
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13581
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13582
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13583
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13584
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13585
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13586
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13587
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13588
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13589
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
13590
|
-
instructionArgumentTypeMap[Instruction.MOVE_REG] = ArgumentType.TWO_REGISTERS;
|
|
13591
|
-
instructionArgumentTypeMap[Instruction.SBRK] = ArgumentType.TWO_REGISTERS;
|
|
13592
|
-
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
13593
|
-
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
13594
|
-
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
13595
|
-
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
13596
|
-
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
13597
|
-
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
13598
|
-
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_8] = ArgumentType.TWO_REGISTERS;
|
|
13599
|
-
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
13600
|
-
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
13601
|
-
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
13602
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13603
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13604
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13605
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13606
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13607
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13608
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13609
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13610
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13611
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13612
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13613
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13614
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13615
|
-
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13616
|
-
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13617
|
-
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13618
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13619
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13620
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13621
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13622
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13623
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13624
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13625
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13626
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13627
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13628
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13629
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13630
|
-
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13631
|
-
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13632
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13633
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13634
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13635
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13636
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13637
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13638
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13639
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13640
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13641
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13642
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13643
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
13644
|
-
instructionArgumentTypeMap[Instruction.BRANCH_EQ] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
13645
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
13646
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
13647
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
13648
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
13649
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
13650
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP_IND] = ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
13651
|
-
instructionArgumentTypeMap[Instruction.ADD_32] = ArgumentType.THREE_REGISTERS;
|
|
13652
|
-
instructionArgumentTypeMap[Instruction.ADD_64] = ArgumentType.THREE_REGISTERS;
|
|
13653
|
-
instructionArgumentTypeMap[Instruction.SUB_32] = ArgumentType.THREE_REGISTERS;
|
|
13654
|
-
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
13655
|
-
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
13656
|
-
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
13657
|
-
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
13658
|
-
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
13659
|
-
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
13660
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
13661
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
13662
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
13663
|
-
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
13664
|
-
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
13665
|
-
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
13666
|
-
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
13667
|
-
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
13668
|
-
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
13669
|
-
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
13670
|
-
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
13671
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
13672
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
13673
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
13674
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
13675
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
13676
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
13677
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
13678
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
13679
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
13680
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
13681
|
-
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
13682
|
-
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
13683
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
13684
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
13685
|
-
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
13686
|
-
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
13687
|
-
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
13688
|
-
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
13689
|
-
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
13690
|
-
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
13691
|
-
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
13692
|
-
return instructionArgumentTypeMap;
|
|
13693
|
-
})();
|
|
13694
|
-
|
|
13695
|
-
const instructionsWithoutArgs = [
|
|
13696
|
-
[Instruction.TRAP, 1],
|
|
13697
|
-
[Instruction.FALLTHROUGH, 1],
|
|
13698
|
-
];
|
|
13699
|
-
const instructionsWithOneImmediate = [[Instruction.ECALLI, 1]];
|
|
13700
|
-
const instructionsWithOneRegisterAndOneExtendedWidthImmediate = [[Instruction.LOAD_IMM_64, 1]];
|
|
13701
|
-
const instructionsWithTwoImmediates = [
|
|
13702
|
-
[Instruction.STORE_IMM_U8, 1],
|
|
13703
|
-
[Instruction.STORE_IMM_U16, 1],
|
|
13704
|
-
[Instruction.STORE_IMM_U32, 1],
|
|
13705
|
-
[Instruction.STORE_IMM_U64, 1],
|
|
13706
|
-
];
|
|
13707
|
-
const instructionsWithOneOffset = [[Instruction.JUMP, 1]];
|
|
13708
|
-
const instructionsWithOneRegisterAndOneImmediate = [
|
|
13709
|
-
[Instruction.JUMP_IND, 1],
|
|
13710
|
-
[Instruction.LOAD_IMM, 1],
|
|
13711
|
-
[Instruction.LOAD_U8, 1],
|
|
13712
|
-
[Instruction.LOAD_I8, 1],
|
|
13713
|
-
[Instruction.LOAD_U16, 1],
|
|
13714
|
-
[Instruction.LOAD_I16, 1],
|
|
13715
|
-
[Instruction.LOAD_U32, 1],
|
|
13716
|
-
[Instruction.LOAD_I32, 1],
|
|
13717
|
-
[Instruction.LOAD_U64, 1],
|
|
13718
|
-
[Instruction.STORE_U8, 1],
|
|
13719
|
-
[Instruction.STORE_U16, 1],
|
|
13720
|
-
[Instruction.STORE_U32, 1],
|
|
13721
|
-
[Instruction.STORE_U64, 1],
|
|
13722
|
-
];
|
|
13723
|
-
const instructionsWithOneRegisterAndTwoImmediate = [
|
|
13724
|
-
[Instruction.STORE_IMM_IND_U8, 1],
|
|
13725
|
-
[Instruction.STORE_IMM_IND_U16, 1],
|
|
13726
|
-
[Instruction.STORE_IMM_IND_U32, 1],
|
|
13727
|
-
[Instruction.STORE_IMM_IND_U64, 1],
|
|
13728
|
-
];
|
|
13729
|
-
const instructionsWithOneRegisterOneImmediateAndOneOffset = [
|
|
13730
|
-
[Instruction.LOAD_IMM_JUMP, 1],
|
|
13731
|
-
[Instruction.BRANCH_EQ_IMM, 1],
|
|
13732
|
-
[Instruction.BRANCH_NE_IMM, 1],
|
|
13733
|
-
[Instruction.BRANCH_LT_U_IMM, 1],
|
|
13734
|
-
[Instruction.BRANCH_LE_U_IMM, 1],
|
|
13735
|
-
[Instruction.BRANCH_GE_U_IMM, 1],
|
|
13736
|
-
[Instruction.BRANCH_GT_U_IMM, 1],
|
|
13737
|
-
[Instruction.BRANCH_LT_S_IMM, 1],
|
|
13738
|
-
[Instruction.BRANCH_LE_S_IMM, 1],
|
|
13739
|
-
[Instruction.BRANCH_GE_S_IMM, 1],
|
|
13740
|
-
[Instruction.BRANCH_GT_S_IMM, 1],
|
|
13741
|
-
];
|
|
13742
|
-
const instructionsWithTwoRegisters = [
|
|
13743
|
-
[Instruction.MOVE_REG, 1],
|
|
13744
|
-
[Instruction.SBRK, 1],
|
|
13745
|
-
[Instruction.COUNT_SET_BITS_64, 1],
|
|
13746
|
-
[Instruction.COUNT_SET_BITS_32, 1],
|
|
13747
|
-
[Instruction.LEADING_ZERO_BITS_64, 1],
|
|
13748
|
-
[Instruction.LEADING_ZERO_BITS_32, 1],
|
|
13749
|
-
[Instruction.TRAILING_ZERO_BITS_64, 1],
|
|
13750
|
-
[Instruction.TRAILING_ZERO_BITS_32, 1],
|
|
13751
|
-
[Instruction.SIGN_EXTEND_8, 1],
|
|
13752
|
-
[Instruction.SIGN_EXTEND_16, 1],
|
|
13753
|
-
[Instruction.ZERO_EXTEND_16, 1],
|
|
13754
|
-
[Instruction.REVERSE_BYTES, 1],
|
|
13755
|
-
];
|
|
13756
|
-
const instructionsWithTwoRegistersAndOneImmediate = [
|
|
13757
|
-
[Instruction.STORE_IND_U8, 1],
|
|
13758
|
-
[Instruction.STORE_IND_U16, 1],
|
|
13759
|
-
[Instruction.STORE_IND_U32, 1],
|
|
13760
|
-
[Instruction.STORE_IND_U64, 1],
|
|
13761
|
-
[Instruction.LOAD_IND_U8, 1],
|
|
13762
|
-
[Instruction.LOAD_IND_I8, 1],
|
|
13763
|
-
[Instruction.LOAD_IND_U16, 1],
|
|
13764
|
-
[Instruction.LOAD_IND_I16, 1],
|
|
13765
|
-
[Instruction.LOAD_IND_U32, 1],
|
|
13766
|
-
[Instruction.LOAD_IND_I32, 1],
|
|
13767
|
-
[Instruction.LOAD_IND_U64, 1],
|
|
13768
|
-
[Instruction.ADD_IMM_32, 1],
|
|
13769
|
-
[Instruction.AND_IMM, 1],
|
|
13770
|
-
[Instruction.XOR_IMM, 1],
|
|
13771
|
-
[Instruction.OR_IMM, 1],
|
|
13772
|
-
[Instruction.MUL_IMM_32, 1],
|
|
13773
|
-
[Instruction.SET_LT_U_IMM, 1],
|
|
13774
|
-
[Instruction.SET_LT_S_IMM, 1],
|
|
13775
|
-
[Instruction.SHLO_L_IMM_32, 1],
|
|
13776
|
-
[Instruction.SHLO_R_IMM_32, 1],
|
|
13777
|
-
[Instruction.SHAR_R_IMM_32, 1],
|
|
13778
|
-
[Instruction.NEG_ADD_IMM_32, 1],
|
|
13779
|
-
[Instruction.SET_GT_U_IMM, 1],
|
|
13780
|
-
[Instruction.SET_GT_S_IMM, 1],
|
|
13781
|
-
[Instruction.SHLO_L_IMM_ALT_32, 1],
|
|
13782
|
-
[Instruction.SHLO_R_IMM_ALT_32, 1],
|
|
13783
|
-
[Instruction.SHAR_R_IMM_ALT_32, 1],
|
|
13784
|
-
[Instruction.CMOV_IZ_IMM, 1],
|
|
13785
|
-
[Instruction.CMOV_NZ_IMM, 1],
|
|
13786
|
-
[Instruction.ADD_IMM_64, 1],
|
|
13787
|
-
[Instruction.MUL_IMM_64, 1],
|
|
13788
|
-
[Instruction.SHLO_L_IMM_64, 1],
|
|
13789
|
-
[Instruction.SHLO_R_IMM_64, 1],
|
|
13790
|
-
[Instruction.SHAR_R_IMM_64, 1],
|
|
13791
|
-
[Instruction.NEG_ADD_IMM_64, 1],
|
|
13792
|
-
[Instruction.SHLO_L_IMM_ALT_64, 1],
|
|
13793
|
-
[Instruction.SHLO_R_IMM_ALT_64, 1],
|
|
13794
|
-
[Instruction.SHAR_R_IMM_ALT_64, 1],
|
|
13795
|
-
[Instruction.ROT_R_64_IMM, 1],
|
|
13796
|
-
[Instruction.ROT_R_64_IMM_ALT, 1],
|
|
13797
|
-
[Instruction.ROT_R_32_IMM, 1],
|
|
13798
|
-
[Instruction.ROT_R_32_IMM_ALT, 1],
|
|
13799
|
-
];
|
|
13800
|
-
const instructionsWithTwoRegistersAndOneOffset = [
|
|
13801
|
-
[Instruction.BRANCH_EQ, 1],
|
|
13802
|
-
[Instruction.BRANCH_NE, 1],
|
|
13803
|
-
[Instruction.BRANCH_LT_U, 1],
|
|
13804
|
-
[Instruction.BRANCH_LT_S, 1],
|
|
13805
|
-
[Instruction.BRANCH_GE_U, 1],
|
|
13806
|
-
[Instruction.BRANCH_GE_S, 1],
|
|
13807
|
-
];
|
|
13808
|
-
const instructionWithTwoRegistersAndTwoImmediates = [[Instruction.LOAD_IMM_JUMP_IND, 1]];
|
|
13809
|
-
const instructionsWithThreeRegisters = [
|
|
13810
|
-
[Instruction.ADD_32, 1],
|
|
13811
|
-
[Instruction.SUB_32, 1],
|
|
13812
|
-
[Instruction.MUL_32, 1],
|
|
13813
|
-
[Instruction.DIV_U_32, 1],
|
|
13814
|
-
[Instruction.DIV_S_32, 1],
|
|
13815
|
-
[Instruction.REM_U_32, 1],
|
|
13816
|
-
[Instruction.REM_S_32, 1],
|
|
13817
|
-
[Instruction.SHLO_L_32, 1],
|
|
13818
|
-
[Instruction.SHLO_R_32, 1],
|
|
13819
|
-
[Instruction.SHAR_R_32, 1],
|
|
13820
|
-
[Instruction.ADD_64, 1],
|
|
13821
|
-
[Instruction.SUB_64, 1],
|
|
13822
|
-
[Instruction.MUL_64, 1],
|
|
13823
|
-
[Instruction.DIV_U_64, 1],
|
|
13824
|
-
[Instruction.DIV_S_64, 1],
|
|
13825
|
-
[Instruction.REM_U_64, 1],
|
|
13826
|
-
[Instruction.REM_S_64, 1],
|
|
13827
|
-
[Instruction.SHLO_L_64, 1],
|
|
13828
|
-
[Instruction.SHLO_R_64, 1],
|
|
13829
|
-
[Instruction.SHAR_R_64, 1],
|
|
13830
|
-
[Instruction.AND, 1],
|
|
13831
|
-
[Instruction.XOR, 1],
|
|
13832
|
-
[Instruction.OR, 1],
|
|
13833
|
-
[Instruction.MUL_UPPER_S_S, 1],
|
|
13834
|
-
[Instruction.MUL_UPPER_U_U, 1],
|
|
13835
|
-
[Instruction.MUL_UPPER_S_U, 1],
|
|
13836
|
-
[Instruction.SET_LT_U, 1],
|
|
13837
|
-
[Instruction.SET_LT_S, 1],
|
|
13838
|
-
[Instruction.CMOV_IZ, 1],
|
|
13839
|
-
[Instruction.CMOV_NZ, 1],
|
|
13840
|
-
[Instruction.ROT_L_64, 1],
|
|
13841
|
-
[Instruction.ROT_L_32, 1],
|
|
13842
|
-
[Instruction.ROT_R_64, 1],
|
|
13843
|
-
[Instruction.ROT_R_32, 1],
|
|
13844
|
-
[Instruction.AND_INV, 1],
|
|
13845
|
-
[Instruction.OR_INV, 1],
|
|
13846
|
-
[Instruction.XNOR, 1],
|
|
13847
|
-
[Instruction.MAX, 1],
|
|
13848
|
-
[Instruction.MAX_U, 1],
|
|
13849
|
-
[Instruction.MIN, 1],
|
|
13850
|
-
[Instruction.MIN_U, 1],
|
|
13851
|
-
];
|
|
13852
|
-
const instructions = [
|
|
13853
|
-
...instructionsWithoutArgs,
|
|
13854
|
-
...instructionsWithOneImmediate,
|
|
13855
|
-
...instructionsWithOneRegisterAndOneExtendedWidthImmediate,
|
|
13856
|
-
...instructionsWithTwoImmediates,
|
|
13857
|
-
...instructionsWithOneOffset,
|
|
13858
|
-
...instructionsWithOneRegisterAndOneImmediate,
|
|
13859
|
-
...instructionsWithOneRegisterAndTwoImmediate,
|
|
13860
|
-
...instructionsWithOneRegisterOneImmediateAndOneOffset,
|
|
13861
|
-
...instructionsWithTwoRegisters,
|
|
13862
|
-
...instructionsWithTwoRegistersAndOneImmediate,
|
|
13863
|
-
...instructionsWithTwoRegistersAndOneOffset,
|
|
13864
|
-
...instructionWithTwoRegistersAndTwoImmediates,
|
|
13865
|
-
...instructionsWithThreeRegisters,
|
|
13866
|
-
];
|
|
13867
|
-
const createOpCodeEntry = ([byte, gas]) => [byte, { gas: tryAsSmallGas(gas) }];
|
|
13868
|
-
const byteToOpCodeMap = instructions.reduce((acc, instruction) => {
|
|
13869
|
-
const [byte, opCode] = createOpCodeEntry(instruction);
|
|
13870
|
-
acc[byte] = opCode;
|
|
13871
|
-
return acc;
|
|
13872
|
-
}, {});
|
|
13873
|
-
function assemblify(program, mask) {
|
|
13874
|
-
return program.reduce((acc, byte, index) => {
|
|
13875
|
-
if (mask.isInstruction(index)) {
|
|
13876
|
-
acc.push([Instruction[byte]]);
|
|
13568
|
+
var AccessType;
|
|
13569
|
+
(function (AccessType) {
|
|
13570
|
+
AccessType[AccessType["READ"] = 0] = "READ";
|
|
13571
|
+
AccessType[AccessType["WRITE"] = 1] = "WRITE";
|
|
13572
|
+
})(AccessType || (AccessType = {}));
|
|
13573
|
+
const logger$2 = Logger.new(undefined, "pvm:mem");
|
|
13574
|
+
class Memory {
|
|
13575
|
+
sbrkIndex;
|
|
13576
|
+
virtualSbrkIndex;
|
|
13577
|
+
endHeapIndex;
|
|
13578
|
+
memory;
|
|
13579
|
+
static fromInitialMemory(initialMemoryState) {
|
|
13580
|
+
return new Memory(initialMemoryState?.sbrkIndex, initialMemoryState?.sbrkIndex, initialMemoryState?.endHeapIndex, initialMemoryState?.memory);
|
|
13581
|
+
}
|
|
13582
|
+
constructor(sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end), virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end), endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX), memory = new Map()) {
|
|
13583
|
+
this.sbrkIndex = sbrkIndex;
|
|
13584
|
+
this.virtualSbrkIndex = virtualSbrkIndex;
|
|
13585
|
+
this.endHeapIndex = endHeapIndex;
|
|
13586
|
+
this.memory = memory;
|
|
13587
|
+
}
|
|
13588
|
+
store(address, bytes) {
|
|
13589
|
+
return this.storeFrom(tryAsMemoryIndex(address), bytes);
|
|
13590
|
+
}
|
|
13591
|
+
read(address, output) {
|
|
13592
|
+
return this.loadInto(output, tryAsMemoryIndex(address));
|
|
13593
|
+
}
|
|
13594
|
+
reset() {
|
|
13595
|
+
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
13596
|
+
this.virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
13597
|
+
this.endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX);
|
|
13598
|
+
this.memory = new Map(); // TODO [MaSi]: We should keep allocated pages somewhere and reuse it when it is possible
|
|
13599
|
+
}
|
|
13600
|
+
copyFrom(memory) {
|
|
13601
|
+
this.sbrkIndex = memory.sbrkIndex;
|
|
13602
|
+
this.virtualSbrkIndex = memory.virtualSbrkIndex;
|
|
13603
|
+
this.endHeapIndex = memory.endHeapIndex;
|
|
13604
|
+
this.memory = memory.memory;
|
|
13605
|
+
}
|
|
13606
|
+
storeFrom(address, bytes) {
|
|
13607
|
+
if (bytes.length === 0) {
|
|
13608
|
+
return Result$1.ok(OK);
|
|
13609
|
+
}
|
|
13610
|
+
logger$2.insane `MEM[${address}] <- ${BytesBlob.blobFrom(bytes)}`;
|
|
13611
|
+
const pagesResult = this.getPages(address, bytes.length, AccessType.WRITE);
|
|
13612
|
+
if (pagesResult.isError) {
|
|
13613
|
+
return Result$1.error(pagesResult.error, pagesResult.details);
|
|
13614
|
+
}
|
|
13615
|
+
const pages = pagesResult.ok;
|
|
13616
|
+
let currentPosition = address;
|
|
13617
|
+
let bytesLeft = bytes.length;
|
|
13618
|
+
for (const page of pages) {
|
|
13619
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE$1);
|
|
13620
|
+
const bytesToWrite = Math.min(PAGE_SIZE$1 - pageStartIndex, bytesLeft);
|
|
13621
|
+
const sourceStartIndex = currentPosition - address;
|
|
13622
|
+
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
13623
|
+
page.storeFrom(pageStartIndex, source);
|
|
13624
|
+
currentPosition += bytesToWrite;
|
|
13625
|
+
bytesLeft -= bytesToWrite;
|
|
13626
|
+
}
|
|
13627
|
+
return Result$1.ok(OK);
|
|
13628
|
+
}
|
|
13629
|
+
getPages(startAddress, length, accessType) {
|
|
13630
|
+
if (length === 0) {
|
|
13631
|
+
return Result$1.ok([]);
|
|
13632
|
+
}
|
|
13633
|
+
const memoryRange = MemoryRange.fromStartAndLength(startAddress, length);
|
|
13634
|
+
const pageRange = PageRange.fromMemoryRange(memoryRange);
|
|
13635
|
+
const pages = [];
|
|
13636
|
+
for (const pageNumber of pageRange) {
|
|
13637
|
+
if (pageNumber < RESERVED_NUMBER_OF_PAGES) {
|
|
13638
|
+
return Result$1.error(PageFault.fromPageNumber(pageNumber, true), () => `Page fault: attempted to access reserved page ${pageNumber}`);
|
|
13639
|
+
}
|
|
13640
|
+
const page = this.memory.get(pageNumber);
|
|
13641
|
+
if (page === undefined) {
|
|
13642
|
+
return Result$1.error(PageFault.fromPageNumber(pageNumber), () => `Page fault: page ${pageNumber} not allocated`);
|
|
13643
|
+
}
|
|
13644
|
+
if (accessType === AccessType.WRITE && !page.isWriteable()) {
|
|
13645
|
+
return Result$1.error(PageFault.fromPageNumber(pageNumber, true), () => `Page fault: attempted to write to read-only page ${pageNumber}`);
|
|
13646
|
+
}
|
|
13647
|
+
pages.push(page);
|
|
13648
|
+
}
|
|
13649
|
+
return Result$1.ok(pages);
|
|
13650
|
+
}
|
|
13651
|
+
/**
|
|
13652
|
+
* Read content of the memory at `[address, address + result.length)` and
|
|
13653
|
+
* write the result into the `result` buffer.
|
|
13654
|
+
*
|
|
13655
|
+
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
13656
|
+
*/
|
|
13657
|
+
loadInto(result, startAddress) {
|
|
13658
|
+
if (result.length === 0) {
|
|
13659
|
+
return Result$1.ok(OK);
|
|
13660
|
+
}
|
|
13661
|
+
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
13662
|
+
if (pagesResult.isError) {
|
|
13663
|
+
return Result$1.error(pagesResult.error, pagesResult.details);
|
|
13664
|
+
}
|
|
13665
|
+
const pages = pagesResult.ok;
|
|
13666
|
+
let currentPosition = startAddress;
|
|
13667
|
+
let bytesLeft = result.length;
|
|
13668
|
+
for (const page of pages) {
|
|
13669
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE$1);
|
|
13670
|
+
const bytesToRead = Math.min(PAGE_SIZE$1 - pageStartIndex, bytesLeft);
|
|
13671
|
+
const destinationStartIndex = currentPosition - startAddress;
|
|
13672
|
+
const destination = result.subarray(destinationStartIndex);
|
|
13673
|
+
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
13674
|
+
currentPosition += bytesToRead;
|
|
13675
|
+
bytesLeft -= bytesToRead;
|
|
13877
13676
|
}
|
|
13878
|
-
|
|
13879
|
-
|
|
13677
|
+
logger$2.insane `MEM[${startAddress}] => ${BytesBlob.blobFrom(result)}`;
|
|
13678
|
+
return Result$1.ok(OK);
|
|
13679
|
+
}
|
|
13680
|
+
sbrk(length) {
|
|
13681
|
+
const currentSbrkIndex = this.sbrkIndex;
|
|
13682
|
+
const currentVirtualSbrkIndex = this.virtualSbrkIndex;
|
|
13683
|
+
// new sbrk index is bigger than 2 ** 32 or endHeapIndex
|
|
13684
|
+
if (MAX_MEMORY_INDEX < currentVirtualSbrkIndex + length || currentVirtualSbrkIndex + length > this.endHeapIndex) {
|
|
13685
|
+
throw new OutOfMemory();
|
|
13880
13686
|
}
|
|
13881
|
-
|
|
13882
|
-
|
|
13687
|
+
const newVirtualSbrkIndex = tryAsSbrkIndex(this.virtualSbrkIndex + length);
|
|
13688
|
+
// no alllocation needed
|
|
13689
|
+
if (newVirtualSbrkIndex <= currentSbrkIndex) {
|
|
13690
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
13691
|
+
return currentVirtualSbrkIndex;
|
|
13692
|
+
}
|
|
13693
|
+
// standard allocation using "Writeable" pages
|
|
13694
|
+
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize$1(newVirtualSbrkIndex));
|
|
13695
|
+
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
13696
|
+
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
13697
|
+
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE$1;
|
|
13698
|
+
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
13699
|
+
for (const pageNumber of rangeToAllocate) {
|
|
13700
|
+
const page = new WriteablePage(pageNumber);
|
|
13701
|
+
this.memory.set(pageNumber, page);
|
|
13702
|
+
}
|
|
13703
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
13704
|
+
this.sbrkIndex = newSbrkIndex;
|
|
13705
|
+
return currentVirtualSbrkIndex;
|
|
13706
|
+
}
|
|
13707
|
+
getPageDump(pageNumber) {
|
|
13708
|
+
const page = this.memory.get(pageNumber);
|
|
13709
|
+
return page?.getPageDump() ?? null;
|
|
13710
|
+
}
|
|
13711
|
+
getDirtyPages() {
|
|
13712
|
+
return this.memory.keys();
|
|
13713
|
+
}
|
|
13714
|
+
}
|
|
13715
|
+
|
|
13716
|
+
class MemoryBuilder {
|
|
13717
|
+
initialMemory = new Map();
|
|
13718
|
+
isFinalized = false;
|
|
13719
|
+
ensureNotFinalized() {
|
|
13720
|
+
if (this.isFinalized) {
|
|
13721
|
+
throw new FinalizedBuilderModification();
|
|
13722
|
+
}
|
|
13723
|
+
}
|
|
13724
|
+
ensureNoReservedMemoryUsage(range) {
|
|
13725
|
+
if (range.overlapsWith(RESERVED_MEMORY_RANGE)) {
|
|
13726
|
+
throw new ReservedMemoryFault();
|
|
13727
|
+
}
|
|
13728
|
+
}
|
|
13729
|
+
/**
|
|
13730
|
+
* Create entire readable pages to handle the `[start, end)` range.
|
|
13731
|
+
*
|
|
13732
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
13733
|
+
* they need to be the start indices of the pages.
|
|
13734
|
+
*
|
|
13735
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
13736
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
13737
|
+
*/
|
|
13738
|
+
setReadablePages(start, end, data = new Uint8Array()) {
|
|
13739
|
+
this.ensureNotFinalized();
|
|
13740
|
+
check `${start < end} end has to be bigger than start`;
|
|
13741
|
+
check `${start % PAGE_SIZE$1 === 0} start needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
13742
|
+
check `${end % PAGE_SIZE$1 === 0} end needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
13743
|
+
check `${data.length <= end - start} the initial data is longer than address range`;
|
|
13744
|
+
const length = end - start;
|
|
13745
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
13746
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
13747
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
13748
|
+
const noOfPages = pages.length;
|
|
13749
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
13750
|
+
const pageNumber = pages[i];
|
|
13751
|
+
const dataChunk = data.subarray(i * PAGE_SIZE$1, (i + 1) * PAGE_SIZE$1);
|
|
13752
|
+
const page = new ReadablePage(pageNumber, dataChunk);
|
|
13753
|
+
this.initialMemory.set(pageNumber, page);
|
|
13754
|
+
}
|
|
13755
|
+
return this;
|
|
13756
|
+
}
|
|
13757
|
+
/**
|
|
13758
|
+
* Create entire writeable pages to handle the `[start, end)` range.
|
|
13759
|
+
*
|
|
13760
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
13761
|
+
* they need to be the start indices of the pages.
|
|
13762
|
+
*
|
|
13763
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
13764
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
13765
|
+
*/
|
|
13766
|
+
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
13767
|
+
this.ensureNotFinalized();
|
|
13768
|
+
check `${start < end} end has to be bigger than start`;
|
|
13769
|
+
check `${start % PAGE_SIZE$1 === 0} start needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
13770
|
+
check `${end % PAGE_SIZE$1 === 0} end needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
13771
|
+
check `${data.length <= end - start} the initial data is longer than address range`;
|
|
13772
|
+
const length = end - start;
|
|
13773
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
13774
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
13775
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
13776
|
+
const noOfPages = pages.length;
|
|
13777
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
13778
|
+
const pageNumber = pages[i];
|
|
13779
|
+
const dataChunk = data.subarray(i * PAGE_SIZE$1, (i + 1) * PAGE_SIZE$1);
|
|
13780
|
+
const page = new WriteablePage(pageNumber, dataChunk);
|
|
13781
|
+
this.initialMemory.set(pageNumber, page);
|
|
13782
|
+
}
|
|
13783
|
+
return this;
|
|
13784
|
+
}
|
|
13785
|
+
/**
|
|
13786
|
+
* This function can be useful when page map and initial memory data are provided separatelly.
|
|
13787
|
+
* You can use setWriteablePages/setReadablePages to create empty pages and then setData to fill them
|
|
13788
|
+
*/
|
|
13789
|
+
setData(start, data) {
|
|
13790
|
+
this.ensureNotFinalized();
|
|
13791
|
+
const pageOffset = start % PAGE_SIZE$1;
|
|
13792
|
+
const remainingSpaceOnPage = PAGE_SIZE$1 - pageOffset;
|
|
13793
|
+
check `${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
13794
|
+
const length = data.length;
|
|
13795
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
13796
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
13797
|
+
const pageNumber = getPageNumber(start);
|
|
13798
|
+
const page = this.initialMemory.get(pageNumber);
|
|
13799
|
+
if (page === undefined) {
|
|
13800
|
+
throw new PageNotExist();
|
|
13801
|
+
}
|
|
13802
|
+
const startPageIndex = tryAsPageIndex(start - page.start);
|
|
13803
|
+
page.setData(startPageIndex, data);
|
|
13804
|
+
return this;
|
|
13805
|
+
}
|
|
13806
|
+
finalize(startHeapIndex, endHeapIndex) {
|
|
13807
|
+
check `
|
|
13808
|
+
${startHeapIndex <= endHeapIndex}
|
|
13809
|
+
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
13810
|
+
`;
|
|
13811
|
+
this.ensureNotFinalized();
|
|
13812
|
+
const heapRange = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
13813
|
+
const heapPagesRange = PageRange.fromMemoryRange(heapRange);
|
|
13814
|
+
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
13815
|
+
for (const pageNumber of initializedPageNumbers) {
|
|
13816
|
+
if (heapPagesRange.isInRange(pageNumber)) {
|
|
13817
|
+
throw new IncorrectSbrkIndex();
|
|
13818
|
+
}
|
|
13819
|
+
}
|
|
13820
|
+
const memory = Memory.fromInitialMemory({
|
|
13821
|
+
memory: this.initialMemory,
|
|
13822
|
+
sbrkIndex: tryAsSbrkIndex(startHeapIndex),
|
|
13823
|
+
endHeapIndex,
|
|
13824
|
+
});
|
|
13825
|
+
this.isFinalized = true;
|
|
13826
|
+
return memory;
|
|
13827
|
+
}
|
|
13828
|
+
}
|
|
13829
|
+
|
|
13830
|
+
// GP reference: https://graypaper.fluffylabs.dev/#/7e6ff6a/2d32002d3200?v=0.6.7
|
|
13831
|
+
const PAGE_SIZE = 2 ** 12; // Z_P from GP
|
|
13832
|
+
const SEGMENT_SIZE = 2 ** 16; // Z_Z from GP
|
|
13833
|
+
const DATA_LEGNTH = 2 ** 24; // Z_I from GP
|
|
13834
|
+
const STACK_SEGMENT = 0xfe_fe_00_00; // 2^32 - 2Z_Z - Z_I from GP
|
|
13835
|
+
const ARGS_SEGMENT = 0xfe_ff_00_00; // 2^32 - Z_Z - Z_I from GP
|
|
13836
|
+
const LAST_PAGE = 0xff_ff_00_00;
|
|
13837
|
+
|
|
13838
|
+
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2bd2022bd202
|
|
13839
|
+
function alignToSegmentSize(size) {
|
|
13840
|
+
// Q(x) from GP
|
|
13841
|
+
return SEGMENT_SIZE * Math.ceil(size / SEGMENT_SIZE);
|
|
13842
|
+
}
|
|
13843
|
+
function alignToPageSize(size) {
|
|
13844
|
+
// P(x) from GP
|
|
13845
|
+
return PAGE_SIZE * Math.ceil(size / PAGE_SIZE);
|
|
13846
|
+
}
|
|
13847
|
+
|
|
13848
|
+
const NO_OF_REGISTERS = 13;
|
|
13849
|
+
class MemorySegment extends WithDebug {
|
|
13850
|
+
start;
|
|
13851
|
+
end;
|
|
13852
|
+
data;
|
|
13853
|
+
static from({ start, end, data }) {
|
|
13854
|
+
return new MemorySegment(start, end, data);
|
|
13855
|
+
}
|
|
13856
|
+
constructor(start, end, data) {
|
|
13857
|
+
super();
|
|
13858
|
+
this.start = start;
|
|
13859
|
+
this.end = end;
|
|
13860
|
+
this.data = data;
|
|
13861
|
+
}
|
|
13862
|
+
}
|
|
13863
|
+
class SpiMemory extends WithDebug {
|
|
13864
|
+
readable;
|
|
13865
|
+
writeable;
|
|
13866
|
+
sbrkIndex;
|
|
13867
|
+
heapEnd;
|
|
13868
|
+
constructor(readable, writeable, sbrkIndex, heapEnd) {
|
|
13869
|
+
super();
|
|
13870
|
+
this.readable = readable;
|
|
13871
|
+
this.writeable = writeable;
|
|
13872
|
+
this.sbrkIndex = sbrkIndex;
|
|
13873
|
+
this.heapEnd = heapEnd;
|
|
13874
|
+
}
|
|
13875
|
+
}
|
|
13876
|
+
class SpiProgram extends WithDebug {
|
|
13877
|
+
code;
|
|
13878
|
+
memory;
|
|
13879
|
+
registers;
|
|
13880
|
+
constructor(code, memory, registers) {
|
|
13881
|
+
super();
|
|
13882
|
+
this.code = code;
|
|
13883
|
+
this.memory = memory;
|
|
13884
|
+
this.registers = registers;
|
|
13885
|
+
}
|
|
13886
|
+
}
|
|
13887
|
+
/**
|
|
13888
|
+
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
13889
|
+
*
|
|
13890
|
+
* E_n - little endian encoding, n - length
|
|
13891
|
+
* o - initial read only data
|
|
13892
|
+
* w - initial heap
|
|
13893
|
+
* z - heap pages filled with zeros
|
|
13894
|
+
* s - stack size
|
|
13895
|
+
* c - program code
|
|
13896
|
+
*
|
|
13897
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
13898
|
+
*/
|
|
13899
|
+
function decodeStandardProgram(program, args) {
|
|
13900
|
+
const decoder = Decoder.fromBlob(program);
|
|
13901
|
+
const oLength = decoder.u24();
|
|
13902
|
+
const wLength = decoder.u24();
|
|
13903
|
+
check `${args.length <= DATA_LEGNTH} Incorrect arguments length`;
|
|
13904
|
+
check `${oLength <= DATA_LEGNTH} Incorrect readonly segment length`;
|
|
13905
|
+
const readOnlyLength = oLength;
|
|
13906
|
+
check `${wLength <= DATA_LEGNTH} Incorrect heap segment length`;
|
|
13907
|
+
const heapLength = wLength;
|
|
13908
|
+
const noOfHeapZerosPages = decoder.u16();
|
|
13909
|
+
const stackSize = decoder.u24();
|
|
13910
|
+
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
13911
|
+
const initialHeap = decoder.bytes(heapLength).raw;
|
|
13912
|
+
const codeLength = decoder.u32();
|
|
13913
|
+
const code = decoder.bytes(codeLength).raw;
|
|
13914
|
+
decoder.finish();
|
|
13915
|
+
const readonlyDataStart = SEGMENT_SIZE;
|
|
13916
|
+
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
13917
|
+
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
13918
|
+
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
13919
|
+
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
13920
|
+
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
13921
|
+
const stackEnd = STACK_SEGMENT;
|
|
13922
|
+
const argsStart = ARGS_SEGMENT;
|
|
13923
|
+
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
13924
|
+
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
13925
|
+
function nonEmpty(s) {
|
|
13926
|
+
return s !== false;
|
|
13927
|
+
}
|
|
13928
|
+
const readableMemory = [
|
|
13929
|
+
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
13930
|
+
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
13931
|
+
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
13932
|
+
].filter(nonEmpty);
|
|
13933
|
+
const writeableMemory = [
|
|
13934
|
+
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
13935
|
+
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
13936
|
+
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
13937
|
+
].filter(nonEmpty);
|
|
13938
|
+
return new SpiProgram(code, new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart), getRegisters(args.length));
|
|
13939
|
+
}
|
|
13940
|
+
function getMemorySegment(start, end, data = null) {
|
|
13941
|
+
return new MemorySegment(start, end, data);
|
|
13942
|
+
}
|
|
13943
|
+
function getRegisters(argsLength) {
|
|
13944
|
+
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
13945
|
+
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
13946
|
+
regs[0] = BigInt(LAST_PAGE);
|
|
13947
|
+
regs[1] = BigInt(STACK_SEGMENT);
|
|
13948
|
+
regs[7] = BigInt(ARGS_SEGMENT);
|
|
13949
|
+
regs[8] = BigInt(argsLength);
|
|
13950
|
+
return regs;
|
|
13883
13951
|
}
|
|
13884
13952
|
|
|
13885
|
-
|
|
13886
|
-
|
|
13887
|
-
|
|
13888
|
-
|
|
13889
|
-
|
|
13890
|
-
|
|
13891
|
-
|
|
13892
|
-
terminationInstructions[Instruction.LOAD_IMM_JUMP] = true;
|
|
13893
|
-
terminationInstructions[Instruction.LOAD_IMM_JUMP_IND] = true;
|
|
13894
|
-
terminationInstructions[Instruction.BRANCH_EQ] = true;
|
|
13895
|
-
terminationInstructions[Instruction.BRANCH_NE] = true;
|
|
13896
|
-
terminationInstructions[Instruction.BRANCH_GE_U] = true;
|
|
13897
|
-
terminationInstructions[Instruction.BRANCH_GE_S] = true;
|
|
13898
|
-
terminationInstructions[Instruction.BRANCH_LT_U] = true;
|
|
13899
|
-
terminationInstructions[Instruction.BRANCH_LT_S] = true;
|
|
13900
|
-
terminationInstructions[Instruction.BRANCH_EQ_IMM] = true;
|
|
13901
|
-
terminationInstructions[Instruction.BRANCH_NE_IMM] = true;
|
|
13902
|
-
terminationInstructions[Instruction.BRANCH_LT_U_IMM] = true;
|
|
13903
|
-
terminationInstructions[Instruction.BRANCH_LT_S_IMM] = true;
|
|
13904
|
-
terminationInstructions[Instruction.BRANCH_LE_U_IMM] = true;
|
|
13905
|
-
terminationInstructions[Instruction.BRANCH_LE_S_IMM] = true;
|
|
13906
|
-
terminationInstructions[Instruction.BRANCH_GE_U_IMM] = true;
|
|
13907
|
-
terminationInstructions[Instruction.BRANCH_GE_S_IMM] = true;
|
|
13908
|
-
terminationInstructions[Instruction.BRANCH_GT_U_IMM] = true;
|
|
13909
|
-
terminationInstructions[Instruction.BRANCH_GT_S_IMM] = true;
|
|
13910
|
-
return terminationInstructions;
|
|
13911
|
-
})();
|
|
13953
|
+
var index$7 = /*#__PURE__*/Object.freeze({
|
|
13954
|
+
__proto__: null,
|
|
13955
|
+
MemorySegment: MemorySegment,
|
|
13956
|
+
SpiMemory: SpiMemory,
|
|
13957
|
+
SpiProgram: SpiProgram,
|
|
13958
|
+
decodeStandardProgram: decodeStandardProgram
|
|
13959
|
+
});
|
|
13912
13960
|
|
|
13913
|
-
class
|
|
13914
|
-
|
|
13915
|
-
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
|
|
13919
|
-
const
|
|
13920
|
-
|
|
13921
|
-
|
|
13922
|
-
|
|
13923
|
-
|
|
13961
|
+
class Program {
|
|
13962
|
+
code;
|
|
13963
|
+
registers;
|
|
13964
|
+
memory;
|
|
13965
|
+
metadata;
|
|
13966
|
+
static fromSpi(blob, args, hasMetadata) {
|
|
13967
|
+
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
13968
|
+
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
13969
|
+
const regs = new Registers();
|
|
13970
|
+
regs.copyFrom(registers);
|
|
13971
|
+
const memoryBuilder = new MemoryBuilder();
|
|
13972
|
+
for (const { start, end, data } of rawMemory.readable) {
|
|
13973
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
13974
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
13975
|
+
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
13924
13976
|
}
|
|
13977
|
+
for (const { start, end, data } of rawMemory.writeable) {
|
|
13978
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
13979
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
13980
|
+
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
13981
|
+
}
|
|
13982
|
+
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
13983
|
+
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
13984
|
+
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
13985
|
+
return new Program(code, regs, memory, metadata);
|
|
13925
13986
|
}
|
|
13926
|
-
|
|
13927
|
-
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
const instructionGasMap = (() => {
|
|
13932
|
-
const instructionGasMap = new Array(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
13933
|
-
for (let i = 0; i < HIGHEST_INSTRUCTION_NUMBER + 1; i++) {
|
|
13934
|
-
const gas = byteToOpCodeMap[i]?.gas;
|
|
13935
|
-
instructionGasMap[i] = gas;
|
|
13987
|
+
static fromGeneric(blob, hasMetadata) {
|
|
13988
|
+
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
13989
|
+
const regs = new Registers();
|
|
13990
|
+
const memory = new Memory();
|
|
13991
|
+
return new Program(code, regs, memory, metadata);
|
|
13936
13992
|
}
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
status = null;
|
|
13943
|
-
/**
|
|
13944
|
-
* A numeric exit parameter of the PVM.
|
|
13945
|
-
*
|
|
13946
|
-
* In case of a `status === Result.FAULT` this will be the memory address
|
|
13947
|
-
* that triggered the fault.
|
|
13948
|
-
* In case of a `status === Result.HOST` this will be the host call index
|
|
13949
|
-
* that should be invoked.
|
|
13950
|
-
*
|
|
13951
|
-
* In any other circumstance the value should be `null`.
|
|
13952
|
-
*/
|
|
13953
|
-
exitParam = null;
|
|
13954
|
-
reset() {
|
|
13955
|
-
this.nextPc = 0;
|
|
13956
|
-
this.status = null;
|
|
13957
|
-
this.exitParam = null;
|
|
13993
|
+
constructor(code, registers, memory, metadata = new Uint8Array()) {
|
|
13994
|
+
this.code = code;
|
|
13995
|
+
this.registers = registers;
|
|
13996
|
+
this.memory = memory;
|
|
13997
|
+
this.metadata = metadata;
|
|
13958
13998
|
}
|
|
13959
13999
|
}
|
|
13960
|
-
|
|
13961
|
-
const MAX_MEMORY_INDEX = 0xffff_ffff;
|
|
13962
|
-
const MEMORY_SIZE = MAX_MEMORY_INDEX + 1;
|
|
13963
|
-
const PAGE_SIZE_SHIFT = 12;
|
|
13964
|
-
// PAGE_SIZE has to be a power of 2
|
|
13965
|
-
const PAGE_SIZE$1 = 1 << PAGE_SIZE_SHIFT;
|
|
13966
|
-
const MIN_ALLOCATION_SHIFT = (() => {
|
|
13967
|
-
const MIN_ALLOCATION_SHIFT = 7;
|
|
13968
|
-
check `${MIN_ALLOCATION_SHIFT < PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
13969
|
-
return MIN_ALLOCATION_SHIFT;
|
|
13970
|
-
})();
|
|
13971
|
-
const MIN_ALLOCATION_LENGTH = PAGE_SIZE$1 >> MIN_ALLOCATION_SHIFT;
|
|
13972
|
-
const LAST_PAGE_NUMBER = (MEMORY_SIZE - PAGE_SIZE$1) / PAGE_SIZE$1;
|
|
13973
|
-
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
13974
|
-
const RESERVED_NUMBER_OF_PAGES = 16;
|
|
13975
|
-
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
13976
|
-
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE / PAGE_SIZE$1;
|
|
13977
|
-
|
|
13978
|
-
const tryAsMemoryIndex = (index) => {
|
|
13979
|
-
check `${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
13980
|
-
return asOpaqueType(index);
|
|
13981
|
-
};
|
|
13982
|
-
const tryAsSbrkIndex = (index) => {
|
|
13983
|
-
check `${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
13984
|
-
return asOpaqueType(index);
|
|
13985
|
-
};
|
|
13986
|
-
|
|
13987
|
-
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
13988
|
-
const tryAsPageIndex = (index) => {
|
|
13989
|
-
check `${index >= 0 && index < PAGE_SIZE$1}, Incorect page index: ${index}!`;
|
|
13990
|
-
return asOpaqueType(index);
|
|
13991
|
-
};
|
|
13992
|
-
/** Ensure that given `index` represents an index of one of the pages. */
|
|
13993
|
-
const tryAsPageNumber = (index) => {
|
|
13994
|
-
check `${index >= 0 && index <= LAST_PAGE_NUMBER}, Incorect page number: ${index}!`;
|
|
13995
|
-
return asOpaqueType(index);
|
|
13996
|
-
};
|
|
13997
14000
|
/**
|
|
13998
|
-
*
|
|
13999
|
-
*
|
|
14000
|
-
* GP references:
|
|
14001
|
-
* 1. The modulo subscription operator is used in all load/store instructions, for example:
|
|
14002
|
-
* https://graypaper.fluffylabs.dev/#/579bd12/25af0125af01
|
|
14001
|
+
* A function that splits preimage into metadata and code.
|
|
14003
14002
|
*
|
|
14004
|
-
*
|
|
14005
|
-
* https://graypaper.fluffylabs.dev/#/579bd12/073a00073a00
|
|
14003
|
+
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
14006
14004
|
*/
|
|
14007
|
-
function
|
|
14008
|
-
const
|
|
14009
|
-
|
|
14005
|
+
function extractCodeAndMetadata(blobWithMetadata) {
|
|
14006
|
+
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
14007
|
+
const metadata = decoder.bytesBlob().raw;
|
|
14008
|
+
const code = decoder.remainingBytes().raw;
|
|
14009
|
+
return { metadata, code };
|
|
14010
14010
|
}
|
|
14011
14011
|
|
|
14012
|
-
|
|
14013
|
-
|
|
14014
|
-
|
|
14015
|
-
|
|
14016
|
-
|
|
14017
|
-
}
|
|
14018
|
-
function getStartPageIndex(address) {
|
|
14019
|
-
return tryAsMemoryIndex((address >>> PAGE_SIZE_SHIFT) << PAGE_SIZE_SHIFT);
|
|
14020
|
-
}
|
|
14021
|
-
function getStartPageIndexFromPageNumber(pageNumber) {
|
|
14022
|
-
// >>> 0 is needed to avoid changing sign of the number
|
|
14023
|
-
return tryAsMemoryIndex((pageNumber << PAGE_SIZE_SHIFT) >>> 0);
|
|
14024
|
-
}
|
|
14012
|
+
var index$6 = /*#__PURE__*/Object.freeze({
|
|
14013
|
+
__proto__: null,
|
|
14014
|
+
Program: Program,
|
|
14015
|
+
extractCodeAndMetadata: extractCodeAndMetadata
|
|
14016
|
+
});
|
|
14025
14017
|
|
|
14026
|
-
|
|
14027
|
-
|
|
14028
|
-
|
|
14029
|
-
|
|
14030
|
-
|
|
14031
|
-
|
|
14018
|
+
/**
|
|
14019
|
+
* Upper bound of instruction distance - it is equal to max value of GP's skip function + 1
|
|
14020
|
+
*/
|
|
14021
|
+
const MAX_INSTRUCTION_DISTANCE = 25;
|
|
14022
|
+
/**
|
|
14023
|
+
* Mask class is an implementation of skip function defined in GP.
|
|
14024
|
+
*
|
|
14025
|
+
* https://graypaper.fluffylabs.dev/#/5f542d7/237201239801
|
|
14026
|
+
*/
|
|
14027
|
+
class Mask {
|
|
14028
|
+
/**
|
|
14029
|
+
* The lookup table will have `0` at the index which corresponds to an instruction on the same index in the bytecode.
|
|
14030
|
+
* In case the value is non-zero it signifies the offset to the index with next instruction.
|
|
14031
|
+
*
|
|
14032
|
+
* Example:
|
|
14033
|
+
* ```
|
|
14034
|
+
* 0..1..2..3..4..5..6..7..8..9 # Indices
|
|
14035
|
+
* 0..2..1..0..1..0..3..2..1..0 # lookupTable forward values
|
|
14036
|
+
* ```
|
|
14037
|
+
* There are instructions at indices `0, 3, 5, 9`.
|
|
14038
|
+
*/
|
|
14039
|
+
lookupTableForward;
|
|
14040
|
+
constructor(mask) {
|
|
14041
|
+
this.lookupTableForward = this.buildLookupTableForward(mask);
|
|
14032
14042
|
}
|
|
14033
|
-
|
|
14034
|
-
|
|
14035
|
-
|
|
14036
|
-
|
|
14043
|
+
isInstruction(index) {
|
|
14044
|
+
return this.lookupTableForward[index] === 0;
|
|
14045
|
+
}
|
|
14046
|
+
getNoOfBytesToNextInstruction(index) {
|
|
14047
|
+
check `${index >= 0} index (${index}) cannot be a negative number`;
|
|
14048
|
+
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
14049
|
+
}
|
|
14050
|
+
buildLookupTableForward(mask) {
|
|
14051
|
+
const table = safeAllocUint8Array(mask.bitLength);
|
|
14052
|
+
let lastInstructionOffset = 0;
|
|
14053
|
+
for (let i = mask.bitLength - 1; i >= 0; i--) {
|
|
14054
|
+
if (mask.isSet(i)) {
|
|
14055
|
+
lastInstructionOffset = 0;
|
|
14056
|
+
}
|
|
14057
|
+
else {
|
|
14058
|
+
lastInstructionOffset++;
|
|
14059
|
+
}
|
|
14060
|
+
table[i] = lastInstructionOffset;
|
|
14061
|
+
}
|
|
14062
|
+
return table;
|
|
14037
14063
|
}
|
|
14038
|
-
static
|
|
14039
|
-
|
|
14040
|
-
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
14041
|
-
return new PageFault(startPageIndex, isAccessFault);
|
|
14064
|
+
static empty() {
|
|
14065
|
+
return new Mask(BitVec.empty(0));
|
|
14042
14066
|
}
|
|
14043
14067
|
}
|
|
14044
|
-
|
|
14068
|
+
|
|
14069
|
+
var ArgumentType;
|
|
14070
|
+
(function (ArgumentType) {
|
|
14071
|
+
ArgumentType[ArgumentType["NO_ARGUMENTS"] = 0] = "NO_ARGUMENTS";
|
|
14072
|
+
ArgumentType[ArgumentType["ONE_IMMEDIATE"] = 1] = "ONE_IMMEDIATE";
|
|
14073
|
+
ArgumentType[ArgumentType["TWO_IMMEDIATES"] = 2] = "TWO_IMMEDIATES";
|
|
14074
|
+
ArgumentType[ArgumentType["ONE_OFFSET"] = 3] = "ONE_OFFSET";
|
|
14075
|
+
ArgumentType[ArgumentType["ONE_REGISTER_ONE_IMMEDIATE"] = 4] = "ONE_REGISTER_ONE_IMMEDIATE";
|
|
14076
|
+
ArgumentType[ArgumentType["ONE_REGISTER_TWO_IMMEDIATES"] = 5] = "ONE_REGISTER_TWO_IMMEDIATES";
|
|
14077
|
+
ArgumentType[ArgumentType["ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET"] = 6] = "ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET";
|
|
14078
|
+
ArgumentType[ArgumentType["TWO_REGISTERS"] = 7] = "TWO_REGISTERS";
|
|
14079
|
+
ArgumentType[ArgumentType["TWO_REGISTERS_ONE_IMMEDIATE"] = 8] = "TWO_REGISTERS_ONE_IMMEDIATE";
|
|
14080
|
+
ArgumentType[ArgumentType["TWO_REGISTERS_ONE_OFFSET"] = 9] = "TWO_REGISTERS_ONE_OFFSET";
|
|
14081
|
+
ArgumentType[ArgumentType["TWO_REGISTERS_TWO_IMMEDIATES"] = 10] = "TWO_REGISTERS_TWO_IMMEDIATES";
|
|
14082
|
+
ArgumentType[ArgumentType["THREE_REGISTERS"] = 11] = "THREE_REGISTERS";
|
|
14083
|
+
ArgumentType[ArgumentType["ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE"] = 12] = "ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE";
|
|
14084
|
+
})(ArgumentType || (ArgumentType = {}));
|
|
14085
|
+
|
|
14086
|
+
const BUFFER_SIZE = 8;
|
|
14087
|
+
const IMMEDIATE_SIZE$1 = 4;
|
|
14088
|
+
const U32_INDEX = 0;
|
|
14089
|
+
const U64_INDEX = 0;
|
|
14090
|
+
class ImmediateDecoder {
|
|
14091
|
+
u32;
|
|
14092
|
+
i32;
|
|
14093
|
+
u64;
|
|
14094
|
+
i64;
|
|
14095
|
+
view;
|
|
14096
|
+
bytes;
|
|
14045
14097
|
constructor() {
|
|
14046
|
-
|
|
14098
|
+
const buffer = new ArrayBuffer(BUFFER_SIZE);
|
|
14099
|
+
this.u32 = new Uint32Array(buffer);
|
|
14100
|
+
this.i32 = new Int32Array(buffer);
|
|
14101
|
+
this.u64 = new BigUint64Array(buffer);
|
|
14102
|
+
this.i64 = new BigInt64Array(buffer);
|
|
14103
|
+
this.view = new DataView(buffer);
|
|
14104
|
+
this.bytes = new Uint8Array(buffer);
|
|
14047
14105
|
}
|
|
14048
|
-
|
|
14049
|
-
|
|
14050
|
-
|
|
14051
|
-
|
|
14106
|
+
setBytes(bytes) {
|
|
14107
|
+
const n = bytes.length;
|
|
14108
|
+
const msb = n > 0 ? bytes[n - 1] & 0x80 : 0;
|
|
14109
|
+
const noOfBytes = Math.min(n, BUFFER_SIZE);
|
|
14110
|
+
const prefix = msb !== 0 ? 0xff : 0x00;
|
|
14111
|
+
for (let i = 0; i < noOfBytes; i++) {
|
|
14112
|
+
this.view.setUint8(i, bytes[i]);
|
|
14113
|
+
}
|
|
14114
|
+
for (let i = n; i < BUFFER_SIZE; i++) {
|
|
14115
|
+
this.view.setUint8(i, prefix);
|
|
14116
|
+
}
|
|
14052
14117
|
}
|
|
14053
|
-
|
|
14054
|
-
|
|
14055
|
-
|
|
14056
|
-
|
|
14118
|
+
/**
|
|
14119
|
+
* @deprecated Use getU32 instead
|
|
14120
|
+
*/
|
|
14121
|
+
getUnsigned() {
|
|
14122
|
+
return this.u32[U32_INDEX];
|
|
14057
14123
|
}
|
|
14058
|
-
|
|
14059
|
-
|
|
14060
|
-
|
|
14061
|
-
|
|
14124
|
+
/**
|
|
14125
|
+
* @deprecated Use getI32 instead
|
|
14126
|
+
*/
|
|
14127
|
+
getSigned() {
|
|
14128
|
+
return this.i32[U32_INDEX];
|
|
14062
14129
|
}
|
|
14063
|
-
|
|
14064
|
-
|
|
14065
|
-
constructor() {
|
|
14066
|
-
super("You try to fill data on memory page that does not exist!");
|
|
14130
|
+
getU32() {
|
|
14131
|
+
return this.u32[U32_INDEX];
|
|
14067
14132
|
}
|
|
14068
|
-
|
|
14069
|
-
|
|
14070
|
-
|
|
14071
|
-
|
|
14133
|
+
getI32() {
|
|
14134
|
+
return this.i32[U32_INDEX];
|
|
14135
|
+
}
|
|
14136
|
+
getU64() {
|
|
14137
|
+
return this.u64[U64_INDEX];
|
|
14138
|
+
}
|
|
14139
|
+
getI64() {
|
|
14140
|
+
return this.i64[U64_INDEX];
|
|
14141
|
+
}
|
|
14142
|
+
getBytesAsLittleEndian() {
|
|
14143
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE$1);
|
|
14144
|
+
}
|
|
14145
|
+
getExtendedBytesAsLittleEndian() {
|
|
14146
|
+
return this.bytes;
|
|
14072
14147
|
}
|
|
14073
14148
|
}
|
|
14074
14149
|
|
|
14075
|
-
|
|
14076
|
-
|
|
14077
|
-
|
|
14078
|
-
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
class MemoryRange {
|
|
14082
|
-
start;
|
|
14083
|
-
length;
|
|
14084
|
-
/**
|
|
14085
|
-
* Exclusive end index of the range.
|
|
14086
|
-
*
|
|
14087
|
-
* NOTE: The index may be wrapped around and smaller than `start`!
|
|
14088
|
-
*/
|
|
14089
|
-
end;
|
|
14090
|
-
/**
|
|
14091
|
-
* Inclusive last index of the range (present unless the range is empty).
|
|
14092
|
-
*
|
|
14093
|
-
* NOTE: the index may be wrapped around and smaller than `start`!
|
|
14094
|
-
*/
|
|
14095
|
-
lastIndex = null;
|
|
14096
|
-
constructor(start, length) {
|
|
14097
|
-
this.start = start;
|
|
14098
|
-
this.length = length;
|
|
14099
|
-
this.end = tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
14100
|
-
if (length > 0) {
|
|
14101
|
-
this.lastIndex = tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
14102
|
-
}
|
|
14150
|
+
const MAX_REGISTER_INDEX = NO_OF_REGISTERS$1 - 1;
|
|
14151
|
+
const MAX_LENGTH = 4;
|
|
14152
|
+
class NibblesDecoder {
|
|
14153
|
+
byte = new Int8Array(1);
|
|
14154
|
+
setByte(byte) {
|
|
14155
|
+
this.byte[0] = byte;
|
|
14103
14156
|
}
|
|
14104
|
-
|
|
14105
|
-
|
|
14106
|
-
if (!Number.isInteger(length) || length < 0 || length > MEMORY_SIZE) {
|
|
14107
|
-
throw new TypeError(`length must be a non-negative integer and less than ${MEMORY_SIZE}, got ${length}`);
|
|
14108
|
-
}
|
|
14109
|
-
return new MemoryRange(start, length);
|
|
14157
|
+
getHighNibble() {
|
|
14158
|
+
return (this.byte[0] & 0xf0) >>> 4;
|
|
14110
14159
|
}
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
return this.length === 0;
|
|
14160
|
+
getLowNibble() {
|
|
14161
|
+
return this.byte[0] & 0x0f;
|
|
14114
14162
|
}
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
return this.start >= this.end && !this.isEmpty();
|
|
14163
|
+
getHighNibbleAsRegisterIndex() {
|
|
14164
|
+
return Math.min(this.getHighNibble(), MAX_REGISTER_INDEX);
|
|
14118
14165
|
}
|
|
14119
|
-
|
|
14120
|
-
|
|
14121
|
-
if (this.isWrapped()) {
|
|
14122
|
-
return address >= this.start || address < this.end;
|
|
14123
|
-
}
|
|
14124
|
-
return address >= this.start && address < this.end;
|
|
14166
|
+
getLowNibbleAsRegisterIndex() {
|
|
14167
|
+
return Math.min(this.getLowNibble(), MAX_REGISTER_INDEX);
|
|
14125
14168
|
}
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
|
|
14129
|
-
|
|
14169
|
+
getHighNibbleAsLength() {
|
|
14170
|
+
return Math.min(this.getHighNibble(), MAX_LENGTH);
|
|
14171
|
+
}
|
|
14172
|
+
getLowNibbleAsLength() {
|
|
14173
|
+
return Math.min(this.getLowNibble(), MAX_LENGTH);
|
|
14174
|
+
}
|
|
14175
|
+
}
|
|
14176
|
+
|
|
14177
|
+
const IMMEDIATE_AND_OFFSET_MAX_LENGTH = 4;
|
|
14178
|
+
class ArgsDecoder {
|
|
14179
|
+
nibblesDecoder = new NibblesDecoder();
|
|
14180
|
+
offsetDecoder = new ImmediateDecoder();
|
|
14181
|
+
code = new Uint8Array();
|
|
14182
|
+
mask = Mask.empty();
|
|
14183
|
+
reset(code, mask) {
|
|
14184
|
+
this.code = code;
|
|
14185
|
+
this.mask = mask;
|
|
14186
|
+
}
|
|
14187
|
+
fillArgs(pc, result) {
|
|
14188
|
+
const nextInstructionDistance = 1 + this.mask.getNoOfBytesToNextInstruction(pc + 1);
|
|
14189
|
+
result.noOfBytesToSkip = nextInstructionDistance;
|
|
14190
|
+
switch (result.type) {
|
|
14191
|
+
case ArgumentType.NO_ARGUMENTS:
|
|
14192
|
+
break;
|
|
14193
|
+
case ArgumentType.ONE_IMMEDIATE: {
|
|
14194
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
14195
|
+
const argsStartIndex = pc + 1;
|
|
14196
|
+
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
14197
|
+
break;
|
|
14198
|
+
}
|
|
14199
|
+
case ArgumentType.THREE_REGISTERS: {
|
|
14200
|
+
const firstByte = this.code[pc + 1];
|
|
14201
|
+
const secondByte = this.code[pc + 2];
|
|
14202
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14203
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14204
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14205
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
14206
|
+
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14207
|
+
break;
|
|
14208
|
+
}
|
|
14209
|
+
case ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE: {
|
|
14210
|
+
const firstByte = this.code[pc + 1];
|
|
14211
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14212
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14213
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14214
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
14215
|
+
const immediateStartIndex = pc + 2;
|
|
14216
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14217
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
14218
|
+
break;
|
|
14219
|
+
}
|
|
14220
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET: {
|
|
14221
|
+
const firstByte = this.code[pc + 1];
|
|
14222
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14223
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14224
|
+
const immediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
14225
|
+
const immediateStartIndex = pc + 2;
|
|
14226
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14227
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
14228
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2 - immediateLength));
|
|
14229
|
+
const offsetStartIndex = pc + 2 + immediateLength;
|
|
14230
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14231
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
14232
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
14233
|
+
break;
|
|
14234
|
+
}
|
|
14235
|
+
case ArgumentType.TWO_REGISTERS_ONE_OFFSET: {
|
|
14236
|
+
const firstByte = this.code[pc + 1];
|
|
14237
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14238
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14239
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14240
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
14241
|
+
const offsetStartIndex = pc + 2;
|
|
14242
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14243
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
14244
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
14245
|
+
break;
|
|
14246
|
+
}
|
|
14247
|
+
case ArgumentType.TWO_REGISTERS: {
|
|
14248
|
+
const firstByte = this.code[pc + 1];
|
|
14249
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14250
|
+
result.firstRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14251
|
+
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14252
|
+
break;
|
|
14253
|
+
}
|
|
14254
|
+
case ArgumentType.ONE_OFFSET: {
|
|
14255
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
14256
|
+
const offsetStartIndex = pc + 1;
|
|
14257
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14258
|
+
const offsetBytes = this.code.subarray(offsetStartIndex, offsetEndIndex);
|
|
14259
|
+
this.offsetDecoder.setBytes(offsetBytes);
|
|
14260
|
+
const offsetValue = this.offsetDecoder.getSigned();
|
|
14261
|
+
result.nextPc = pc + offsetValue;
|
|
14262
|
+
break;
|
|
14263
|
+
}
|
|
14264
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE: {
|
|
14265
|
+
const firstByte = this.code[pc + 1];
|
|
14266
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14267
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14268
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
14269
|
+
const immediateStartIndex = pc + 2;
|
|
14270
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14271
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
14272
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
14273
|
+
break;
|
|
14274
|
+
}
|
|
14275
|
+
case ArgumentType.TWO_IMMEDIATES: {
|
|
14276
|
+
const firstByte = this.code[pc + 1];
|
|
14277
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14278
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
14279
|
+
const firstImmediateStartIndex = pc + 2;
|
|
14280
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14281
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14282
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
14283
|
+
const secondImmediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2 - firstImmediateLength));
|
|
14284
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14285
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14286
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14287
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14288
|
+
break;
|
|
14289
|
+
}
|
|
14290
|
+
case ArgumentType.ONE_REGISTER_TWO_IMMEDIATES: {
|
|
14291
|
+
const firstByte = this.code[pc + 1];
|
|
14292
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14293
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14294
|
+
const firstImmediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
14295
|
+
const firstImmediateStartIndex = pc + 2;
|
|
14296
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14297
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14298
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
14299
|
+
const secondImmediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2 - firstImmediateLength));
|
|
14300
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14301
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14302
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14303
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14304
|
+
break;
|
|
14305
|
+
}
|
|
14306
|
+
case ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES: {
|
|
14307
|
+
const firstByte = this.code[pc + 1];
|
|
14308
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14309
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14310
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14311
|
+
const secondByte = this.code[pc + 2];
|
|
14312
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
14313
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
14314
|
+
const firstImmediateStartIndex = pc + 3;
|
|
14315
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14316
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14317
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
14318
|
+
const secondImmediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 3 - firstImmediateLength));
|
|
14319
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14320
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14321
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14322
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14323
|
+
break;
|
|
14324
|
+
}
|
|
14325
|
+
case ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE: {
|
|
14326
|
+
const firstByte = this.code[pc + 1];
|
|
14327
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
14328
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14329
|
+
const immediateStartIndex = pc + 2;
|
|
14330
|
+
const immediateEndIndex = immediateStartIndex + 8;
|
|
14331
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
14332
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
14333
|
+
break;
|
|
14334
|
+
}
|
|
14130
14335
|
}
|
|
14131
|
-
return (this.isInRange(other.start) ||
|
|
14132
|
-
this.isInRange(other.lastIndex) ||
|
|
14133
|
-
other.isInRange(this.start) ||
|
|
14134
|
-
other.isInRange(this.lastIndex));
|
|
14135
14336
|
}
|
|
14136
14337
|
}
|
|
14137
|
-
/**
|
|
14138
|
-
* The first 16 pages of memory are reserved.
|
|
14139
|
-
*
|
|
14140
|
-
* https://graypaper.fluffylabs.dev/#/cc517d7/24d00024d000?v=0.6.5
|
|
14141
|
-
*
|
|
14142
|
-
* it should be in `memory-consts` but it cannot be there because of circular dependency
|
|
14143
|
-
*/
|
|
14144
|
-
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(tryAsMemoryIndex(0), RESERVED_NUMBER_OF_PAGES * PAGE_SIZE$1);
|
|
14145
14338
|
|
|
14146
|
-
|
|
14147
|
-
|
|
14148
|
-
|
|
14149
|
-
|
|
14150
|
-
|
|
14151
|
-
|
|
14152
|
-
|
|
14153
|
-
|
|
14154
|
-
* Exclusive end of the page range.
|
|
14155
|
-
*
|
|
14156
|
-
* NOTE: it may be smaller than `start` in case the range is wrapped.
|
|
14157
|
-
*/
|
|
14158
|
-
end;
|
|
14159
|
-
constructor(start, length) {
|
|
14160
|
-
this.start = start;
|
|
14161
|
-
this.length = length;
|
|
14162
|
-
this.end = tryAsPageNumber((this.start + this.length) % MAX_NUMBER_OF_PAGES);
|
|
14163
|
-
}
|
|
14164
|
-
/**
|
|
14165
|
-
* Creates range of pages that includes all indices in a given memory range.
|
|
14166
|
-
*
|
|
14167
|
-
* Example: For memory range `[PAGE_SIZE, MEMORY_SIZE - PAGE_SIZE)`
|
|
14168
|
-
* we will get `[1, MAX_NUMBER_OF_PAGES - 1)` page range.
|
|
14169
|
-
*/
|
|
14170
|
-
static fromMemoryRange(range) {
|
|
14171
|
-
const startPage = getPageNumber(range.start);
|
|
14172
|
-
if (range.isEmpty()) {
|
|
14173
|
-
return new PageRange(startPage, 0);
|
|
14174
|
-
}
|
|
14175
|
-
// lastIndex is not null because we just ensured that the range is not empty
|
|
14176
|
-
const pageWithLastIndex = getPageNumber(range.lastIndex ?? range.end);
|
|
14177
|
-
const endPage = getNextPageNumber(pageWithLastIndex);
|
|
14178
|
-
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length > PAGE_SIZE$1) {
|
|
14179
|
-
// full range
|
|
14180
|
-
return new PageRange(startPage, MAX_NUMBER_OF_PAGES);
|
|
14181
|
-
}
|
|
14182
|
-
const length = startPage < endPage ? endPage - startPage : MAX_NUMBER_OF_PAGES - startPage + endPage;
|
|
14183
|
-
return PageRange.fromStartAndLength(startPage, length);
|
|
14339
|
+
const IMMEDIATE_SIZE = 8;
|
|
14340
|
+
class ExtendedWitdthImmediateDecoder {
|
|
14341
|
+
unsignedImmediate;
|
|
14342
|
+
bytes;
|
|
14343
|
+
constructor() {
|
|
14344
|
+
const buffer = new ArrayBuffer(IMMEDIATE_SIZE);
|
|
14345
|
+
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
14346
|
+
this.bytes = new Uint8Array(buffer);
|
|
14184
14347
|
}
|
|
14185
|
-
|
|
14186
|
-
|
|
14187
|
-
|
|
14188
|
-
|
|
14348
|
+
setBytes(bytes) {
|
|
14349
|
+
let i = 0;
|
|
14350
|
+
for (; i < bytes.length; i++) {
|
|
14351
|
+
this.bytes[i] = bytes[i];
|
|
14189
14352
|
}
|
|
14190
|
-
|
|
14191
|
-
|
|
14192
|
-
/** Returns true if the page range is wrapped (`start` >= `end`) and is not empty */
|
|
14193
|
-
isWrapped() {
|
|
14194
|
-
return this.start >= this.end && !this.isEmpty();
|
|
14195
|
-
}
|
|
14196
|
-
/** Checks if given page number is within the range */
|
|
14197
|
-
isInRange(page) {
|
|
14198
|
-
if (this.isWrapped()) {
|
|
14199
|
-
return page >= this.start || page < this.end;
|
|
14353
|
+
for (; i < IMMEDIATE_SIZE; i++) {
|
|
14354
|
+
this.bytes[i] = 0;
|
|
14200
14355
|
}
|
|
14201
|
-
return page >= this.start && page < this.end;
|
|
14202
14356
|
}
|
|
14203
|
-
|
|
14204
|
-
|
|
14205
|
-
return this.length === 0;
|
|
14357
|
+
getValue() {
|
|
14358
|
+
return this.unsignedImmediate[0];
|
|
14206
14359
|
}
|
|
14207
|
-
|
|
14208
|
-
|
|
14209
|
-
return;
|
|
14210
|
-
}
|
|
14211
|
-
const end = this.end;
|
|
14212
|
-
let i = this.start;
|
|
14213
|
-
do {
|
|
14214
|
-
yield i;
|
|
14215
|
-
i = getNextPageNumber(i);
|
|
14216
|
-
} while (i !== end);
|
|
14360
|
+
getBytesAsLittleEndian() {
|
|
14361
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE);
|
|
14217
14362
|
}
|
|
14218
14363
|
}
|
|
14219
14364
|
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14365
|
+
const ARGUMENT_TYPE_LENGTH = Object.keys(ArgumentType).length / 2;
|
|
14366
|
+
const createResults = () => {
|
|
14367
|
+
const results = new Array(ARGUMENT_TYPE_LENGTH);
|
|
14368
|
+
results[ArgumentType.NO_ARGUMENTS] = {
|
|
14369
|
+
type: ArgumentType.NO_ARGUMENTS,
|
|
14370
|
+
noOfBytesToSkip: 1,
|
|
14371
|
+
};
|
|
14372
|
+
results[ArgumentType.ONE_IMMEDIATE] = {
|
|
14373
|
+
type: ArgumentType.ONE_IMMEDIATE,
|
|
14374
|
+
noOfBytesToSkip: 1,
|
|
14375
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
14376
|
+
};
|
|
14377
|
+
results[ArgumentType.TWO_REGISTERS] = {
|
|
14378
|
+
type: ArgumentType.TWO_REGISTERS,
|
|
14379
|
+
noOfBytesToSkip: 1,
|
|
14380
|
+
firstRegisterIndex: 0,
|
|
14381
|
+
secondRegisterIndex: 0,
|
|
14382
|
+
};
|
|
14383
|
+
results[ArgumentType.THREE_REGISTERS] = {
|
|
14384
|
+
type: ArgumentType.THREE_REGISTERS,
|
|
14385
|
+
noOfBytesToSkip: 1,
|
|
14386
|
+
firstRegisterIndex: 0,
|
|
14387
|
+
secondRegisterIndex: 0,
|
|
14388
|
+
thirdRegisterIndex: 0,
|
|
14389
|
+
};
|
|
14390
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET] = {
|
|
14391
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET,
|
|
14392
|
+
noOfBytesToSkip: 1,
|
|
14393
|
+
registerIndex: 0,
|
|
14394
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
14395
|
+
nextPc: 0,
|
|
14396
|
+
};
|
|
14397
|
+
results[ArgumentType.TWO_REGISTERS_ONE_OFFSET] = {
|
|
14398
|
+
type: ArgumentType.TWO_REGISTERS_ONE_OFFSET,
|
|
14399
|
+
noOfBytesToSkip: 1,
|
|
14400
|
+
firstRegisterIndex: 0,
|
|
14401
|
+
secondRegisterIndex: 0,
|
|
14402
|
+
nextPc: 0,
|
|
14403
|
+
};
|
|
14404
|
+
results[ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE] = {
|
|
14405
|
+
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE,
|
|
14406
|
+
noOfBytesToSkip: 1,
|
|
14407
|
+
firstRegisterIndex: 0,
|
|
14408
|
+
secondRegisterIndex: 0,
|
|
14409
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
14410
|
+
};
|
|
14411
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE] = {
|
|
14412
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE,
|
|
14413
|
+
noOfBytesToSkip: 1,
|
|
14414
|
+
registerIndex: 0,
|
|
14415
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
14416
|
+
};
|
|
14417
|
+
results[ArgumentType.ONE_REGISTER_TWO_IMMEDIATES] = {
|
|
14418
|
+
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES,
|
|
14419
|
+
noOfBytesToSkip: 1,
|
|
14420
|
+
registerIndex: 0,
|
|
14421
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
14422
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
14423
|
+
};
|
|
14424
|
+
results[ArgumentType.ONE_OFFSET] = {
|
|
14425
|
+
type: ArgumentType.ONE_OFFSET,
|
|
14426
|
+
noOfBytesToSkip: 1,
|
|
14427
|
+
nextPc: 0,
|
|
14428
|
+
};
|
|
14429
|
+
results[ArgumentType.TWO_IMMEDIATES] = {
|
|
14430
|
+
type: ArgumentType.TWO_IMMEDIATES,
|
|
14431
|
+
noOfBytesToSkip: 1,
|
|
14432
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
14433
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
14434
|
+
};
|
|
14435
|
+
results[ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES] = {
|
|
14436
|
+
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES,
|
|
14437
|
+
noOfBytesToSkip: 1,
|
|
14438
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
14439
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
14440
|
+
firstRegisterIndex: 0,
|
|
14441
|
+
secondRegisterIndex: 0,
|
|
14442
|
+
};
|
|
14443
|
+
results[ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE] = {
|
|
14444
|
+
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE,
|
|
14445
|
+
noOfBytesToSkip: 9,
|
|
14446
|
+
registerIndex: 0,
|
|
14447
|
+
immediateDecoder: new ExtendedWitdthImmediateDecoder(),
|
|
14448
|
+
};
|
|
14449
|
+
return results;
|
|
14450
|
+
};
|
|
14451
|
+
|
|
14452
|
+
var Instruction;
|
|
14453
|
+
(function (Instruction) {
|
|
14454
|
+
Instruction[Instruction["TRAP"] = 0] = "TRAP";
|
|
14455
|
+
Instruction[Instruction["FALLTHROUGH"] = 1] = "FALLTHROUGH";
|
|
14456
|
+
Instruction[Instruction["ECALLI"] = 10] = "ECALLI";
|
|
14457
|
+
Instruction[Instruction["LOAD_IMM_64"] = 20] = "LOAD_IMM_64";
|
|
14458
|
+
Instruction[Instruction["STORE_IMM_U8"] = 30] = "STORE_IMM_U8";
|
|
14459
|
+
Instruction[Instruction["STORE_IMM_U16"] = 31] = "STORE_IMM_U16";
|
|
14460
|
+
Instruction[Instruction["STORE_IMM_U32"] = 32] = "STORE_IMM_U32";
|
|
14461
|
+
Instruction[Instruction["STORE_IMM_U64"] = 33] = "STORE_IMM_U64";
|
|
14462
|
+
Instruction[Instruction["JUMP"] = 40] = "JUMP";
|
|
14463
|
+
Instruction[Instruction["JUMP_IND"] = 50] = "JUMP_IND";
|
|
14464
|
+
Instruction[Instruction["LOAD_IMM"] = 51] = "LOAD_IMM";
|
|
14465
|
+
Instruction[Instruction["LOAD_U8"] = 52] = "LOAD_U8";
|
|
14466
|
+
Instruction[Instruction["LOAD_I8"] = 53] = "LOAD_I8";
|
|
14467
|
+
Instruction[Instruction["LOAD_U16"] = 54] = "LOAD_U16";
|
|
14468
|
+
Instruction[Instruction["LOAD_I16"] = 55] = "LOAD_I16";
|
|
14469
|
+
Instruction[Instruction["LOAD_U32"] = 56] = "LOAD_U32";
|
|
14470
|
+
Instruction[Instruction["LOAD_I32"] = 57] = "LOAD_I32";
|
|
14471
|
+
Instruction[Instruction["LOAD_U64"] = 58] = "LOAD_U64";
|
|
14472
|
+
Instruction[Instruction["STORE_U8"] = 59] = "STORE_U8";
|
|
14473
|
+
Instruction[Instruction["STORE_U16"] = 60] = "STORE_U16";
|
|
14474
|
+
Instruction[Instruction["STORE_U32"] = 61] = "STORE_U32";
|
|
14475
|
+
Instruction[Instruction["STORE_U64"] = 62] = "STORE_U64";
|
|
14476
|
+
Instruction[Instruction["STORE_IMM_IND_U8"] = 70] = "STORE_IMM_IND_U8";
|
|
14477
|
+
Instruction[Instruction["STORE_IMM_IND_U16"] = 71] = "STORE_IMM_IND_U16";
|
|
14478
|
+
Instruction[Instruction["STORE_IMM_IND_U32"] = 72] = "STORE_IMM_IND_U32";
|
|
14479
|
+
Instruction[Instruction["STORE_IMM_IND_U64"] = 73] = "STORE_IMM_IND_U64";
|
|
14480
|
+
Instruction[Instruction["LOAD_IMM_JUMP"] = 80] = "LOAD_IMM_JUMP";
|
|
14481
|
+
Instruction[Instruction["BRANCH_EQ_IMM"] = 81] = "BRANCH_EQ_IMM";
|
|
14482
|
+
Instruction[Instruction["BRANCH_NE_IMM"] = 82] = "BRANCH_NE_IMM";
|
|
14483
|
+
Instruction[Instruction["BRANCH_LT_U_IMM"] = 83] = "BRANCH_LT_U_IMM";
|
|
14484
|
+
Instruction[Instruction["BRANCH_LE_U_IMM"] = 84] = "BRANCH_LE_U_IMM";
|
|
14485
|
+
Instruction[Instruction["BRANCH_GE_U_IMM"] = 85] = "BRANCH_GE_U_IMM";
|
|
14486
|
+
Instruction[Instruction["BRANCH_GT_U_IMM"] = 86] = "BRANCH_GT_U_IMM";
|
|
14487
|
+
Instruction[Instruction["BRANCH_LT_S_IMM"] = 87] = "BRANCH_LT_S_IMM";
|
|
14488
|
+
Instruction[Instruction["BRANCH_LE_S_IMM"] = 88] = "BRANCH_LE_S_IMM";
|
|
14489
|
+
Instruction[Instruction["BRANCH_GE_S_IMM"] = 89] = "BRANCH_GE_S_IMM";
|
|
14490
|
+
Instruction[Instruction["BRANCH_GT_S_IMM"] = 90] = "BRANCH_GT_S_IMM";
|
|
14491
|
+
Instruction[Instruction["MOVE_REG"] = 100] = "MOVE_REG";
|
|
14492
|
+
Instruction[Instruction["SBRK"] = 101] = "SBRK";
|
|
14493
|
+
Instruction[Instruction["COUNT_SET_BITS_64"] = 102] = "COUNT_SET_BITS_64";
|
|
14494
|
+
Instruction[Instruction["COUNT_SET_BITS_32"] = 103] = "COUNT_SET_BITS_32";
|
|
14495
|
+
Instruction[Instruction["LEADING_ZERO_BITS_64"] = 104] = "LEADING_ZERO_BITS_64";
|
|
14496
|
+
Instruction[Instruction["LEADING_ZERO_BITS_32"] = 105] = "LEADING_ZERO_BITS_32";
|
|
14497
|
+
Instruction[Instruction["TRAILING_ZERO_BITS_64"] = 106] = "TRAILING_ZERO_BITS_64";
|
|
14498
|
+
Instruction[Instruction["TRAILING_ZERO_BITS_32"] = 107] = "TRAILING_ZERO_BITS_32";
|
|
14499
|
+
Instruction[Instruction["SIGN_EXTEND_8"] = 108] = "SIGN_EXTEND_8";
|
|
14500
|
+
Instruction[Instruction["SIGN_EXTEND_16"] = 109] = "SIGN_EXTEND_16";
|
|
14501
|
+
Instruction[Instruction["ZERO_EXTEND_16"] = 110] = "ZERO_EXTEND_16";
|
|
14502
|
+
Instruction[Instruction["REVERSE_BYTES"] = 111] = "REVERSE_BYTES";
|
|
14503
|
+
Instruction[Instruction["STORE_IND_U8"] = 120] = "STORE_IND_U8";
|
|
14504
|
+
Instruction[Instruction["STORE_IND_U16"] = 121] = "STORE_IND_U16";
|
|
14505
|
+
Instruction[Instruction["STORE_IND_U32"] = 122] = "STORE_IND_U32";
|
|
14506
|
+
Instruction[Instruction["STORE_IND_U64"] = 123] = "STORE_IND_U64";
|
|
14507
|
+
Instruction[Instruction["LOAD_IND_U8"] = 124] = "LOAD_IND_U8";
|
|
14508
|
+
Instruction[Instruction["LOAD_IND_I8"] = 125] = "LOAD_IND_I8";
|
|
14509
|
+
Instruction[Instruction["LOAD_IND_U16"] = 126] = "LOAD_IND_U16";
|
|
14510
|
+
Instruction[Instruction["LOAD_IND_I16"] = 127] = "LOAD_IND_I16";
|
|
14511
|
+
Instruction[Instruction["LOAD_IND_U32"] = 128] = "LOAD_IND_U32";
|
|
14512
|
+
Instruction[Instruction["LOAD_IND_I32"] = 129] = "LOAD_IND_I32";
|
|
14513
|
+
Instruction[Instruction["LOAD_IND_U64"] = 130] = "LOAD_IND_U64";
|
|
14514
|
+
Instruction[Instruction["ADD_IMM_32"] = 131] = "ADD_IMM_32";
|
|
14515
|
+
Instruction[Instruction["AND_IMM"] = 132] = "AND_IMM";
|
|
14516
|
+
Instruction[Instruction["XOR_IMM"] = 133] = "XOR_IMM";
|
|
14517
|
+
Instruction[Instruction["OR_IMM"] = 134] = "OR_IMM";
|
|
14518
|
+
Instruction[Instruction["MUL_IMM_32"] = 135] = "MUL_IMM_32";
|
|
14519
|
+
Instruction[Instruction["SET_LT_U_IMM"] = 136] = "SET_LT_U_IMM";
|
|
14520
|
+
Instruction[Instruction["SET_LT_S_IMM"] = 137] = "SET_LT_S_IMM";
|
|
14521
|
+
Instruction[Instruction["SHLO_L_IMM_32"] = 138] = "SHLO_L_IMM_32";
|
|
14522
|
+
Instruction[Instruction["SHLO_R_IMM_32"] = 139] = "SHLO_R_IMM_32";
|
|
14523
|
+
Instruction[Instruction["SHAR_R_IMM_32"] = 140] = "SHAR_R_IMM_32";
|
|
14524
|
+
Instruction[Instruction["NEG_ADD_IMM_32"] = 141] = "NEG_ADD_IMM_32";
|
|
14525
|
+
Instruction[Instruction["SET_GT_U_IMM"] = 142] = "SET_GT_U_IMM";
|
|
14526
|
+
Instruction[Instruction["SET_GT_S_IMM"] = 143] = "SET_GT_S_IMM";
|
|
14527
|
+
Instruction[Instruction["SHLO_L_IMM_ALT_32"] = 144] = "SHLO_L_IMM_ALT_32";
|
|
14528
|
+
Instruction[Instruction["SHLO_R_IMM_ALT_32"] = 145] = "SHLO_R_IMM_ALT_32";
|
|
14529
|
+
Instruction[Instruction["SHAR_R_IMM_ALT_32"] = 146] = "SHAR_R_IMM_ALT_32";
|
|
14530
|
+
Instruction[Instruction["CMOV_IZ_IMM"] = 147] = "CMOV_IZ_IMM";
|
|
14531
|
+
Instruction[Instruction["CMOV_NZ_IMM"] = 148] = "CMOV_NZ_IMM";
|
|
14532
|
+
Instruction[Instruction["ADD_IMM_64"] = 149] = "ADD_IMM_64";
|
|
14533
|
+
Instruction[Instruction["MUL_IMM_64"] = 150] = "MUL_IMM_64";
|
|
14534
|
+
Instruction[Instruction["SHLO_L_IMM_64"] = 151] = "SHLO_L_IMM_64";
|
|
14535
|
+
Instruction[Instruction["SHLO_R_IMM_64"] = 152] = "SHLO_R_IMM_64";
|
|
14536
|
+
Instruction[Instruction["SHAR_R_IMM_64"] = 153] = "SHAR_R_IMM_64";
|
|
14537
|
+
Instruction[Instruction["NEG_ADD_IMM_64"] = 154] = "NEG_ADD_IMM_64";
|
|
14538
|
+
Instruction[Instruction["SHLO_L_IMM_ALT_64"] = 155] = "SHLO_L_IMM_ALT_64";
|
|
14539
|
+
Instruction[Instruction["SHLO_R_IMM_ALT_64"] = 156] = "SHLO_R_IMM_ALT_64";
|
|
14540
|
+
Instruction[Instruction["SHAR_R_IMM_ALT_64"] = 157] = "SHAR_R_IMM_ALT_64";
|
|
14541
|
+
Instruction[Instruction["ROT_R_64_IMM"] = 158] = "ROT_R_64_IMM";
|
|
14542
|
+
Instruction[Instruction["ROT_R_64_IMM_ALT"] = 159] = "ROT_R_64_IMM_ALT";
|
|
14543
|
+
Instruction[Instruction["ROT_R_32_IMM"] = 160] = "ROT_R_32_IMM";
|
|
14544
|
+
Instruction[Instruction["ROT_R_32_IMM_ALT"] = 161] = "ROT_R_32_IMM_ALT";
|
|
14545
|
+
Instruction[Instruction["BRANCH_EQ"] = 170] = "BRANCH_EQ";
|
|
14546
|
+
Instruction[Instruction["BRANCH_NE"] = 171] = "BRANCH_NE";
|
|
14547
|
+
Instruction[Instruction["BRANCH_LT_U"] = 172] = "BRANCH_LT_U";
|
|
14548
|
+
Instruction[Instruction["BRANCH_LT_S"] = 173] = "BRANCH_LT_S";
|
|
14549
|
+
Instruction[Instruction["BRANCH_GE_U"] = 174] = "BRANCH_GE_U";
|
|
14550
|
+
Instruction[Instruction["BRANCH_GE_S"] = 175] = "BRANCH_GE_S";
|
|
14551
|
+
Instruction[Instruction["LOAD_IMM_JUMP_IND"] = 180] = "LOAD_IMM_JUMP_IND";
|
|
14552
|
+
Instruction[Instruction["ADD_32"] = 190] = "ADD_32";
|
|
14553
|
+
Instruction[Instruction["SUB_32"] = 191] = "SUB_32";
|
|
14554
|
+
Instruction[Instruction["MUL_32"] = 192] = "MUL_32";
|
|
14555
|
+
Instruction[Instruction["DIV_U_32"] = 193] = "DIV_U_32";
|
|
14556
|
+
Instruction[Instruction["DIV_S_32"] = 194] = "DIV_S_32";
|
|
14557
|
+
Instruction[Instruction["REM_U_32"] = 195] = "REM_U_32";
|
|
14558
|
+
Instruction[Instruction["REM_S_32"] = 196] = "REM_S_32";
|
|
14559
|
+
Instruction[Instruction["SHLO_L_32"] = 197] = "SHLO_L_32";
|
|
14560
|
+
Instruction[Instruction["SHLO_R_32"] = 198] = "SHLO_R_32";
|
|
14561
|
+
Instruction[Instruction["SHAR_R_32"] = 199] = "SHAR_R_32";
|
|
14562
|
+
Instruction[Instruction["ADD_64"] = 200] = "ADD_64";
|
|
14563
|
+
Instruction[Instruction["SUB_64"] = 201] = "SUB_64";
|
|
14564
|
+
Instruction[Instruction["MUL_64"] = 202] = "MUL_64";
|
|
14565
|
+
Instruction[Instruction["DIV_U_64"] = 203] = "DIV_U_64";
|
|
14566
|
+
Instruction[Instruction["DIV_S_64"] = 204] = "DIV_S_64";
|
|
14567
|
+
Instruction[Instruction["REM_U_64"] = 205] = "REM_U_64";
|
|
14568
|
+
Instruction[Instruction["REM_S_64"] = 206] = "REM_S_64";
|
|
14569
|
+
Instruction[Instruction["SHLO_L_64"] = 207] = "SHLO_L_64";
|
|
14570
|
+
Instruction[Instruction["SHLO_R_64"] = 208] = "SHLO_R_64";
|
|
14571
|
+
Instruction[Instruction["SHAR_R_64"] = 209] = "SHAR_R_64";
|
|
14572
|
+
Instruction[Instruction["AND"] = 210] = "AND";
|
|
14573
|
+
Instruction[Instruction["XOR"] = 211] = "XOR";
|
|
14574
|
+
Instruction[Instruction["OR"] = 212] = "OR";
|
|
14575
|
+
Instruction[Instruction["MUL_UPPER_S_S"] = 213] = "MUL_UPPER_S_S";
|
|
14576
|
+
Instruction[Instruction["MUL_UPPER_U_U"] = 214] = "MUL_UPPER_U_U";
|
|
14577
|
+
Instruction[Instruction["MUL_UPPER_S_U"] = 215] = "MUL_UPPER_S_U";
|
|
14578
|
+
Instruction[Instruction["SET_LT_U"] = 216] = "SET_LT_U";
|
|
14579
|
+
Instruction[Instruction["SET_LT_S"] = 217] = "SET_LT_S";
|
|
14580
|
+
Instruction[Instruction["CMOV_IZ"] = 218] = "CMOV_IZ";
|
|
14581
|
+
Instruction[Instruction["CMOV_NZ"] = 219] = "CMOV_NZ";
|
|
14582
|
+
Instruction[Instruction["ROT_L_64"] = 220] = "ROT_L_64";
|
|
14583
|
+
Instruction[Instruction["ROT_L_32"] = 221] = "ROT_L_32";
|
|
14584
|
+
Instruction[Instruction["ROT_R_64"] = 222] = "ROT_R_64";
|
|
14585
|
+
Instruction[Instruction["ROT_R_32"] = 223] = "ROT_R_32";
|
|
14586
|
+
Instruction[Instruction["AND_INV"] = 224] = "AND_INV";
|
|
14587
|
+
Instruction[Instruction["OR_INV"] = 225] = "OR_INV";
|
|
14588
|
+
Instruction[Instruction["XNOR"] = 226] = "XNOR";
|
|
14589
|
+
Instruction[Instruction["MAX"] = 227] = "MAX";
|
|
14590
|
+
Instruction[Instruction["MAX_U"] = 228] = "MAX_U";
|
|
14591
|
+
Instruction[Instruction["MIN"] = 229] = "MIN";
|
|
14592
|
+
Instruction[Instruction["MIN_U"] = 230] = "MIN_U";
|
|
14593
|
+
})(Instruction || (Instruction = {}));
|
|
14594
|
+
const HIGHEST_INSTRUCTION_NUMBER = Instruction.MIN_U;
|
|
14226
14595
|
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
|
|
14230
|
-
|
|
14231
|
-
|
|
14232
|
-
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
|
|
14236
|
-
|
|
14237
|
-
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14242
|
-
|
|
14243
|
-
|
|
14244
|
-
|
|
14245
|
-
|
|
14246
|
-
|
|
14247
|
-
|
|
14248
|
-
|
|
14249
|
-
|
|
14250
|
-
|
|
14251
|
-
|
|
14252
|
-
|
|
14253
|
-
|
|
14254
|
-
|
|
14255
|
-
|
|
14256
|
-
|
|
14596
|
+
const instructionArgumentTypeMap = (() => {
|
|
14597
|
+
const instructionArgumentTypeMap = new Array(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
14598
|
+
instructionArgumentTypeMap[Instruction.TRAP] = ArgumentType.NO_ARGUMENTS;
|
|
14599
|
+
instructionArgumentTypeMap[Instruction.FALLTHROUGH] = ArgumentType.NO_ARGUMENTS;
|
|
14600
|
+
instructionArgumentTypeMap[Instruction.ECALLI] = ArgumentType.ONE_IMMEDIATE;
|
|
14601
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_64] = ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
14602
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U8] = ArgumentType.TWO_IMMEDIATES;
|
|
14603
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U16] = ArgumentType.TWO_IMMEDIATES;
|
|
14604
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U32] = ArgumentType.TWO_IMMEDIATES;
|
|
14605
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U64] = ArgumentType.TWO_IMMEDIATES;
|
|
14606
|
+
instructionArgumentTypeMap[Instruction.JUMP] = ArgumentType.ONE_OFFSET;
|
|
14607
|
+
instructionArgumentTypeMap[Instruction.JUMP_IND] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14608
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14609
|
+
instructionArgumentTypeMap[Instruction.LOAD_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14610
|
+
instructionArgumentTypeMap[Instruction.LOAD_I8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14611
|
+
instructionArgumentTypeMap[Instruction.LOAD_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14612
|
+
instructionArgumentTypeMap[Instruction.LOAD_I16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14613
|
+
instructionArgumentTypeMap[Instruction.LOAD_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14614
|
+
instructionArgumentTypeMap[Instruction.LOAD_I32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14615
|
+
instructionArgumentTypeMap[Instruction.LOAD_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14616
|
+
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14617
|
+
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14618
|
+
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14619
|
+
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14620
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U8] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
14621
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U16] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
14622
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
14623
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
14624
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14625
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14626
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14627
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14628
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14629
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14630
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14631
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14632
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14633
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14634
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
14635
|
+
instructionArgumentTypeMap[Instruction.MOVE_REG] = ArgumentType.TWO_REGISTERS;
|
|
14636
|
+
instructionArgumentTypeMap[Instruction.SBRK] = ArgumentType.TWO_REGISTERS;
|
|
14637
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
14638
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
14639
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
14640
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
14641
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
14642
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
14643
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_8] = ArgumentType.TWO_REGISTERS;
|
|
14644
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
14645
|
+
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
14646
|
+
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
14647
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14648
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14649
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14650
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14651
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14652
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14653
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14654
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14655
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14656
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14657
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14658
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14659
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14660
|
+
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14661
|
+
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14662
|
+
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14663
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14664
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14665
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14666
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14667
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14668
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14669
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14670
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14671
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14672
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14673
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14674
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14675
|
+
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14676
|
+
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14677
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14678
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14679
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14680
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14681
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14682
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14683
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14684
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14685
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14686
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14687
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14688
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14689
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
14690
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
14691
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
14692
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
14693
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
14694
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
14695
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP_IND] = ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
14696
|
+
instructionArgumentTypeMap[Instruction.ADD_32] = ArgumentType.THREE_REGISTERS;
|
|
14697
|
+
instructionArgumentTypeMap[Instruction.ADD_64] = ArgumentType.THREE_REGISTERS;
|
|
14698
|
+
instructionArgumentTypeMap[Instruction.SUB_32] = ArgumentType.THREE_REGISTERS;
|
|
14699
|
+
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
14700
|
+
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
14701
|
+
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
14702
|
+
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
14703
|
+
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
14704
|
+
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
14705
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
14706
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
14707
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
14708
|
+
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
14709
|
+
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
14710
|
+
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
14711
|
+
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
14712
|
+
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
14713
|
+
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
14714
|
+
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
14715
|
+
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
14716
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
14717
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
14718
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
14719
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
14720
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
14721
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
14722
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
14723
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
14724
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
14725
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
14726
|
+
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
14727
|
+
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
14728
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
14729
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
14730
|
+
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
14731
|
+
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
14732
|
+
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
14733
|
+
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
14734
|
+
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
14735
|
+
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
14736
|
+
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
14737
|
+
return instructionArgumentTypeMap;
|
|
14738
|
+
})();
|
|
14257
14739
|
|
|
14258
|
-
|
|
14259
|
-
|
|
14260
|
-
|
|
14261
|
-
|
|
14262
|
-
|
|
14263
|
-
|
|
14264
|
-
|
|
14265
|
-
|
|
14266
|
-
|
|
14267
|
-
|
|
14268
|
-
|
|
14269
|
-
|
|
14270
|
-
|
|
14271
|
-
|
|
14272
|
-
|
|
14273
|
-
|
|
14274
|
-
|
|
14275
|
-
|
|
14276
|
-
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
|
|
14280
|
-
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
|
|
14284
|
-
|
|
14285
|
-
|
|
14740
|
+
const instructionsWithoutArgs = [
|
|
14741
|
+
[Instruction.TRAP, 1],
|
|
14742
|
+
[Instruction.FALLTHROUGH, 1],
|
|
14743
|
+
];
|
|
14744
|
+
const instructionsWithOneImmediate = [[Instruction.ECALLI, 1]];
|
|
14745
|
+
const instructionsWithOneRegisterAndOneExtendedWidthImmediate = [[Instruction.LOAD_IMM_64, 1]];
|
|
14746
|
+
const instructionsWithTwoImmediates = [
|
|
14747
|
+
[Instruction.STORE_IMM_U8, 1],
|
|
14748
|
+
[Instruction.STORE_IMM_U16, 1],
|
|
14749
|
+
[Instruction.STORE_IMM_U32, 1],
|
|
14750
|
+
[Instruction.STORE_IMM_U64, 1],
|
|
14751
|
+
];
|
|
14752
|
+
const instructionsWithOneOffset = [[Instruction.JUMP, 1]];
|
|
14753
|
+
const instructionsWithOneRegisterAndOneImmediate = [
|
|
14754
|
+
[Instruction.JUMP_IND, 1],
|
|
14755
|
+
[Instruction.LOAD_IMM, 1],
|
|
14756
|
+
[Instruction.LOAD_U8, 1],
|
|
14757
|
+
[Instruction.LOAD_I8, 1],
|
|
14758
|
+
[Instruction.LOAD_U16, 1],
|
|
14759
|
+
[Instruction.LOAD_I16, 1],
|
|
14760
|
+
[Instruction.LOAD_U32, 1],
|
|
14761
|
+
[Instruction.LOAD_I32, 1],
|
|
14762
|
+
[Instruction.LOAD_U64, 1],
|
|
14763
|
+
[Instruction.STORE_U8, 1],
|
|
14764
|
+
[Instruction.STORE_U16, 1],
|
|
14765
|
+
[Instruction.STORE_U32, 1],
|
|
14766
|
+
[Instruction.STORE_U64, 1],
|
|
14767
|
+
];
|
|
14768
|
+
const instructionsWithOneRegisterAndTwoImmediate = [
|
|
14769
|
+
[Instruction.STORE_IMM_IND_U8, 1],
|
|
14770
|
+
[Instruction.STORE_IMM_IND_U16, 1],
|
|
14771
|
+
[Instruction.STORE_IMM_IND_U32, 1],
|
|
14772
|
+
[Instruction.STORE_IMM_IND_U64, 1],
|
|
14773
|
+
];
|
|
14774
|
+
const instructionsWithOneRegisterOneImmediateAndOneOffset = [
|
|
14775
|
+
[Instruction.LOAD_IMM_JUMP, 1],
|
|
14776
|
+
[Instruction.BRANCH_EQ_IMM, 1],
|
|
14777
|
+
[Instruction.BRANCH_NE_IMM, 1],
|
|
14778
|
+
[Instruction.BRANCH_LT_U_IMM, 1],
|
|
14779
|
+
[Instruction.BRANCH_LE_U_IMM, 1],
|
|
14780
|
+
[Instruction.BRANCH_GE_U_IMM, 1],
|
|
14781
|
+
[Instruction.BRANCH_GT_U_IMM, 1],
|
|
14782
|
+
[Instruction.BRANCH_LT_S_IMM, 1],
|
|
14783
|
+
[Instruction.BRANCH_LE_S_IMM, 1],
|
|
14784
|
+
[Instruction.BRANCH_GE_S_IMM, 1],
|
|
14785
|
+
[Instruction.BRANCH_GT_S_IMM, 1],
|
|
14786
|
+
];
|
|
14787
|
+
const instructionsWithTwoRegisters = [
|
|
14788
|
+
[Instruction.MOVE_REG, 1],
|
|
14789
|
+
[Instruction.SBRK, 1],
|
|
14790
|
+
[Instruction.COUNT_SET_BITS_64, 1],
|
|
14791
|
+
[Instruction.COUNT_SET_BITS_32, 1],
|
|
14792
|
+
[Instruction.LEADING_ZERO_BITS_64, 1],
|
|
14793
|
+
[Instruction.LEADING_ZERO_BITS_32, 1],
|
|
14794
|
+
[Instruction.TRAILING_ZERO_BITS_64, 1],
|
|
14795
|
+
[Instruction.TRAILING_ZERO_BITS_32, 1],
|
|
14796
|
+
[Instruction.SIGN_EXTEND_8, 1],
|
|
14797
|
+
[Instruction.SIGN_EXTEND_16, 1],
|
|
14798
|
+
[Instruction.ZERO_EXTEND_16, 1],
|
|
14799
|
+
[Instruction.REVERSE_BYTES, 1],
|
|
14800
|
+
];
|
|
14801
|
+
const instructionsWithTwoRegistersAndOneImmediate = [
|
|
14802
|
+
[Instruction.STORE_IND_U8, 1],
|
|
14803
|
+
[Instruction.STORE_IND_U16, 1],
|
|
14804
|
+
[Instruction.STORE_IND_U32, 1],
|
|
14805
|
+
[Instruction.STORE_IND_U64, 1],
|
|
14806
|
+
[Instruction.LOAD_IND_U8, 1],
|
|
14807
|
+
[Instruction.LOAD_IND_I8, 1],
|
|
14808
|
+
[Instruction.LOAD_IND_U16, 1],
|
|
14809
|
+
[Instruction.LOAD_IND_I16, 1],
|
|
14810
|
+
[Instruction.LOAD_IND_U32, 1],
|
|
14811
|
+
[Instruction.LOAD_IND_I32, 1],
|
|
14812
|
+
[Instruction.LOAD_IND_U64, 1],
|
|
14813
|
+
[Instruction.ADD_IMM_32, 1],
|
|
14814
|
+
[Instruction.AND_IMM, 1],
|
|
14815
|
+
[Instruction.XOR_IMM, 1],
|
|
14816
|
+
[Instruction.OR_IMM, 1],
|
|
14817
|
+
[Instruction.MUL_IMM_32, 1],
|
|
14818
|
+
[Instruction.SET_LT_U_IMM, 1],
|
|
14819
|
+
[Instruction.SET_LT_S_IMM, 1],
|
|
14820
|
+
[Instruction.SHLO_L_IMM_32, 1],
|
|
14821
|
+
[Instruction.SHLO_R_IMM_32, 1],
|
|
14822
|
+
[Instruction.SHAR_R_IMM_32, 1],
|
|
14823
|
+
[Instruction.NEG_ADD_IMM_32, 1],
|
|
14824
|
+
[Instruction.SET_GT_U_IMM, 1],
|
|
14825
|
+
[Instruction.SET_GT_S_IMM, 1],
|
|
14826
|
+
[Instruction.SHLO_L_IMM_ALT_32, 1],
|
|
14827
|
+
[Instruction.SHLO_R_IMM_ALT_32, 1],
|
|
14828
|
+
[Instruction.SHAR_R_IMM_ALT_32, 1],
|
|
14829
|
+
[Instruction.CMOV_IZ_IMM, 1],
|
|
14830
|
+
[Instruction.CMOV_NZ_IMM, 1],
|
|
14831
|
+
[Instruction.ADD_IMM_64, 1],
|
|
14832
|
+
[Instruction.MUL_IMM_64, 1],
|
|
14833
|
+
[Instruction.SHLO_L_IMM_64, 1],
|
|
14834
|
+
[Instruction.SHLO_R_IMM_64, 1],
|
|
14835
|
+
[Instruction.SHAR_R_IMM_64, 1],
|
|
14836
|
+
[Instruction.NEG_ADD_IMM_64, 1],
|
|
14837
|
+
[Instruction.SHLO_L_IMM_ALT_64, 1],
|
|
14838
|
+
[Instruction.SHLO_R_IMM_ALT_64, 1],
|
|
14839
|
+
[Instruction.SHAR_R_IMM_ALT_64, 1],
|
|
14840
|
+
[Instruction.ROT_R_64_IMM, 1],
|
|
14841
|
+
[Instruction.ROT_R_64_IMM_ALT, 1],
|
|
14842
|
+
[Instruction.ROT_R_32_IMM, 1],
|
|
14843
|
+
[Instruction.ROT_R_32_IMM_ALT, 1],
|
|
14844
|
+
];
|
|
14845
|
+
const instructionsWithTwoRegistersAndOneOffset = [
|
|
14846
|
+
[Instruction.BRANCH_EQ, 1],
|
|
14847
|
+
[Instruction.BRANCH_NE, 1],
|
|
14848
|
+
[Instruction.BRANCH_LT_U, 1],
|
|
14849
|
+
[Instruction.BRANCH_LT_S, 1],
|
|
14850
|
+
[Instruction.BRANCH_GE_U, 1],
|
|
14851
|
+
[Instruction.BRANCH_GE_S, 1],
|
|
14852
|
+
];
|
|
14853
|
+
const instructionWithTwoRegistersAndTwoImmediates = [[Instruction.LOAD_IMM_JUMP_IND, 1]];
|
|
14854
|
+
const instructionsWithThreeRegisters = [
|
|
14855
|
+
[Instruction.ADD_32, 1],
|
|
14856
|
+
[Instruction.SUB_32, 1],
|
|
14857
|
+
[Instruction.MUL_32, 1],
|
|
14858
|
+
[Instruction.DIV_U_32, 1],
|
|
14859
|
+
[Instruction.DIV_S_32, 1],
|
|
14860
|
+
[Instruction.REM_U_32, 1],
|
|
14861
|
+
[Instruction.REM_S_32, 1],
|
|
14862
|
+
[Instruction.SHLO_L_32, 1],
|
|
14863
|
+
[Instruction.SHLO_R_32, 1],
|
|
14864
|
+
[Instruction.SHAR_R_32, 1],
|
|
14865
|
+
[Instruction.ADD_64, 1],
|
|
14866
|
+
[Instruction.SUB_64, 1],
|
|
14867
|
+
[Instruction.MUL_64, 1],
|
|
14868
|
+
[Instruction.DIV_U_64, 1],
|
|
14869
|
+
[Instruction.DIV_S_64, 1],
|
|
14870
|
+
[Instruction.REM_U_64, 1],
|
|
14871
|
+
[Instruction.REM_S_64, 1],
|
|
14872
|
+
[Instruction.SHLO_L_64, 1],
|
|
14873
|
+
[Instruction.SHLO_R_64, 1],
|
|
14874
|
+
[Instruction.SHAR_R_64, 1],
|
|
14875
|
+
[Instruction.AND, 1],
|
|
14876
|
+
[Instruction.XOR, 1],
|
|
14877
|
+
[Instruction.OR, 1],
|
|
14878
|
+
[Instruction.MUL_UPPER_S_S, 1],
|
|
14879
|
+
[Instruction.MUL_UPPER_U_U, 1],
|
|
14880
|
+
[Instruction.MUL_UPPER_S_U, 1],
|
|
14881
|
+
[Instruction.SET_LT_U, 1],
|
|
14882
|
+
[Instruction.SET_LT_S, 1],
|
|
14883
|
+
[Instruction.CMOV_IZ, 1],
|
|
14884
|
+
[Instruction.CMOV_NZ, 1],
|
|
14885
|
+
[Instruction.ROT_L_64, 1],
|
|
14886
|
+
[Instruction.ROT_L_32, 1],
|
|
14887
|
+
[Instruction.ROT_R_64, 1],
|
|
14888
|
+
[Instruction.ROT_R_32, 1],
|
|
14889
|
+
[Instruction.AND_INV, 1],
|
|
14890
|
+
[Instruction.OR_INV, 1],
|
|
14891
|
+
[Instruction.XNOR, 1],
|
|
14892
|
+
[Instruction.MAX, 1],
|
|
14893
|
+
[Instruction.MAX_U, 1],
|
|
14894
|
+
[Instruction.MIN, 1],
|
|
14895
|
+
[Instruction.MIN_U, 1],
|
|
14896
|
+
];
|
|
14897
|
+
const instructions = [
|
|
14898
|
+
...instructionsWithoutArgs,
|
|
14899
|
+
...instructionsWithOneImmediate,
|
|
14900
|
+
...instructionsWithOneRegisterAndOneExtendedWidthImmediate,
|
|
14901
|
+
...instructionsWithTwoImmediates,
|
|
14902
|
+
...instructionsWithOneOffset,
|
|
14903
|
+
...instructionsWithOneRegisterAndOneImmediate,
|
|
14904
|
+
...instructionsWithOneRegisterAndTwoImmediate,
|
|
14905
|
+
...instructionsWithOneRegisterOneImmediateAndOneOffset,
|
|
14906
|
+
...instructionsWithTwoRegisters,
|
|
14907
|
+
...instructionsWithTwoRegistersAndOneImmediate,
|
|
14908
|
+
...instructionsWithTwoRegistersAndOneOffset,
|
|
14909
|
+
...instructionWithTwoRegistersAndTwoImmediates,
|
|
14910
|
+
...instructionsWithThreeRegisters,
|
|
14911
|
+
];
|
|
14912
|
+
const createOpCodeEntry = ([byte, gas]) => [byte, { gas: tryAsSmallGas(gas) }];
|
|
14913
|
+
const byteToOpCodeMap = instructions.reduce((acc, instruction) => {
|
|
14914
|
+
const [byte, opCode] = createOpCodeEntry(instruction);
|
|
14915
|
+
acc[byte] = opCode;
|
|
14916
|
+
return acc;
|
|
14917
|
+
}, {});
|
|
14918
|
+
function assemblify(program, mask) {
|
|
14919
|
+
return program.reduce((acc, byte, index) => {
|
|
14920
|
+
if (mask.isInstruction(index)) {
|
|
14921
|
+
acc.push([Instruction[byte]]);
|
|
14286
14922
|
}
|
|
14287
|
-
|
|
14288
|
-
|
|
14289
|
-
}
|
|
14290
|
-
setData(pageIndex, data) {
|
|
14291
|
-
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength < PAGE_SIZE$1) {
|
|
14292
|
-
const newLength = Math.min(PAGE_SIZE$1, Math.max(MIN_ALLOCATION_LENGTH, pageIndex + data.length));
|
|
14293
|
-
this.buffer.resize(newLength);
|
|
14923
|
+
else {
|
|
14924
|
+
acc[acc.length - 1].push(byte);
|
|
14294
14925
|
}
|
|
14295
|
-
|
|
14296
|
-
}
|
|
14297
|
-
isWriteable() {
|
|
14298
|
-
return true;
|
|
14299
|
-
}
|
|
14300
|
-
getPageDump() {
|
|
14301
|
-
return this.view;
|
|
14302
|
-
}
|
|
14926
|
+
return acc;
|
|
14927
|
+
}, []);
|
|
14303
14928
|
}
|
|
14304
14929
|
|
|
14305
|
-
|
|
14306
|
-
(
|
|
14307
|
-
|
|
14308
|
-
|
|
14309
|
-
|
|
14310
|
-
|
|
14311
|
-
|
|
14312
|
-
|
|
14313
|
-
|
|
14314
|
-
|
|
14315
|
-
|
|
14316
|
-
|
|
14317
|
-
|
|
14318
|
-
|
|
14319
|
-
|
|
14320
|
-
|
|
14321
|
-
|
|
14322
|
-
|
|
14323
|
-
|
|
14324
|
-
|
|
14325
|
-
|
|
14326
|
-
|
|
14327
|
-
|
|
14328
|
-
|
|
14329
|
-
|
|
14330
|
-
|
|
14331
|
-
|
|
14332
|
-
|
|
14333
|
-
|
|
14334
|
-
|
|
14335
|
-
|
|
14336
|
-
|
|
14337
|
-
|
|
14338
|
-
|
|
14339
|
-
|
|
14340
|
-
|
|
14341
|
-
|
|
14342
|
-
|
|
14343
|
-
if (pagesResult.isError) {
|
|
14344
|
-
return Result$1.error(pagesResult.error, pagesResult.details);
|
|
14345
|
-
}
|
|
14346
|
-
const pages = pagesResult.ok;
|
|
14347
|
-
let currentPosition = address;
|
|
14348
|
-
let bytesLeft = bytes.length;
|
|
14349
|
-
for (const page of pages) {
|
|
14350
|
-
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE$1);
|
|
14351
|
-
const bytesToWrite = Math.min(PAGE_SIZE$1 - pageStartIndex, bytesLeft);
|
|
14352
|
-
const sourceStartIndex = currentPosition - address;
|
|
14353
|
-
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
14354
|
-
page.storeFrom(pageStartIndex, source);
|
|
14355
|
-
currentPosition += bytesToWrite;
|
|
14356
|
-
bytesLeft -= bytesToWrite;
|
|
14357
|
-
}
|
|
14358
|
-
return Result$1.ok(OK);
|
|
14359
|
-
}
|
|
14360
|
-
getPages(startAddress, length, accessType) {
|
|
14361
|
-
if (length === 0) {
|
|
14362
|
-
return Result$1.ok([]);
|
|
14363
|
-
}
|
|
14364
|
-
const memoryRange = MemoryRange.fromStartAndLength(startAddress, length);
|
|
14365
|
-
const pageRange = PageRange.fromMemoryRange(memoryRange);
|
|
14366
|
-
const pages = [];
|
|
14367
|
-
for (const pageNumber of pageRange) {
|
|
14368
|
-
if (pageNumber < RESERVED_NUMBER_OF_PAGES) {
|
|
14369
|
-
return Result$1.error(PageFault.fromPageNumber(pageNumber, true), () => `Page fault: attempted to access reserved page ${pageNumber}`);
|
|
14370
|
-
}
|
|
14371
|
-
const page = this.memory.get(pageNumber);
|
|
14372
|
-
if (page === undefined) {
|
|
14373
|
-
return Result$1.error(PageFault.fromPageNumber(pageNumber), () => `Page fault: page ${pageNumber} not allocated`);
|
|
14374
|
-
}
|
|
14375
|
-
if (accessType === AccessType.WRITE && !page.isWriteable()) {
|
|
14376
|
-
return Result$1.error(PageFault.fromPageNumber(pageNumber, true), () => `Page fault: attempted to write to read-only page ${pageNumber}`);
|
|
14930
|
+
const terminationInstructions = (() => {
|
|
14931
|
+
const terminationInstructions = new Array(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
14932
|
+
terminationInstructions.fill(false);
|
|
14933
|
+
terminationInstructions[Instruction.TRAP] = true;
|
|
14934
|
+
terminationInstructions[Instruction.FALLTHROUGH] = true;
|
|
14935
|
+
terminationInstructions[Instruction.JUMP] = true;
|
|
14936
|
+
terminationInstructions[Instruction.JUMP_IND] = true;
|
|
14937
|
+
terminationInstructions[Instruction.LOAD_IMM_JUMP] = true;
|
|
14938
|
+
terminationInstructions[Instruction.LOAD_IMM_JUMP_IND] = true;
|
|
14939
|
+
terminationInstructions[Instruction.BRANCH_EQ] = true;
|
|
14940
|
+
terminationInstructions[Instruction.BRANCH_NE] = true;
|
|
14941
|
+
terminationInstructions[Instruction.BRANCH_GE_U] = true;
|
|
14942
|
+
terminationInstructions[Instruction.BRANCH_GE_S] = true;
|
|
14943
|
+
terminationInstructions[Instruction.BRANCH_LT_U] = true;
|
|
14944
|
+
terminationInstructions[Instruction.BRANCH_LT_S] = true;
|
|
14945
|
+
terminationInstructions[Instruction.BRANCH_EQ_IMM] = true;
|
|
14946
|
+
terminationInstructions[Instruction.BRANCH_NE_IMM] = true;
|
|
14947
|
+
terminationInstructions[Instruction.BRANCH_LT_U_IMM] = true;
|
|
14948
|
+
terminationInstructions[Instruction.BRANCH_LT_S_IMM] = true;
|
|
14949
|
+
terminationInstructions[Instruction.BRANCH_LE_U_IMM] = true;
|
|
14950
|
+
terminationInstructions[Instruction.BRANCH_LE_S_IMM] = true;
|
|
14951
|
+
terminationInstructions[Instruction.BRANCH_GE_U_IMM] = true;
|
|
14952
|
+
terminationInstructions[Instruction.BRANCH_GE_S_IMM] = true;
|
|
14953
|
+
terminationInstructions[Instruction.BRANCH_GT_U_IMM] = true;
|
|
14954
|
+
terminationInstructions[Instruction.BRANCH_GT_S_IMM] = true;
|
|
14955
|
+
return terminationInstructions;
|
|
14956
|
+
})();
|
|
14957
|
+
|
|
14958
|
+
class BasicBlocks {
|
|
14959
|
+
basicBlocks = new Set();
|
|
14960
|
+
reset(code, mask) {
|
|
14961
|
+
this.basicBlocks.clear();
|
|
14962
|
+
this.basicBlocks.add(0);
|
|
14963
|
+
const codeLength = code.length;
|
|
14964
|
+
const isBasicBlockTermination = (index) => mask.isInstruction(index) && terminationInstructions[code[index]];
|
|
14965
|
+
for (let i = 0; i < codeLength; i++) {
|
|
14966
|
+
if (mask.isInstruction(i) && isBasicBlockTermination(i)) {
|
|
14967
|
+
this.basicBlocks.add(i + 1 + mask.getNoOfBytesToNextInstruction(i + 1));
|
|
14377
14968
|
}
|
|
14378
|
-
pages.push(page);
|
|
14379
|
-
}
|
|
14380
|
-
return Result$1.ok(pages);
|
|
14381
|
-
}
|
|
14382
|
-
/**
|
|
14383
|
-
* Read content of the memory at `[address, address + result.length)` and
|
|
14384
|
-
* write the result into the `result` buffer.
|
|
14385
|
-
*
|
|
14386
|
-
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
14387
|
-
*/
|
|
14388
|
-
loadInto(result, startAddress) {
|
|
14389
|
-
if (result.length === 0) {
|
|
14390
|
-
return Result$1.ok(OK);
|
|
14391
|
-
}
|
|
14392
|
-
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
14393
|
-
if (pagesResult.isError) {
|
|
14394
|
-
return Result$1.error(pagesResult.error, pagesResult.details);
|
|
14395
|
-
}
|
|
14396
|
-
const pages = pagesResult.ok;
|
|
14397
|
-
let currentPosition = startAddress;
|
|
14398
|
-
let bytesLeft = result.length;
|
|
14399
|
-
for (const page of pages) {
|
|
14400
|
-
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE$1);
|
|
14401
|
-
const bytesToRead = Math.min(PAGE_SIZE$1 - pageStartIndex, bytesLeft);
|
|
14402
|
-
const destinationStartIndex = currentPosition - startAddress;
|
|
14403
|
-
const destination = result.subarray(destinationStartIndex);
|
|
14404
|
-
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
14405
|
-
currentPosition += bytesToRead;
|
|
14406
|
-
bytesLeft -= bytesToRead;
|
|
14407
|
-
}
|
|
14408
|
-
logger$3.insane `MEM[${startAddress}] => ${BytesBlob.blobFrom(result)}`;
|
|
14409
|
-
return Result$1.ok(OK);
|
|
14410
|
-
}
|
|
14411
|
-
sbrk(length) {
|
|
14412
|
-
const currentSbrkIndex = this.sbrkIndex;
|
|
14413
|
-
const currentVirtualSbrkIndex = this.virtualSbrkIndex;
|
|
14414
|
-
// new sbrk index is bigger than 2 ** 32 or endHeapIndex
|
|
14415
|
-
if (MAX_MEMORY_INDEX < currentVirtualSbrkIndex + length || currentVirtualSbrkIndex + length > this.endHeapIndex) {
|
|
14416
|
-
throw new OutOfMemory();
|
|
14417
|
-
}
|
|
14418
|
-
const newVirtualSbrkIndex = tryAsSbrkIndex(this.virtualSbrkIndex + length);
|
|
14419
|
-
// no alllocation needed
|
|
14420
|
-
if (newVirtualSbrkIndex <= currentSbrkIndex) {
|
|
14421
|
-
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
14422
|
-
return currentVirtualSbrkIndex;
|
|
14423
|
-
}
|
|
14424
|
-
// standard allocation using "Writeable" pages
|
|
14425
|
-
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize$1(newVirtualSbrkIndex));
|
|
14426
|
-
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
14427
|
-
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
14428
|
-
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE$1;
|
|
14429
|
-
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
14430
|
-
for (const pageNumber of rangeToAllocate) {
|
|
14431
|
-
const page = new WriteablePage(pageNumber);
|
|
14432
|
-
this.memory.set(pageNumber, page);
|
|
14433
14969
|
}
|
|
14434
|
-
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
14435
|
-
this.sbrkIndex = newSbrkIndex;
|
|
14436
|
-
return currentVirtualSbrkIndex;
|
|
14437
|
-
}
|
|
14438
|
-
getPageDump(pageNumber) {
|
|
14439
|
-
const page = this.memory.get(pageNumber);
|
|
14440
|
-
return page?.getPageDump() ?? null;
|
|
14441
14970
|
}
|
|
14442
|
-
|
|
14443
|
-
return this.
|
|
14971
|
+
isBeginningOfBasicBlock(index) {
|
|
14972
|
+
return this.basicBlocks.has(index);
|
|
14444
14973
|
}
|
|
14445
14974
|
}
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
throw new FinalizedBuilderModification();
|
|
14453
|
-
}
|
|
14454
|
-
}
|
|
14455
|
-
ensureNoReservedMemoryUsage(range) {
|
|
14456
|
-
if (range.overlapsWith(RESERVED_MEMORY_RANGE)) {
|
|
14457
|
-
throw new ReservedMemoryFault();
|
|
14458
|
-
}
|
|
14459
|
-
}
|
|
14460
|
-
/**
|
|
14461
|
-
* Create entire readable pages to handle the `[start, end)` range.
|
|
14462
|
-
*
|
|
14463
|
-
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
14464
|
-
* they need to be the start indices of the pages.
|
|
14465
|
-
*
|
|
14466
|
-
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
14467
|
-
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
14468
|
-
*/
|
|
14469
|
-
setReadablePages(start, end, data = new Uint8Array()) {
|
|
14470
|
-
this.ensureNotFinalized();
|
|
14471
|
-
check `${start < end} end has to be bigger than start`;
|
|
14472
|
-
check `${start % PAGE_SIZE$1 === 0} start needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
14473
|
-
check `${end % PAGE_SIZE$1 === 0} end needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
14474
|
-
check `${data.length <= end - start} the initial data is longer than address range`;
|
|
14475
|
-
const length = end - start;
|
|
14476
|
-
const range = MemoryRange.fromStartAndLength(start, length);
|
|
14477
|
-
this.ensureNoReservedMemoryUsage(range);
|
|
14478
|
-
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
14479
|
-
const noOfPages = pages.length;
|
|
14480
|
-
for (let i = 0; i < noOfPages; i++) {
|
|
14481
|
-
const pageNumber = pages[i];
|
|
14482
|
-
const dataChunk = data.subarray(i * PAGE_SIZE$1, (i + 1) * PAGE_SIZE$1);
|
|
14483
|
-
const page = new ReadablePage(pageNumber, dataChunk);
|
|
14484
|
-
this.initialMemory.set(pageNumber, page);
|
|
14485
|
-
}
|
|
14486
|
-
return this;
|
|
14975
|
+
|
|
14976
|
+
const instructionGasMap = (() => {
|
|
14977
|
+
const instructionGasMap = new Array(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
14978
|
+
for (let i = 0; i < HIGHEST_INSTRUCTION_NUMBER + 1; i++) {
|
|
14979
|
+
const gas = byteToOpCodeMap[i]?.gas;
|
|
14980
|
+
instructionGasMap[i] = gas;
|
|
14487
14981
|
}
|
|
14982
|
+
return instructionGasMap;
|
|
14983
|
+
})();
|
|
14984
|
+
|
|
14985
|
+
class InstructionResult {
|
|
14986
|
+
nextPc = 0;
|
|
14987
|
+
status = null;
|
|
14488
14988
|
/**
|
|
14489
|
-
*
|
|
14989
|
+
* A numeric exit parameter of the PVM.
|
|
14490
14990
|
*
|
|
14491
|
-
*
|
|
14492
|
-
*
|
|
14991
|
+
* In case of a `status === Result.FAULT` this will be the memory address
|
|
14992
|
+
* that triggered the fault.
|
|
14993
|
+
* In case of a `status === Result.HOST` this will be the host call index
|
|
14994
|
+
* that should be invoked.
|
|
14493
14995
|
*
|
|
14494
|
-
*
|
|
14495
|
-
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
14496
|
-
*/
|
|
14497
|
-
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
14498
|
-
this.ensureNotFinalized();
|
|
14499
|
-
check `${start < end} end has to be bigger than start`;
|
|
14500
|
-
check `${start % PAGE_SIZE$1 === 0} start needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
14501
|
-
check `${end % PAGE_SIZE$1 === 0} end needs to be a multiple of page size (${PAGE_SIZE$1})`;
|
|
14502
|
-
check `${data.length <= end - start} the initial data is longer than address range`;
|
|
14503
|
-
const length = end - start;
|
|
14504
|
-
const range = MemoryRange.fromStartAndLength(start, length);
|
|
14505
|
-
this.ensureNoReservedMemoryUsage(range);
|
|
14506
|
-
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
14507
|
-
const noOfPages = pages.length;
|
|
14508
|
-
for (let i = 0; i < noOfPages; i++) {
|
|
14509
|
-
const pageNumber = pages[i];
|
|
14510
|
-
const dataChunk = data.subarray(i * PAGE_SIZE$1, (i + 1) * PAGE_SIZE$1);
|
|
14511
|
-
const page = new WriteablePage(pageNumber, dataChunk);
|
|
14512
|
-
this.initialMemory.set(pageNumber, page);
|
|
14513
|
-
}
|
|
14514
|
-
return this;
|
|
14515
|
-
}
|
|
14516
|
-
/**
|
|
14517
|
-
* This function can be useful when page map and initial memory data are provided separatelly.
|
|
14518
|
-
* You can use setWriteablePages/setReadablePages to create empty pages and then setData to fill them
|
|
14996
|
+
* In any other circumstance the value should be `null`.
|
|
14519
14997
|
*/
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
const length = data.length;
|
|
14526
|
-
const range = MemoryRange.fromStartAndLength(start, length);
|
|
14527
|
-
this.ensureNoReservedMemoryUsage(range);
|
|
14528
|
-
const pageNumber = getPageNumber(start);
|
|
14529
|
-
const page = this.initialMemory.get(pageNumber);
|
|
14530
|
-
if (page === undefined) {
|
|
14531
|
-
throw new PageNotExist();
|
|
14532
|
-
}
|
|
14533
|
-
const startPageIndex = tryAsPageIndex(start - page.start);
|
|
14534
|
-
page.setData(startPageIndex, data);
|
|
14535
|
-
return this;
|
|
14536
|
-
}
|
|
14537
|
-
finalize(startHeapIndex, endHeapIndex) {
|
|
14538
|
-
check `
|
|
14539
|
-
${startHeapIndex <= endHeapIndex}
|
|
14540
|
-
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
14541
|
-
`;
|
|
14542
|
-
this.ensureNotFinalized();
|
|
14543
|
-
const heapRange = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
14544
|
-
const heapPagesRange = PageRange.fromMemoryRange(heapRange);
|
|
14545
|
-
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
14546
|
-
for (const pageNumber of initializedPageNumbers) {
|
|
14547
|
-
if (heapPagesRange.isInRange(pageNumber)) {
|
|
14548
|
-
throw new IncorrectSbrkIndex();
|
|
14549
|
-
}
|
|
14550
|
-
}
|
|
14551
|
-
const memory = Memory.fromInitialMemory({
|
|
14552
|
-
memory: this.initialMemory,
|
|
14553
|
-
sbrkIndex: tryAsSbrkIndex(startHeapIndex),
|
|
14554
|
-
endHeapIndex,
|
|
14555
|
-
});
|
|
14556
|
-
this.isFinalized = true;
|
|
14557
|
-
return memory;
|
|
14998
|
+
exitParam = null;
|
|
14999
|
+
reset() {
|
|
15000
|
+
this.nextPc = 0;
|
|
15001
|
+
this.status = null;
|
|
15002
|
+
this.exitParam = null;
|
|
14558
15003
|
}
|
|
14559
15004
|
}
|
|
14560
15005
|
|
|
@@ -15493,7 +15938,7 @@ class StoreOps {
|
|
|
15493
15938
|
}
|
|
15494
15939
|
else {
|
|
15495
15940
|
this.instructionResult.status = Result.FAULT;
|
|
15496
|
-
this.instructionResult.exitParam = getStartPageIndex(storeResult.error.address);
|
|
15941
|
+
this.instructionResult.exitParam = getStartPageIndex(tryAsMemoryIndex(storeResult.error.address));
|
|
15497
15942
|
}
|
|
15498
15943
|
}
|
|
15499
15944
|
}
|
|
@@ -16145,7 +16590,7 @@ class JumpTable {
|
|
|
16145
16590
|
}
|
|
16146
16591
|
}
|
|
16147
16592
|
|
|
16148
|
-
const logger$
|
|
16593
|
+
const logger$1 = Logger.new(undefined, "pvm-interpreter");
|
|
16149
16594
|
var ProgramDecoderError;
|
|
16150
16595
|
(function (ProgramDecoderError) {
|
|
16151
16596
|
ProgramDecoderError[ProgramDecoderError["InvalidProgramError"] = 0] = "InvalidProgramError";
|
|
@@ -16195,21 +16640,21 @@ class ProgramDecoder {
|
|
|
16195
16640
|
return Result$1.ok(new ProgramDecoder(program));
|
|
16196
16641
|
}
|
|
16197
16642
|
catch (e) {
|
|
16198
|
-
logger$
|
|
16643
|
+
logger$1.error `Invalid program: ${e}`;
|
|
16199
16644
|
return Result$1.error(ProgramDecoderError.InvalidProgramError, () => `Program decoder error: ${e}`);
|
|
16200
16645
|
}
|
|
16201
16646
|
}
|
|
16202
16647
|
}
|
|
16203
16648
|
|
|
16204
|
-
const logger
|
|
16649
|
+
const logger = Logger.new(undefined, "pvm");
|
|
16205
16650
|
class Interpreter {
|
|
16206
16651
|
useSbrkGas;
|
|
16207
16652
|
registers = new Registers();
|
|
16653
|
+
memory = new Memory();
|
|
16654
|
+
gas = gasCounter(tryAsGas(0));
|
|
16208
16655
|
code = new Uint8Array();
|
|
16209
16656
|
mask = Mask.empty();
|
|
16210
16657
|
pc = 0;
|
|
16211
|
-
gas = gasCounter(tryAsGas(0));
|
|
16212
|
-
initialGas = gasCounter(tryAsGas(0));
|
|
16213
16658
|
argsDecoder;
|
|
16214
16659
|
threeRegsDispatcher;
|
|
16215
16660
|
twoRegsOneImmDispatcher;
|
|
@@ -16219,7 +16664,6 @@ class Interpreter {
|
|
|
16219
16664
|
oneOffsetDispatcher;
|
|
16220
16665
|
oneRegOneImmDispatcher;
|
|
16221
16666
|
instructionResult = new InstructionResult();
|
|
16222
|
-
memory = new Memory();
|
|
16223
16667
|
twoImmsDispatcher;
|
|
16224
16668
|
oneRegTwoImmsDispatcher;
|
|
16225
16669
|
noArgsDispatcher;
|
|
@@ -16261,14 +16705,17 @@ class Interpreter {
|
|
|
16261
16705
|
this.oneImmDispatcher = new OneImmDispatcher(hostCallOps);
|
|
16262
16706
|
this.oneRegOneExtImmDispatcher = new OneRegOneExtImmDispatcher(loadOps);
|
|
16263
16707
|
}
|
|
16264
|
-
|
|
16708
|
+
resetJam(program, args, pc, gas) {
|
|
16709
|
+
const p = Program.fromSpi(program, args, true);
|
|
16710
|
+
this.resetGeneric(p.code, pc, gas, p.registers, p.memory);
|
|
16711
|
+
}
|
|
16712
|
+
resetGeneric(rawProgram, pc, gas, maybeRegisters, maybeMemory) {
|
|
16265
16713
|
const programDecoder = new ProgramDecoder(rawProgram);
|
|
16266
16714
|
this.code = programDecoder.getCode();
|
|
16267
16715
|
this.mask = programDecoder.getMask();
|
|
16268
16716
|
this.jumpTable.copyFrom(programDecoder.getJumpTable());
|
|
16269
16717
|
this.pc = pc;
|
|
16270
16718
|
this.gas = gasCounter(gas);
|
|
16271
|
-
this.initialGas = gasCounter(gas);
|
|
16272
16719
|
this.status = Status.OK;
|
|
16273
16720
|
this.argsDecoder.reset(this.code, this.mask);
|
|
16274
16721
|
this.basicBlocks.reset(this.code, this.mask);
|
|
@@ -16320,7 +16767,7 @@ class Interpreter {
|
|
|
16320
16767
|
const argsType = instructionArgumentTypeMap[currentInstruction] ?? ArgumentType.NO_ARGUMENTS;
|
|
16321
16768
|
const argsResult = this.argsDecodingResults[argsType];
|
|
16322
16769
|
this.argsDecoder.fillArgs(this.pc, argsResult);
|
|
16323
|
-
logger
|
|
16770
|
+
logger.insane `[PC: ${this.pc}] ${Instruction[currentInstruction]}`;
|
|
16324
16771
|
if (!isValidInstruction) {
|
|
16325
16772
|
this.instructionResult.status = Result.PANIC;
|
|
16326
16773
|
}
|
|
@@ -16392,34 +16839,18 @@ class Interpreter {
|
|
|
16392
16839
|
this.status = Status.HOST;
|
|
16393
16840
|
break;
|
|
16394
16841
|
}
|
|
16395
|
-
logger
|
|
16842
|
+
logger.insane `[PC: ${this.pc}] Status: ${Result[this.instructionResult.status]}`;
|
|
16396
16843
|
return this.status;
|
|
16397
16844
|
}
|
|
16398
16845
|
this.pc = this.instructionResult.nextPc;
|
|
16399
16846
|
return this.status;
|
|
16400
16847
|
}
|
|
16401
|
-
getRegisters() {
|
|
16402
|
-
return this.registers;
|
|
16403
|
-
}
|
|
16404
16848
|
getPC() {
|
|
16405
16849
|
return this.pc;
|
|
16406
16850
|
}
|
|
16407
16851
|
setNextPC(nextPc) {
|
|
16408
16852
|
this.pc = nextPc;
|
|
16409
16853
|
}
|
|
16410
|
-
getGas() {
|
|
16411
|
-
return this.gas.get();
|
|
16412
|
-
}
|
|
16413
|
-
getGasConsumed() {
|
|
16414
|
-
const gasConsumed = tryAsBigGas(this.initialGas.get()) - tryAsBigGas(this.gas.get());
|
|
16415
|
-
if (gasConsumed < 0) {
|
|
16416
|
-
return this.initialGas.get();
|
|
16417
|
-
}
|
|
16418
|
-
return tryAsBigGas(gasConsumed);
|
|
16419
|
-
}
|
|
16420
|
-
getGasCounter() {
|
|
16421
|
-
return this.gas;
|
|
16422
|
-
}
|
|
16423
16854
|
getStatus() {
|
|
16424
16855
|
return this.status;
|
|
16425
16856
|
}
|
|
@@ -16427,9 +16858,6 @@ class Interpreter {
|
|
|
16427
16858
|
const p = this.instructionResult.exitParam;
|
|
16428
16859
|
return p !== null ? tryAsU32(p) : p;
|
|
16429
16860
|
}
|
|
16430
|
-
getMemory() {
|
|
16431
|
-
return this.memory;
|
|
16432
|
-
}
|
|
16433
16861
|
getMemoryPage(pageNumber) {
|
|
16434
16862
|
return this.memory.getPageDump(tryAsPageNumber(pageNumber));
|
|
16435
16863
|
}
|
|
@@ -16453,212 +16881,560 @@ class Interpreter {
|
|
|
16453
16881
|
}
|
|
16454
16882
|
}
|
|
16455
16883
|
|
|
16456
|
-
var index$
|
|
16884
|
+
var index$5 = /*#__PURE__*/Object.freeze({
|
|
16457
16885
|
__proto__: null,
|
|
16458
16886
|
Interpreter: Interpreter,
|
|
16459
16887
|
Memory: Memory,
|
|
16460
16888
|
MemoryBuilder: MemoryBuilder,
|
|
16461
16889
|
Registers: Registers,
|
|
16462
16890
|
gasCounter: gasCounter,
|
|
16463
|
-
tryAsBigGas: tryAsBigGas,
|
|
16464
|
-
tryAsGas: tryAsGas,
|
|
16465
16891
|
tryAsMemoryIndex: tryAsMemoryIndex,
|
|
16466
|
-
tryAsSbrkIndex: tryAsSbrkIndex
|
|
16467
|
-
tryAsSmallGas: tryAsSmallGas
|
|
16892
|
+
tryAsSbrkIndex: tryAsSbrkIndex
|
|
16468
16893
|
});
|
|
16469
16894
|
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
16473
|
-
|
|
16474
|
-
|
|
16475
|
-
|
|
16476
|
-
|
|
16477
|
-
|
|
16478
|
-
|
|
16479
|
-
|
|
16480
|
-
|
|
16481
|
-
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
|
|
16895
|
+
async function instantiate(module, imports = {}) {
|
|
16896
|
+
const adaptedImports = {
|
|
16897
|
+
env: Object.setPrototypeOf({
|
|
16898
|
+
abort(message, fileName, lineNumber, columnNumber) {
|
|
16899
|
+
// ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
|
|
16900
|
+
message = __liftString(message >>> 0);
|
|
16901
|
+
fileName = __liftString(fileName >>> 0);
|
|
16902
|
+
lineNumber = lineNumber >>> 0;
|
|
16903
|
+
columnNumber = columnNumber >>> 0;
|
|
16904
|
+
(() => {
|
|
16905
|
+
// @external.js
|
|
16906
|
+
throw Error(`${message} in ${fileName}:${lineNumber}:${columnNumber}`);
|
|
16907
|
+
})();
|
|
16908
|
+
},
|
|
16909
|
+
"console.log"(text) {
|
|
16910
|
+
// ~lib/bindings/dom/console.log(~lib/string/String) => void
|
|
16911
|
+
text = __liftString(text >>> 0);
|
|
16912
|
+
console.log(text);
|
|
16913
|
+
},
|
|
16914
|
+
}, Object.assign(Object.create(globalThis), imports.env || {})),
|
|
16915
|
+
};
|
|
16916
|
+
const { exports } = await WebAssembly.instantiate(module, adaptedImports);
|
|
16917
|
+
const memory = exports.memory || imports.env.memory;
|
|
16918
|
+
const adaptedExports = Object.setPrototypeOf({
|
|
16919
|
+
getAssembly(p) {
|
|
16920
|
+
// assembly/api-internal/getAssembly(assembly/program/Program) => ~lib/string/String
|
|
16921
|
+
p = __lowerInternref(p) || __notnull();
|
|
16922
|
+
return __liftString(exports.getAssembly(p) >>> 0);
|
|
16923
|
+
},
|
|
16924
|
+
wrapAsProgram(bytecode) {
|
|
16925
|
+
// assembly/program-build/wrapAsProgram(~lib/typedarray/Uint8Array) => ~lib/typedarray/Uint8Array
|
|
16926
|
+
bytecode = __lowerTypedArray(Uint8Array, 10, 0, bytecode) || __notnull();
|
|
16927
|
+
return __liftTypedArray(Uint8Array, exports.wrapAsProgram(bytecode) >>> 0);
|
|
16928
|
+
},
|
|
16929
|
+
resetJAM(program, pc, initialGas, args, hasMetadata) {
|
|
16930
|
+
// assembly/api-debugger/resetJAM(~lib/array/Array<u8>, f64, i64, ~lib/array/Array<u8>, bool?) => void
|
|
16931
|
+
program = __retain(__lowerArray(__setU8, 6, 0, program) || __notnull());
|
|
16932
|
+
initialGas = initialGas || 0n;
|
|
16933
|
+
args = __lowerArray(__setU8, 6, 0, args) || __notnull();
|
|
16934
|
+
hasMetadata = hasMetadata ? 1 : 0;
|
|
16935
|
+
try {
|
|
16936
|
+
exports.__setArgumentsLength(arguments.length);
|
|
16937
|
+
exports.resetJAM(program, pc, initialGas, args, hasMetadata);
|
|
16938
|
+
} finally {
|
|
16939
|
+
__release(program);
|
|
16940
|
+
}
|
|
16941
|
+
},
|
|
16942
|
+
resetGeneric(program, flatRegisters, initialGas, hasMetadata) {
|
|
16943
|
+
// assembly/api-debugger/resetGeneric(~lib/array/Array<u8>, ~lib/array/Array<u8>, i64, bool?) => void
|
|
16944
|
+
program = __retain(__lowerArray(__setU8, 6, 0, program) || __notnull());
|
|
16945
|
+
flatRegisters = __lowerArray(__setU8, 6, 0, flatRegisters) || __notnull();
|
|
16946
|
+
initialGas = initialGas || 0n;
|
|
16947
|
+
hasMetadata = hasMetadata ? 1 : 0;
|
|
16948
|
+
try {
|
|
16949
|
+
exports.__setArgumentsLength(arguments.length);
|
|
16950
|
+
exports.resetGeneric(program, flatRegisters, initialGas, hasMetadata);
|
|
16951
|
+
} finally {
|
|
16952
|
+
__release(program);
|
|
16953
|
+
}
|
|
16954
|
+
},
|
|
16955
|
+
resetGenericWithMemory(program, flatRegisters, pageMap, chunks, initialGas, hasMetadata) {
|
|
16956
|
+
// assembly/api-debugger/resetGenericWithMemory(~lib/array/Array<u8>, ~lib/array/Array<u8>, ~lib/typedarray/Uint8Array, ~lib/typedarray/Uint8Array, i64, bool?) => void
|
|
16957
|
+
program = __retain(__lowerArray(__setU8, 6, 0, program) || __notnull());
|
|
16958
|
+
flatRegisters = __retain(__lowerArray(__setU8, 6, 0, flatRegisters) || __notnull());
|
|
16959
|
+
pageMap = __retain(__lowerTypedArray(Uint8Array, 10, 0, pageMap) || __notnull());
|
|
16960
|
+
chunks = __lowerTypedArray(Uint8Array, 10, 0, chunks) || __notnull();
|
|
16961
|
+
initialGas = initialGas || 0n;
|
|
16962
|
+
hasMetadata = hasMetadata ? 1 : 0;
|
|
16963
|
+
try {
|
|
16964
|
+
exports.__setArgumentsLength(arguments.length);
|
|
16965
|
+
exports.resetGenericWithMemory(program, flatRegisters, pageMap, chunks, initialGas, hasMetadata);
|
|
16966
|
+
} finally {
|
|
16967
|
+
__release(program);
|
|
16968
|
+
__release(flatRegisters);
|
|
16969
|
+
__release(pageMap);
|
|
16970
|
+
}
|
|
16971
|
+
},
|
|
16972
|
+
nextStep() {
|
|
16973
|
+
// assembly/api-debugger/nextStep() => bool
|
|
16974
|
+
return exports.nextStep() != 0;
|
|
16975
|
+
},
|
|
16976
|
+
nSteps(steps) {
|
|
16977
|
+
// assembly/api-debugger/nSteps(u32) => bool
|
|
16978
|
+
return exports.nSteps(steps) != 0;
|
|
16979
|
+
},
|
|
16980
|
+
getProgramCounter() {
|
|
16981
|
+
// assembly/api-debugger/getProgramCounter() => u32
|
|
16982
|
+
return exports.getProgramCounter() >>> 0;
|
|
16983
|
+
},
|
|
16984
|
+
getExitArg() {
|
|
16985
|
+
// assembly/api-debugger/getExitArg() => u32
|
|
16986
|
+
return exports.getExitArg() >>> 0;
|
|
16987
|
+
},
|
|
16988
|
+
setGasLeft(gas) {
|
|
16989
|
+
// assembly/api-debugger/setGasLeft(i64) => void
|
|
16990
|
+
gas = gas || 0n;
|
|
16991
|
+
exports.setGasLeft(gas);
|
|
16992
|
+
},
|
|
16993
|
+
getRegisters() {
|
|
16994
|
+
// assembly/api-debugger/getRegisters() => ~lib/typedarray/Uint8Array
|
|
16995
|
+
return __liftTypedArray(Uint8Array, exports.getRegisters() >>> 0);
|
|
16996
|
+
},
|
|
16997
|
+
setRegisters(flatRegisters) {
|
|
16998
|
+
// assembly/api-debugger/setRegisters(~lib/array/Array<u8>) => void
|
|
16999
|
+
flatRegisters = __lowerArray(__setU8, 6, 0, flatRegisters) || __notnull();
|
|
17000
|
+
exports.setRegisters(flatRegisters);
|
|
17001
|
+
},
|
|
17002
|
+
getPageDump(index) {
|
|
17003
|
+
// assembly/api-debugger/getPageDump(u32) => ~lib/typedarray/Uint8Array
|
|
17004
|
+
return __liftTypedArray(Uint8Array, exports.getPageDump(index) >>> 0);
|
|
17005
|
+
},
|
|
17006
|
+
getMemory(address, length) {
|
|
17007
|
+
// assembly/api-debugger/getMemory(u32, u32) => ~lib/typedarray/Uint8Array | null
|
|
17008
|
+
return __liftTypedArray(Uint8Array, exports.getMemory(address, length) >>> 0);
|
|
17009
|
+
},
|
|
17010
|
+
setMemory(address, data) {
|
|
17011
|
+
// assembly/api-debugger/setMemory(u32, ~lib/typedarray/Uint8Array) => bool
|
|
17012
|
+
data = __lowerTypedArray(Uint8Array, 10, 0, data) || __notnull();
|
|
17013
|
+
return exports.setMemory(address, data) != 0;
|
|
17014
|
+
},
|
|
17015
|
+
InputKind: (values => (
|
|
17016
|
+
// assembly/api-utils/InputKind
|
|
17017
|
+
values[values.Generic = exports["InputKind.Generic"].valueOf()] = "Generic",
|
|
17018
|
+
values[values.SPI = exports["InputKind.SPI"].valueOf()] = "SPI",
|
|
17019
|
+
values
|
|
17020
|
+
))({}),
|
|
17021
|
+
HasMetadata: (values => (
|
|
17022
|
+
// assembly/api-utils/HasMetadata
|
|
17023
|
+
values[values.Yes = exports["HasMetadata.Yes"].valueOf()] = "Yes",
|
|
17024
|
+
values[values.No = exports["HasMetadata.No"].valueOf()] = "No",
|
|
17025
|
+
values
|
|
17026
|
+
))({}),
|
|
17027
|
+
getGasCosts(input, kind, withMetadata) {
|
|
17028
|
+
// assembly/api-utils/getGasCosts(~lib/array/Array<u8>, i32, i32) => ~lib/array/Array<assembly/gas-costs/BlockGasCost>
|
|
17029
|
+
input = __lowerArray(__setU8, 6, 0, input) || __notnull();
|
|
17030
|
+
return __liftArray(pointer => __liftRecord50(__getU32(pointer)), 2, exports.getGasCosts(input, kind, withMetadata) >>> 0);
|
|
17031
|
+
},
|
|
17032
|
+
disassemble(input, kind, withMetadata) {
|
|
17033
|
+
// assembly/api-utils/disassemble(~lib/array/Array<u8>, i32, i32) => ~lib/string/String
|
|
17034
|
+
input = __lowerArray(__setU8, 6, 0, input) || __notnull();
|
|
17035
|
+
return __liftString(exports.disassemble(input, kind, withMetadata) >>> 0);
|
|
17036
|
+
},
|
|
17037
|
+
prepareProgram(kind, hasMetadata, program, initialRegisters, initialPageMap, initialMemory, args) {
|
|
17038
|
+
// assembly/api-utils/prepareProgram(i32, i32, ~lib/array/Array<u8>, ~lib/array/Array<u64>, ~lib/array/Array<assembly/api-internal/InitialPage>, ~lib/array/Array<assembly/api-internal/InitialChunk>, ~lib/array/Array<u8>) => assembly/spi/StandardProgram
|
|
17039
|
+
program = __retain(__lowerArray(__setU8, 6, 0, program) || __notnull());
|
|
17040
|
+
initialRegisters = __retain(__lowerArray(__setU64, 52, 3, initialRegisters) || __notnull());
|
|
17041
|
+
initialPageMap = __retain(__lowerArray((pointer, value) => { __setU32(pointer, __lowerRecord46(value) || __notnull()); }, 47, 2, initialPageMap) || __notnull());
|
|
17042
|
+
initialMemory = __retain(__lowerArray((pointer, value) => { __setU32(pointer, __lowerRecord48(value) || __notnull()); }, 49, 2, initialMemory) || __notnull());
|
|
17043
|
+
args = __lowerArray(__setU8, 6, 0, args) || __notnull();
|
|
17044
|
+
try {
|
|
17045
|
+
return __liftInternref(exports.prepareProgram(kind, hasMetadata, program, initialRegisters, initialPageMap, initialMemory, args) >>> 0);
|
|
17046
|
+
} finally {
|
|
17047
|
+
__release(program);
|
|
17048
|
+
__release(initialRegisters);
|
|
17049
|
+
__release(initialPageMap);
|
|
17050
|
+
__release(initialMemory);
|
|
17051
|
+
}
|
|
17052
|
+
},
|
|
17053
|
+
runProgram(program, initialGas, programCounter, logs, useSbrkGas) {
|
|
17054
|
+
// assembly/api-utils/runProgram(assembly/spi/StandardProgram, i64?, u32?, bool?, bool?) => assembly/api-internal/VmOutput
|
|
17055
|
+
program = __lowerInternref(program) || __notnull();
|
|
17056
|
+
initialGas = initialGas || 0n;
|
|
17057
|
+
logs = logs ? 1 : 0;
|
|
17058
|
+
useSbrkGas = useSbrkGas ? 1 : 0;
|
|
17059
|
+
exports.__setArgumentsLength(arguments.length);
|
|
17060
|
+
return __liftRecord55(exports.runProgram(program, initialGas, programCounter, logs, useSbrkGas) >>> 0);
|
|
17061
|
+
},
|
|
17062
|
+
}, exports);
|
|
17063
|
+
function __liftRecord50(pointer) {
|
|
17064
|
+
// assembly/gas-costs/BlockGasCost
|
|
17065
|
+
// Hint: Opt-out from lifting as a record by providing an empty constructor
|
|
17066
|
+
if (!pointer) return null;
|
|
17067
|
+
return {
|
|
17068
|
+
pc: __getU32(pointer + 0),
|
|
17069
|
+
gas: __getU64(pointer + 8),
|
|
17070
|
+
};
|
|
17071
|
+
}
|
|
17072
|
+
function __lowerRecord46(value) {
|
|
17073
|
+
// assembly/api-internal/InitialPage
|
|
17074
|
+
// Hint: Opt-out from lowering as a record by providing an empty constructor
|
|
17075
|
+
if (value == null) return 0;
|
|
17076
|
+
const pointer = exports.__pin(exports.__new(12, 46));
|
|
17077
|
+
__setU32(pointer + 0, value.address);
|
|
17078
|
+
__setU32(pointer + 4, value.length);
|
|
17079
|
+
__setU32(pointer + 8, value.access);
|
|
17080
|
+
exports.__unpin(pointer);
|
|
17081
|
+
return pointer;
|
|
17082
|
+
}
|
|
17083
|
+
function __lowerRecord48(value) {
|
|
17084
|
+
// assembly/api-internal/InitialChunk
|
|
17085
|
+
// Hint: Opt-out from lowering as a record by providing an empty constructor
|
|
17086
|
+
if (value == null) return 0;
|
|
17087
|
+
const pointer = exports.__pin(exports.__new(8, 48));
|
|
17088
|
+
__setU32(pointer + 0, value.address);
|
|
17089
|
+
__setU32(pointer + 4, __lowerArray(__setU8, 6, 0, value.data) || __notnull());
|
|
17090
|
+
exports.__unpin(pointer);
|
|
17091
|
+
return pointer;
|
|
17092
|
+
}
|
|
17093
|
+
function __liftRecord48(pointer) {
|
|
17094
|
+
// assembly/api-internal/InitialChunk
|
|
17095
|
+
// Hint: Opt-out from lifting as a record by providing an empty constructor
|
|
17096
|
+
if (!pointer) return null;
|
|
17097
|
+
return {
|
|
17098
|
+
address: __getU32(pointer + 0),
|
|
17099
|
+
data: __liftArray(__getU8, 0, __getU32(pointer + 4)),
|
|
17100
|
+
};
|
|
17101
|
+
}
|
|
17102
|
+
function __liftRecord55(pointer) {
|
|
17103
|
+
// assembly/api-internal/VmOutput
|
|
17104
|
+
// Hint: Opt-out from lifting as a record by providing an empty constructor
|
|
17105
|
+
if (!pointer) return null;
|
|
17106
|
+
return {
|
|
17107
|
+
status: __getI32(pointer + 0),
|
|
17108
|
+
registers: __liftArray(pointer => BigInt.asUintN(64, __getU64(pointer)), 3, __getU32(pointer + 4)),
|
|
17109
|
+
pc: __getU32(pointer + 8),
|
|
17110
|
+
memory: __liftArray(pointer => __liftRecord48(__getU32(pointer)), 2, __getU32(pointer + 12)),
|
|
17111
|
+
gas: __getI64(pointer + 16),
|
|
17112
|
+
exitCode: __getU32(pointer + 24),
|
|
17113
|
+
};
|
|
17114
|
+
}
|
|
17115
|
+
function __liftString(pointer) {
|
|
17116
|
+
if (!pointer) return null;
|
|
17117
|
+
const
|
|
17118
|
+
end = pointer + new Uint32Array(memory.buffer)[pointer - 4 >>> 2] >>> 1,
|
|
17119
|
+
memoryU16 = new Uint16Array(memory.buffer);
|
|
17120
|
+
let
|
|
17121
|
+
start = pointer >>> 1,
|
|
17122
|
+
string = "";
|
|
17123
|
+
while (end - start > 1024) string += String.fromCharCode(...memoryU16.subarray(start, start += 1024));
|
|
17124
|
+
return string + String.fromCharCode(...memoryU16.subarray(start, end));
|
|
17125
|
+
}
|
|
17126
|
+
function __liftArray(liftElement, align, pointer) {
|
|
17127
|
+
if (!pointer) return null;
|
|
17128
|
+
const
|
|
17129
|
+
dataStart = __getU32(pointer + 4),
|
|
17130
|
+
length = __dataview.getUint32(pointer + 12, true),
|
|
17131
|
+
values = new Array(length);
|
|
17132
|
+
for (let i = 0; i < length; ++i) values[i] = liftElement(dataStart + (i << align >>> 0));
|
|
17133
|
+
return values;
|
|
17134
|
+
}
|
|
17135
|
+
function __lowerArray(lowerElement, id, align, values) {
|
|
17136
|
+
if (values == null) return 0;
|
|
17137
|
+
const
|
|
17138
|
+
length = values.length,
|
|
17139
|
+
buffer = exports.__pin(exports.__new(length << align, 1)) >>> 0,
|
|
17140
|
+
header = exports.__pin(exports.__new(16, id)) >>> 0;
|
|
17141
|
+
__setU32(header + 0, buffer);
|
|
17142
|
+
__dataview.setUint32(header + 4, buffer, true);
|
|
17143
|
+
__dataview.setUint32(header + 8, length << align, true);
|
|
17144
|
+
__dataview.setUint32(header + 12, length, true);
|
|
17145
|
+
for (let i = 0; i < length; ++i) lowerElement(buffer + (i << align >>> 0), values[i]);
|
|
17146
|
+
exports.__unpin(buffer);
|
|
17147
|
+
exports.__unpin(header);
|
|
17148
|
+
return header;
|
|
17149
|
+
}
|
|
17150
|
+
function __liftTypedArray(constructor, pointer) {
|
|
17151
|
+
if (!pointer) return null;
|
|
17152
|
+
return new constructor(
|
|
17153
|
+
memory.buffer,
|
|
17154
|
+
__getU32(pointer + 4),
|
|
17155
|
+
__dataview.getUint32(pointer + 8, true) / constructor.BYTES_PER_ELEMENT
|
|
17156
|
+
).slice();
|
|
17157
|
+
}
|
|
17158
|
+
function __lowerTypedArray(constructor, id, align, values) {
|
|
17159
|
+
if (values == null) return 0;
|
|
17160
|
+
const
|
|
17161
|
+
length = values.length,
|
|
17162
|
+
buffer = exports.__pin(exports.__new(length << align, 1)) >>> 0,
|
|
17163
|
+
header = exports.__new(12, id) >>> 0;
|
|
17164
|
+
__setU32(header + 0, buffer);
|
|
17165
|
+
__dataview.setUint32(header + 4, buffer, true);
|
|
17166
|
+
__dataview.setUint32(header + 8, length << align, true);
|
|
17167
|
+
new constructor(memory.buffer, buffer, length).set(values);
|
|
17168
|
+
exports.__unpin(buffer);
|
|
17169
|
+
return header;
|
|
17170
|
+
}
|
|
17171
|
+
class Internref extends Number {}
|
|
17172
|
+
const registry = new FinalizationRegistry(__release);
|
|
17173
|
+
function __liftInternref(pointer) {
|
|
17174
|
+
if (!pointer) return null;
|
|
17175
|
+
const sentinel = new Internref(__retain(pointer));
|
|
17176
|
+
registry.register(sentinel, pointer);
|
|
17177
|
+
return sentinel;
|
|
17178
|
+
}
|
|
17179
|
+
function __lowerInternref(value) {
|
|
17180
|
+
if (value == null) return 0;
|
|
17181
|
+
if (value instanceof Internref) return value.valueOf();
|
|
17182
|
+
throw TypeError("internref expected");
|
|
17183
|
+
}
|
|
17184
|
+
const refcounts = new Map();
|
|
17185
|
+
function __retain(pointer) {
|
|
17186
|
+
if (pointer) {
|
|
17187
|
+
const refcount = refcounts.get(pointer);
|
|
17188
|
+
if (refcount) refcounts.set(pointer, refcount + 1);
|
|
17189
|
+
else refcounts.set(exports.__pin(pointer), 1);
|
|
17190
|
+
}
|
|
17191
|
+
return pointer;
|
|
17192
|
+
}
|
|
17193
|
+
function __release(pointer) {
|
|
17194
|
+
if (pointer) {
|
|
17195
|
+
const refcount = refcounts.get(pointer);
|
|
17196
|
+
if (refcount === 1) exports.__unpin(pointer), refcounts.delete(pointer);
|
|
17197
|
+
else if (refcount) refcounts.set(pointer, refcount - 1);
|
|
17198
|
+
else throw Error(`invalid refcount '${refcount}' for reference '${pointer}'`);
|
|
17199
|
+
}
|
|
17200
|
+
}
|
|
17201
|
+
function __notnull() {
|
|
17202
|
+
throw TypeError("value must not be null");
|
|
17203
|
+
}
|
|
17204
|
+
let __dataview = new DataView(memory.buffer);
|
|
17205
|
+
function __setU8(pointer, value) {
|
|
17206
|
+
try {
|
|
17207
|
+
__dataview.setUint8(pointer, value, true);
|
|
17208
|
+
} catch {
|
|
17209
|
+
__dataview = new DataView(memory.buffer);
|
|
17210
|
+
__dataview.setUint8(pointer, value, true);
|
|
16492
17211
|
}
|
|
16493
|
-
}
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
17212
|
+
}
|
|
17213
|
+
function __setU32(pointer, value) {
|
|
17214
|
+
try {
|
|
17215
|
+
__dataview.setUint32(pointer, value, true);
|
|
17216
|
+
} catch {
|
|
17217
|
+
__dataview = new DataView(memory.buffer);
|
|
17218
|
+
__dataview.setUint32(pointer, value, true);
|
|
16499
17219
|
}
|
|
16500
|
-
|
|
16501
|
-
|
|
17220
|
+
}
|
|
17221
|
+
function __setU64(pointer, value) {
|
|
17222
|
+
try {
|
|
17223
|
+
__dataview.setBigUint64(pointer, value, true);
|
|
17224
|
+
} catch {
|
|
17225
|
+
__dataview = new DataView(memory.buffer);
|
|
17226
|
+
__dataview.setBigUint64(pointer, value, true);
|
|
16502
17227
|
}
|
|
16503
|
-
|
|
16504
|
-
|
|
17228
|
+
}
|
|
17229
|
+
function __getU8(pointer) {
|
|
17230
|
+
try {
|
|
17231
|
+
return __dataview.getUint8(pointer, true);
|
|
17232
|
+
} catch {
|
|
17233
|
+
__dataview = new DataView(memory.buffer);
|
|
17234
|
+
return __dataview.getUint8(pointer, true);
|
|
16505
17235
|
}
|
|
16506
|
-
}
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
this.consumedGas = consumedGas;
|
|
16514
|
-
this.status = status;
|
|
16515
|
-
this.memorySlice = memorySlice;
|
|
16516
|
-
check `
|
|
16517
|
-
${(status === null && memorySlice !== null) || (status !== null && memorySlice === null)}
|
|
16518
|
-
'status' and 'memorySlice' must not both be null or both be non-null — exactly one must be provided
|
|
16519
|
-
`;
|
|
17236
|
+
}
|
|
17237
|
+
function __getI32(pointer) {
|
|
17238
|
+
try {
|
|
17239
|
+
return __dataview.getInt32(pointer, true);
|
|
17240
|
+
} catch {
|
|
17241
|
+
__dataview = new DataView(memory.buffer);
|
|
17242
|
+
return __dataview.getInt32(pointer, true);
|
|
16520
17243
|
}
|
|
16521
|
-
|
|
16522
|
-
|
|
17244
|
+
}
|
|
17245
|
+
function __getU32(pointer) {
|
|
17246
|
+
try {
|
|
17247
|
+
return __dataview.getUint32(pointer, true);
|
|
17248
|
+
} catch {
|
|
17249
|
+
__dataview = new DataView(memory.buffer);
|
|
17250
|
+
return __dataview.getUint32(pointer, true);
|
|
16523
17251
|
}
|
|
16524
|
-
|
|
16525
|
-
|
|
17252
|
+
}
|
|
17253
|
+
function __getI64(pointer) {
|
|
17254
|
+
try {
|
|
17255
|
+
return __dataview.getBigInt64(pointer, true);
|
|
17256
|
+
} catch {
|
|
17257
|
+
__dataview = new DataView(memory.buffer);
|
|
17258
|
+
return __dataview.getBigInt64(pointer, true);
|
|
16526
17259
|
}
|
|
16527
|
-
|
|
16528
|
-
|
|
17260
|
+
}
|
|
17261
|
+
function __getU64(pointer) {
|
|
17262
|
+
try {
|
|
17263
|
+
return __dataview.getBigUint64(pointer, true);
|
|
17264
|
+
} catch {
|
|
17265
|
+
__dataview = new DataView(memory.buffer);
|
|
17266
|
+
return __dataview.getBigUint64(pointer, true);
|
|
17267
|
+
}
|
|
17268
|
+
}
|
|
17269
|
+
return adaptedExports;
|
|
17270
|
+
}
|
|
17271
|
+
|
|
17272
|
+
// TODO [ToDr] Temporary solution. We need to inline WASM files for the final build.
|
|
17273
|
+
const wasmPath = node_url.fileURLToPath(new URL(undefined("@fluffylabs/anan-as/release-mini.wasm"), (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
17274
|
+
const wasmBuffer = fs.readFileSync(wasmPath);
|
|
17275
|
+
// Max u32 value
|
|
17276
|
+
const INF_STEPS = 2 ** 32 - 1;
|
|
17277
|
+
class AnanasRegisters {
|
|
17278
|
+
instance;
|
|
17279
|
+
constructor(instance) {
|
|
17280
|
+
this.instance = instance;
|
|
17281
|
+
}
|
|
17282
|
+
getAllEncoded() {
|
|
17283
|
+
return this.instance.getRegisters();
|
|
17284
|
+
}
|
|
17285
|
+
setAllEncoded(bytes) {
|
|
17286
|
+
check `${bytes.length === NO_OF_REGISTERS$1 * REGISTER_BYTE_SIZE}
|
|
17287
|
+
Incorrect size of input registers. Got: ${bytes.length},
|
|
17288
|
+
need: ${NO_OF_REGISTERS$1 * REGISTER_BYTE_SIZE}`;
|
|
17289
|
+
this.instance.setRegisters(lowerBytes(bytes));
|
|
16529
17290
|
}
|
|
16530
|
-
|
|
16531
|
-
|
|
17291
|
+
getAllU64() {
|
|
17292
|
+
const bytes = this.getAllEncoded();
|
|
17293
|
+
return new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
16532
17294
|
}
|
|
16533
17295
|
}
|
|
16534
|
-
class
|
|
16535
|
-
|
|
16536
|
-
|
|
16537
|
-
|
|
16538
|
-
this.pvmInstanceManager = pvmInstanceManager;
|
|
16539
|
-
this.hostCalls = hostCalls;
|
|
17296
|
+
class AnanasMemory {
|
|
17297
|
+
instance;
|
|
17298
|
+
constructor(instance) {
|
|
17299
|
+
this.instance = instance;
|
|
16540
17300
|
}
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
return ReturnValue.fromStatus(gasConsumed, status);
|
|
16545
|
-
}
|
|
16546
|
-
if (status === Status.HALT) {
|
|
16547
|
-
const memory = pvmInstance.getMemory();
|
|
16548
|
-
const regs = pvmInstance.getRegisters();
|
|
16549
|
-
const maybeAddress = regs.getLowerU32(7);
|
|
16550
|
-
const maybeLength = regs.getLowerU32(8);
|
|
16551
|
-
const result = safeAllocUint8Array(maybeLength);
|
|
16552
|
-
const startAddress = tryAsMemoryIndex(maybeAddress);
|
|
16553
|
-
const loadResult = memory.loadInto(result, startAddress);
|
|
16554
|
-
if (loadResult.isError) {
|
|
16555
|
-
return ReturnValue.fromMemorySlice(gasConsumed, new Uint8Array());
|
|
16556
|
-
}
|
|
16557
|
-
return ReturnValue.fromMemorySlice(gasConsumed, result);
|
|
17301
|
+
store(address, bytes) {
|
|
17302
|
+
if (this.instance.setMemory(address, bytes)) {
|
|
17303
|
+
return Result$1.ok(OK);
|
|
16558
17304
|
}
|
|
16559
|
-
return
|
|
17305
|
+
return Result$1.error({ address: getPageStartAddress(address) }, () => "Memory is unwritable!");
|
|
16560
17306
|
}
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
let status = pvmInstance.getStatus();
|
|
16565
|
-
if (status !== Status.HOST) {
|
|
16566
|
-
return this.getReturnValue(status, pvmInstance);
|
|
16567
|
-
}
|
|
16568
|
-
check `
|
|
16569
|
-
${pvmInstance.getExitParam() !== null}
|
|
16570
|
-
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
16571
|
-
`;
|
|
16572
|
-
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
16573
|
-
const gas = pvmInstance.getGasCounter();
|
|
16574
|
-
const regs = new HostCallRegisters(pvmInstance.getRegisters());
|
|
16575
|
-
const memory = new HostCallMemory(pvmInstance.getMemory());
|
|
16576
|
-
const index = tryAsHostCallIndex(hostCallIndex);
|
|
16577
|
-
const hostCall = this.hostCalls.get(index);
|
|
16578
|
-
const gasBefore = gas.get();
|
|
16579
|
-
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
16580
|
-
const basicGasCost = typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
16581
|
-
const underflow = gas.sub(basicGasCost);
|
|
16582
|
-
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
16583
|
-
if (underflow) {
|
|
16584
|
-
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
16585
|
-
return ReturnValue.fromStatus(pvmInstance.getGasConsumed(), Status.OOG);
|
|
16586
|
-
}
|
|
16587
|
-
this.hostCalls.traceHostCall(`${pcLog} Invoking`, index, hostCall, regs, gasBefore);
|
|
16588
|
-
const result = await hostCall.execute(gas, regs, memory);
|
|
16589
|
-
this.hostCalls.traceHostCall(result === undefined ? `${pcLog} Result` : `${pcLog} Status(${PvmExecution[result]})`, index, hostCall, regs, gas.get());
|
|
16590
|
-
if (result === PvmExecution.Halt) {
|
|
16591
|
-
status = Status.HALT;
|
|
16592
|
-
return this.getReturnValue(status, pvmInstance);
|
|
16593
|
-
}
|
|
16594
|
-
if (result === PvmExecution.Panic) {
|
|
16595
|
-
status = Status.PANIC;
|
|
16596
|
-
return this.getReturnValue(status, pvmInstance);
|
|
16597
|
-
}
|
|
16598
|
-
if (result === PvmExecution.OOG) {
|
|
16599
|
-
status = Status.OOG;
|
|
16600
|
-
return this.getReturnValue(status, pvmInstance);
|
|
16601
|
-
}
|
|
16602
|
-
if (result === undefined) {
|
|
16603
|
-
pvmInstance.runProgram();
|
|
16604
|
-
status = pvmInstance.getStatus();
|
|
16605
|
-
continue;
|
|
16606
|
-
}
|
|
16607
|
-
assertNever(result);
|
|
17307
|
+
read(address, result) {
|
|
17308
|
+
if (result.length === 0) {
|
|
17309
|
+
return Result$1.ok(OK);
|
|
16608
17310
|
}
|
|
17311
|
+
const newResult = this.instance.getMemory(address, result.length);
|
|
17312
|
+
if (newResult === null) {
|
|
17313
|
+
return Result$1.error({ address: getPageStartAddress(address) }, () => "Memory is inaccessible!");
|
|
17314
|
+
}
|
|
17315
|
+
result.set(newResult, 0);
|
|
17316
|
+
return Result$1.ok(OK);
|
|
16609
17317
|
}
|
|
16610
|
-
|
|
16611
|
-
|
|
16612
|
-
|
|
16613
|
-
|
|
16614
|
-
|
|
17318
|
+
}
|
|
17319
|
+
class AnanasGasCounter {
|
|
17320
|
+
instance;
|
|
17321
|
+
initialGas = tryAsGas(0n);
|
|
17322
|
+
constructor(instance) {
|
|
17323
|
+
this.instance = instance;
|
|
17324
|
+
}
|
|
17325
|
+
get() {
|
|
17326
|
+
return tryAsGas(this.instance.getGasLeft());
|
|
17327
|
+
}
|
|
17328
|
+
set(g) {
|
|
17329
|
+
this.instance.setGasLeft(BigInt(g));
|
|
17330
|
+
}
|
|
17331
|
+
sub(g) {
|
|
17332
|
+
const result = this.instance.getGasLeft() - BigInt(g);
|
|
17333
|
+
if (result >= 0n) {
|
|
17334
|
+
this.instance.setGasLeft(result);
|
|
17335
|
+
return false;
|
|
16615
17336
|
}
|
|
16616
|
-
|
|
16617
|
-
|
|
17337
|
+
this.instance.setGasLeft(0n);
|
|
17338
|
+
return true;
|
|
17339
|
+
}
|
|
17340
|
+
used() {
|
|
17341
|
+
const gasConsumed = BigInt(this.initialGas) - BigInt(this.get());
|
|
17342
|
+
if (gasConsumed < 0) {
|
|
17343
|
+
return this.initialGas;
|
|
16618
17344
|
}
|
|
17345
|
+
return tryAsBigGas(gasConsumed);
|
|
16619
17346
|
}
|
|
16620
17347
|
}
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16624
|
-
|
|
16625
|
-
|
|
16626
|
-
|
|
16627
|
-
|
|
16628
|
-
this.
|
|
16629
|
-
|
|
16630
|
-
|
|
16631
|
-
|
|
17348
|
+
class AnanasInterpreter {
|
|
17349
|
+
instance;
|
|
17350
|
+
registers;
|
|
17351
|
+
memory;
|
|
17352
|
+
gas;
|
|
17353
|
+
constructor(instance) {
|
|
17354
|
+
this.instance = instance;
|
|
17355
|
+
this.registers = new AnanasRegisters(instance);
|
|
17356
|
+
this.memory = new AnanasMemory(instance);
|
|
17357
|
+
this.gas = new AnanasGasCounter(instance);
|
|
17358
|
+
}
|
|
17359
|
+
static async new() {
|
|
17360
|
+
const wasmModule = await WebAssembly.compile(wasmBuffer);
|
|
17361
|
+
const instance = await instantiate(wasmModule, {
|
|
17362
|
+
env: {
|
|
17363
|
+
abort: () => {
|
|
17364
|
+
throw new Error("Abort called from WASM");
|
|
17365
|
+
},
|
|
17366
|
+
},
|
|
17367
|
+
});
|
|
17368
|
+
return new AnanasInterpreter(instance);
|
|
17369
|
+
}
|
|
17370
|
+
resetJam(program, args, pc, gas) {
|
|
17371
|
+
const programArr = lowerBytes(program);
|
|
17372
|
+
const argsArr = lowerBytes(args);
|
|
17373
|
+
this.gas.initialGas = gas;
|
|
17374
|
+
this.instance.resetJAM(programArr, pc, BigInt(gas), argsArr, true);
|
|
17375
|
+
}
|
|
17376
|
+
resetGeneric(program, _pc, gas) {
|
|
17377
|
+
const programArr = lowerBytes(program);
|
|
17378
|
+
const emptyRegisters = Array(13 * 8).fill(0);
|
|
17379
|
+
const pageMap = new Uint8Array();
|
|
17380
|
+
const chunks = new Uint8Array();
|
|
17381
|
+
this.gas.initialGas = gas;
|
|
17382
|
+
this.instance.resetGenericWithMemory(programArr, emptyRegisters, pageMap, chunks, BigInt(gas), false);
|
|
17383
|
+
}
|
|
17384
|
+
nextStep() {
|
|
17385
|
+
return this.instance.nextStep();
|
|
17386
|
+
}
|
|
17387
|
+
runProgram() {
|
|
17388
|
+
// NOTE Setting max value u32 in nNextSteps making ananas running until finished
|
|
17389
|
+
// without comming back and forth between JS <-> WASM
|
|
17390
|
+
while (this.instance.nSteps(INF_STEPS)) { }
|
|
17391
|
+
}
|
|
17392
|
+
getStatus() {
|
|
17393
|
+
const status = this.instance.getStatus();
|
|
17394
|
+
if (status < 0) {
|
|
17395
|
+
return Status.OK;
|
|
16632
17396
|
}
|
|
17397
|
+
check `${Status[status] !== undefined} Invalid status returned: ${status}`;
|
|
17398
|
+
return status;
|
|
16633
17399
|
}
|
|
16634
|
-
|
|
16635
|
-
|
|
16636
|
-
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
17400
|
+
getPC() {
|
|
17401
|
+
return this.instance.getProgramCounter();
|
|
16637
17402
|
}
|
|
16638
|
-
|
|
16639
|
-
|
|
16640
|
-
|
|
16641
|
-
|
|
16642
|
-
|
|
16643
|
-
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
|
|
16647
|
-
})
|
|
16648
|
-
.join(", ");
|
|
16649
|
-
logger.insane `[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
17403
|
+
getExitParam() {
|
|
17404
|
+
return tryAsU32(this.instance.getExitArg());
|
|
17405
|
+
}
|
|
17406
|
+
}
|
|
17407
|
+
/** Convert `Uint8Array` to `number[]` */
|
|
17408
|
+
function lowerBytes(data) {
|
|
17409
|
+
const r = new Array(data.length);
|
|
17410
|
+
for (let i = 0; i < data.length; i++) {
|
|
17411
|
+
r[i] = data[i];
|
|
16650
17412
|
}
|
|
17413
|
+
return r;
|
|
16651
17414
|
}
|
|
16652
17415
|
|
|
17416
|
+
// TODO [MaSo] Delete this & also make host calls independent from intepreters.
|
|
16653
17417
|
class InterpreterInstanceManager {
|
|
16654
|
-
instances
|
|
17418
|
+
instances;
|
|
16655
17419
|
waitingQueue = [];
|
|
16656
|
-
constructor(
|
|
16657
|
-
|
|
16658
|
-
|
|
16659
|
-
|
|
16660
|
-
|
|
17420
|
+
constructor(instances) {
|
|
17421
|
+
this.instances = instances;
|
|
17422
|
+
}
|
|
17423
|
+
static async new(interpreter) {
|
|
17424
|
+
const instances = [];
|
|
17425
|
+
switch (interpreter) {
|
|
17426
|
+
case PvmBackend.BuiltIn:
|
|
17427
|
+
instances.push(new Interpreter({
|
|
17428
|
+
useSbrkGas: false,
|
|
17429
|
+
}));
|
|
17430
|
+
break;
|
|
17431
|
+
case PvmBackend.Ananas:
|
|
17432
|
+
instances.push(await AnanasInterpreter.new());
|
|
17433
|
+
break;
|
|
17434
|
+
default:
|
|
17435
|
+
assertNever(interpreter);
|
|
16661
17436
|
}
|
|
17437
|
+
return new InterpreterInstanceManager(instances);
|
|
16662
17438
|
}
|
|
16663
17439
|
async getInstance() {
|
|
16664
17440
|
const instance = this.instances.pop();
|
|
@@ -16678,7 +17454,7 @@ class InterpreterInstanceManager {
|
|
|
16678
17454
|
}
|
|
16679
17455
|
}
|
|
16680
17456
|
|
|
16681
|
-
var index$
|
|
17457
|
+
var index$4 = /*#__PURE__*/Object.freeze({
|
|
16682
17458
|
__proto__: null,
|
|
16683
17459
|
HostCallMemory: HostCallMemory,
|
|
16684
17460
|
HostCallRegisters: HostCallRegisters,
|
|
@@ -16690,194 +17466,6 @@ var index$6 = /*#__PURE__*/Object.freeze({
|
|
|
16690
17466
|
tryAsHostCallIndex: tryAsHostCallIndex
|
|
16691
17467
|
});
|
|
16692
17468
|
|
|
16693
|
-
// GP reference: https://graypaper.fluffylabs.dev/#/7e6ff6a/2d32002d3200?v=0.6.7
|
|
16694
|
-
const PAGE_SIZE = 2 ** 12; // Z_P from GP
|
|
16695
|
-
const SEGMENT_SIZE = 2 ** 16; // Z_Z from GP
|
|
16696
|
-
const DATA_LEGNTH = 2 ** 24; // Z_I from GP
|
|
16697
|
-
const STACK_SEGMENT = 0xfe_fe_00_00; // 2^32 - 2Z_Z - Z_I from GP
|
|
16698
|
-
const ARGS_SEGMENT = 0xfe_ff_00_00; // 2^32 - Z_Z - Z_I from GP
|
|
16699
|
-
const LAST_PAGE = 0xff_ff_00_00;
|
|
16700
|
-
|
|
16701
|
-
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2bd2022bd202
|
|
16702
|
-
function alignToSegmentSize(size) {
|
|
16703
|
-
// Q(x) from GP
|
|
16704
|
-
return SEGMENT_SIZE * Math.ceil(size / SEGMENT_SIZE);
|
|
16705
|
-
}
|
|
16706
|
-
function alignToPageSize(size) {
|
|
16707
|
-
// P(x) from GP
|
|
16708
|
-
return PAGE_SIZE * Math.ceil(size / PAGE_SIZE);
|
|
16709
|
-
}
|
|
16710
|
-
|
|
16711
|
-
const NO_OF_REGISTERS = 13;
|
|
16712
|
-
class MemorySegment extends WithDebug {
|
|
16713
|
-
start;
|
|
16714
|
-
end;
|
|
16715
|
-
data;
|
|
16716
|
-
static from({ start, end, data }) {
|
|
16717
|
-
return new MemorySegment(start, end, data);
|
|
16718
|
-
}
|
|
16719
|
-
constructor(start, end, data) {
|
|
16720
|
-
super();
|
|
16721
|
-
this.start = start;
|
|
16722
|
-
this.end = end;
|
|
16723
|
-
this.data = data;
|
|
16724
|
-
}
|
|
16725
|
-
}
|
|
16726
|
-
class SpiMemory extends WithDebug {
|
|
16727
|
-
readable;
|
|
16728
|
-
writeable;
|
|
16729
|
-
sbrkIndex;
|
|
16730
|
-
heapEnd;
|
|
16731
|
-
constructor(readable, writeable, sbrkIndex, heapEnd) {
|
|
16732
|
-
super();
|
|
16733
|
-
this.readable = readable;
|
|
16734
|
-
this.writeable = writeable;
|
|
16735
|
-
this.sbrkIndex = sbrkIndex;
|
|
16736
|
-
this.heapEnd = heapEnd;
|
|
16737
|
-
}
|
|
16738
|
-
}
|
|
16739
|
-
class SpiProgram extends WithDebug {
|
|
16740
|
-
code;
|
|
16741
|
-
memory;
|
|
16742
|
-
registers;
|
|
16743
|
-
constructor(code, memory, registers) {
|
|
16744
|
-
super();
|
|
16745
|
-
this.code = code;
|
|
16746
|
-
this.memory = memory;
|
|
16747
|
-
this.registers = registers;
|
|
16748
|
-
}
|
|
16749
|
-
}
|
|
16750
|
-
/**
|
|
16751
|
-
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
16752
|
-
*
|
|
16753
|
-
* E_n - little endian encoding, n - length
|
|
16754
|
-
* o - initial read only data
|
|
16755
|
-
* w - initial heap
|
|
16756
|
-
* z - heap pages filled with zeros
|
|
16757
|
-
* s - stack size
|
|
16758
|
-
* c - program code
|
|
16759
|
-
*
|
|
16760
|
-
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
16761
|
-
*/
|
|
16762
|
-
function decodeStandardProgram(program, args) {
|
|
16763
|
-
const decoder = Decoder.fromBlob(program);
|
|
16764
|
-
const oLength = decoder.u24();
|
|
16765
|
-
const wLength = decoder.u24();
|
|
16766
|
-
check `${args.length <= DATA_LEGNTH} Incorrect arguments length`;
|
|
16767
|
-
check `${oLength <= DATA_LEGNTH} Incorrect readonly segment length`;
|
|
16768
|
-
const readOnlyLength = oLength;
|
|
16769
|
-
check `${wLength <= DATA_LEGNTH} Incorrect heap segment length`;
|
|
16770
|
-
const heapLength = wLength;
|
|
16771
|
-
const noOfHeapZerosPages = decoder.u16();
|
|
16772
|
-
const stackSize = decoder.u24();
|
|
16773
|
-
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
16774
|
-
const initialHeap = decoder.bytes(heapLength).raw;
|
|
16775
|
-
const codeLength = decoder.u32();
|
|
16776
|
-
const code = decoder.bytes(codeLength).raw;
|
|
16777
|
-
decoder.finish();
|
|
16778
|
-
const readonlyDataStart = SEGMENT_SIZE;
|
|
16779
|
-
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
16780
|
-
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
16781
|
-
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
16782
|
-
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
16783
|
-
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
16784
|
-
const stackEnd = STACK_SEGMENT;
|
|
16785
|
-
const argsStart = ARGS_SEGMENT;
|
|
16786
|
-
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
16787
|
-
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
16788
|
-
function nonEmpty(s) {
|
|
16789
|
-
return s !== false;
|
|
16790
|
-
}
|
|
16791
|
-
const readableMemory = [
|
|
16792
|
-
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
16793
|
-
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
16794
|
-
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
16795
|
-
].filter(nonEmpty);
|
|
16796
|
-
const writeableMemory = [
|
|
16797
|
-
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
16798
|
-
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
16799
|
-
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
16800
|
-
].filter(nonEmpty);
|
|
16801
|
-
return new SpiProgram(code, new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart), getRegisters(args.length));
|
|
16802
|
-
}
|
|
16803
|
-
function getMemorySegment(start, end, data = null) {
|
|
16804
|
-
return new MemorySegment(start, end, data);
|
|
16805
|
-
}
|
|
16806
|
-
function getRegisters(argsLength) {
|
|
16807
|
-
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
16808
|
-
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
16809
|
-
regs[0] = BigInt(LAST_PAGE);
|
|
16810
|
-
regs[1] = BigInt(STACK_SEGMENT);
|
|
16811
|
-
regs[7] = BigInt(ARGS_SEGMENT);
|
|
16812
|
-
regs[8] = BigInt(argsLength);
|
|
16813
|
-
return regs;
|
|
16814
|
-
}
|
|
16815
|
-
|
|
16816
|
-
var index$5 = /*#__PURE__*/Object.freeze({
|
|
16817
|
-
__proto__: null,
|
|
16818
|
-
MemorySegment: MemorySegment,
|
|
16819
|
-
SpiMemory: SpiMemory,
|
|
16820
|
-
SpiProgram: SpiProgram,
|
|
16821
|
-
decodeStandardProgram: decodeStandardProgram
|
|
16822
|
-
});
|
|
16823
|
-
|
|
16824
|
-
class Program {
|
|
16825
|
-
code;
|
|
16826
|
-
registers;
|
|
16827
|
-
memory;
|
|
16828
|
-
metadata;
|
|
16829
|
-
static fromSpi(blob, args, hasMetadata) {
|
|
16830
|
-
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
16831
|
-
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
16832
|
-
const regs = new Registers();
|
|
16833
|
-
regs.copyFrom(registers);
|
|
16834
|
-
const memoryBuilder = new MemoryBuilder();
|
|
16835
|
-
for (const { start, end, data } of rawMemory.readable) {
|
|
16836
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
16837
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
16838
|
-
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
16839
|
-
}
|
|
16840
|
-
for (const { start, end, data } of rawMemory.writeable) {
|
|
16841
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
16842
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
16843
|
-
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
16844
|
-
}
|
|
16845
|
-
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
16846
|
-
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
16847
|
-
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
16848
|
-
return new Program(code, regs, memory, metadata);
|
|
16849
|
-
}
|
|
16850
|
-
static fromGeneric(blob, hasMetadata) {
|
|
16851
|
-
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
16852
|
-
const regs = new Registers();
|
|
16853
|
-
const memory = new Memory();
|
|
16854
|
-
return new Program(code, regs, memory, metadata);
|
|
16855
|
-
}
|
|
16856
|
-
constructor(code, registers, memory, metadata = new Uint8Array()) {
|
|
16857
|
-
this.code = code;
|
|
16858
|
-
this.registers = registers;
|
|
16859
|
-
this.memory = memory;
|
|
16860
|
-
this.metadata = metadata;
|
|
16861
|
-
}
|
|
16862
|
-
}
|
|
16863
|
-
/**
|
|
16864
|
-
* A function that splits preimage into metadata and code.
|
|
16865
|
-
*
|
|
16866
|
-
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
16867
|
-
*/
|
|
16868
|
-
function extractCodeAndMetadata(blobWithMetadata) {
|
|
16869
|
-
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
16870
|
-
const metadata = decoder.bytesBlob().raw;
|
|
16871
|
-
const code = decoder.remainingBytes().raw;
|
|
16872
|
-
return { metadata, code };
|
|
16873
|
-
}
|
|
16874
|
-
|
|
16875
|
-
var index$4 = /*#__PURE__*/Object.freeze({
|
|
16876
|
-
__proto__: null,
|
|
16877
|
-
Program: Program,
|
|
16878
|
-
extractCodeAndMetadata: extractCodeAndMetadata
|
|
16879
|
-
});
|
|
16880
|
-
|
|
16881
17469
|
class DebuggerAdapter {
|
|
16882
17470
|
pvm;
|
|
16883
17471
|
constructor(useSbrkGas = false) {
|
|
@@ -16888,10 +17476,10 @@ class DebuggerAdapter {
|
|
|
16888
17476
|
return this.pvm;
|
|
16889
17477
|
}
|
|
16890
17478
|
resetGeneric(rawProgram, flatRegisters, initialGas) {
|
|
16891
|
-
this.pvm.
|
|
17479
|
+
this.pvm.resetGeneric(rawProgram, 0, tryAsGas(initialGas), new Registers(flatRegisters));
|
|
16892
17480
|
}
|
|
16893
17481
|
reset(rawProgram, pc, gas, maybeRegisters, maybeMemory) {
|
|
16894
|
-
this.pvm.
|
|
17482
|
+
this.pvm.resetGeneric(rawProgram, pc, tryAsGas(gas), maybeRegisters, maybeMemory);
|
|
16895
17483
|
}
|
|
16896
17484
|
getPageDump(pageNumber) {
|
|
16897
17485
|
const page = this.pvm.getMemoryPage(pageNumber);
|
|
@@ -16909,7 +17497,7 @@ class DebuggerAdapter {
|
|
|
16909
17497
|
return fullPage;
|
|
16910
17498
|
}
|
|
16911
17499
|
setMemory(address, value) {
|
|
16912
|
-
this.pvm.
|
|
17500
|
+
this.pvm.memory.storeFrom(tryAsMemoryIndex(address), value);
|
|
16913
17501
|
}
|
|
16914
17502
|
getExitArg() {
|
|
16915
17503
|
return this.pvm.getExitParam() ?? 0;
|
|
@@ -16931,10 +17519,10 @@ class DebuggerAdapter {
|
|
|
16931
17519
|
return true;
|
|
16932
17520
|
}
|
|
16933
17521
|
getRegisters() {
|
|
16934
|
-
return this.pvm.
|
|
17522
|
+
return this.pvm.registers.getAllU64();
|
|
16935
17523
|
}
|
|
16936
17524
|
setRegisters(registers) {
|
|
16937
|
-
this.pvm.
|
|
17525
|
+
this.pvm.registers.copyFrom(new Registers(registers));
|
|
16938
17526
|
}
|
|
16939
17527
|
getProgramCounter() {
|
|
16940
17528
|
return this.pvm.getPC();
|
|
@@ -16943,10 +17531,10 @@ class DebuggerAdapter {
|
|
|
16943
17531
|
this.pvm.setNextPC(nextPc);
|
|
16944
17532
|
}
|
|
16945
17533
|
getGasLeft() {
|
|
16946
|
-
return BigInt(this.pvm.
|
|
17534
|
+
return BigInt(this.pvm.gas.get());
|
|
16947
17535
|
}
|
|
16948
17536
|
setGasLeft(gas) {
|
|
16949
|
-
this.pvm.
|
|
17537
|
+
this.pvm.gas.set(tryAsGas(gas));
|
|
16950
17538
|
}
|
|
16951
17539
|
}
|
|
16952
17540
|
|
|
@@ -17005,13 +17593,14 @@ var index$3 = /*#__PURE__*/Object.freeze({
|
|
|
17005
17593
|
clampU64ToU32: clampU64ToU32,
|
|
17006
17594
|
createResults: createResults,
|
|
17007
17595
|
decodeStandardProgram: decodeStandardProgram,
|
|
17596
|
+
emptyRegistersBuffer: emptyRegistersBuffer,
|
|
17008
17597
|
extractCodeAndMetadata: extractCodeAndMetadata,
|
|
17009
17598
|
getServiceId: getServiceId,
|
|
17010
17599
|
getServiceIdOrCurrent: getServiceIdOrCurrent,
|
|
17011
17600
|
hash: index$o,
|
|
17012
17601
|
inspect: inspect,
|
|
17013
17602
|
instructionArgumentTypeMap: instructionArgumentTypeMap,
|
|
17014
|
-
interpreter: index$
|
|
17603
|
+
interpreter: index$5,
|
|
17015
17604
|
isBrowser: isBrowser,
|
|
17016
17605
|
measure: measure,
|
|
17017
17606
|
numbers: index$r,
|
|
@@ -17637,10 +18226,10 @@ exports.mmr = index$8;
|
|
|
17637
18226
|
exports.numbers = index$r;
|
|
17638
18227
|
exports.ordering = index$t;
|
|
17639
18228
|
exports.pvm = index$3;
|
|
17640
|
-
exports.pvm_host_calls = index$
|
|
17641
|
-
exports.pvm_interpreter = index$
|
|
17642
|
-
exports.pvm_program = index$
|
|
17643
|
-
exports.pvm_spi_decoder = index$
|
|
18229
|
+
exports.pvm_host_calls = index$4;
|
|
18230
|
+
exports.pvm_interpreter = index$5;
|
|
18231
|
+
exports.pvm_program = index$6;
|
|
18232
|
+
exports.pvm_spi_decoder = index$7;
|
|
17644
18233
|
exports.shuffling = index$2;
|
|
17645
18234
|
exports.state = index$g;
|
|
17646
18235
|
exports.state_json = index$1;
|