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