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