@typeberry/lib 0.2.0-c96e8ef → 0.2.0-daa61f5
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 +2626 -1925
- package/index.d.ts +2096 -1883
- package/index.js +2624 -1923
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ declare enum GpVersion {
|
|
|
2
2
|
V0_6_7 = "0.6.7",
|
|
3
3
|
V0_7_0 = "0.7.0",
|
|
4
4
|
V0_7_1 = "0.7.1",
|
|
5
|
-
V0_7_2 = "0.7.2
|
|
5
|
+
V0_7_2 = "0.7.2",
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
declare enum TestSuite {
|
|
@@ -10,43 +10,39 @@ declare enum TestSuite {
|
|
|
10
10
|
JAMDUNA = "jamduna",
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
declare const ALL_VERSIONS_IN_ORDER = [GpVersion.V0_6_7, GpVersion.V0_7_0, GpVersion.V0_7_1, GpVersion.V0_7_2];
|
|
14
|
+
|
|
13
15
|
declare const DEFAULT_SUITE = TestSuite.W3F_DAVXY;
|
|
14
|
-
declare const DEFAULT_VERSION = GpVersion.
|
|
16
|
+
declare const DEFAULT_VERSION = GpVersion.V0_7_2;
|
|
15
17
|
declare let CURRENT_VERSION = parseCurrentVersion(env.GP_VERSION) ?? DEFAULT_VERSION;
|
|
16
18
|
declare let CURRENT_SUITE = parseCurrentSuite(env.TEST_SUITE) ?? DEFAULT_SUITE;
|
|
17
19
|
|
|
18
|
-
declare const ALL_VERSIONS_IN_ORDER = [GpVersion.V0_6_7, GpVersion.V0_7_0, GpVersion.V0_7_1, GpVersion.V0_7_2];
|
|
19
|
-
|
|
20
20
|
declare function parseCurrentVersion(env?: string): GpVersion | undefined {
|
|
21
21
|
if (env === undefined) {
|
|
22
22
|
return undefined;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
case GpVersion.V0_7_2:
|
|
29
|
-
return env;
|
|
30
|
-
default:
|
|
31
|
-
throw new Error(
|
|
32
|
-
`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`,
|
|
33
|
-
);
|
|
24
|
+
for (const v of Object.values(GpVersion)) {
|
|
25
|
+
if (env === v) {
|
|
26
|
+
return v;
|
|
27
|
+
}
|
|
34
28
|
}
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`,
|
|
31
|
+
);
|
|
35
32
|
}
|
|
36
33
|
|
|
37
34
|
declare function parseCurrentSuite(env?: string): TestSuite | undefined {
|
|
38
35
|
if (env === undefined) {
|
|
39
36
|
return undefined;
|
|
40
37
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
default:
|
|
46
|
-
throw new Error(
|
|
47
|
-
`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`,
|
|
48
|
-
);
|
|
38
|
+
for (const s of Object.values(TestSuite)) {
|
|
39
|
+
if (env === s) {
|
|
40
|
+
return s;
|
|
41
|
+
}
|
|
49
42
|
}
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`,
|
|
45
|
+
);
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
declare class Compatibility {
|
|
@@ -5117,6 +5113,17 @@ declare class Bootnode implements PeerAddress {
|
|
|
5117
5113
|
}
|
|
5118
5114
|
}
|
|
5119
5115
|
|
|
5116
|
+
/** Implemented PVM Backends names in THE SAME ORDER as enum. */
|
|
5117
|
+
declare const PvmBackendNames = ["built-in", "ananas"];
|
|
5118
|
+
|
|
5119
|
+
/** Implemented PVM Backends to choose from. */
|
|
5120
|
+
declare enum PvmBackend {
|
|
5121
|
+
/** Built-in aka. Typeberry 🫐 interpreter. */
|
|
5122
|
+
BuiltIn = 0,
|
|
5123
|
+
/** Ananas 🍍 interpreter. */
|
|
5124
|
+
Ananas = 1,
|
|
5125
|
+
}
|
|
5126
|
+
|
|
5120
5127
|
type index$m_Bootnode = Bootnode;
|
|
5121
5128
|
declare const index$m_Bootnode: typeof Bootnode;
|
|
5122
5129
|
type index$m_ChainSpec = ChainSpec;
|
|
@@ -5128,10 +5135,13 @@ declare const index$m_EST_VALIDATORS: typeof EST_VALIDATORS;
|
|
|
5128
5135
|
declare const index$m_EST_VALIDATORS_SUPER_MAJORITY: typeof EST_VALIDATORS_SUPER_MAJORITY;
|
|
5129
5136
|
type index$m_PeerAddress = PeerAddress;
|
|
5130
5137
|
type index$m_PeerId = PeerId;
|
|
5138
|
+
type index$m_PvmBackend = PvmBackend;
|
|
5139
|
+
declare const index$m_PvmBackend: typeof PvmBackend;
|
|
5140
|
+
declare const index$m_PvmBackendNames: typeof PvmBackendNames;
|
|
5131
5141
|
declare const index$m_fullChainSpec: typeof fullChainSpec;
|
|
5132
5142
|
declare const index$m_tinyChainSpec: typeof tinyChainSpec;
|
|
5133
5143
|
declare namespace index$m {
|
|
5134
|
-
export { index$m_Bootnode as Bootnode, index$m_ChainSpec as ChainSpec, index$m_EC_SEGMENT_SIZE as EC_SEGMENT_SIZE, index$m_EST_CORES as EST_CORES, index$m_EST_EPOCH_LENGTH as EST_EPOCH_LENGTH, index$m_EST_VALIDATORS as EST_VALIDATORS, index$m_EST_VALIDATORS_SUPER_MAJORITY as EST_VALIDATORS_SUPER_MAJORITY, index$m_fullChainSpec as fullChainSpec, index$m_tinyChainSpec as tinyChainSpec };
|
|
5144
|
+
export { index$m_Bootnode as Bootnode, index$m_ChainSpec as ChainSpec, index$m_EC_SEGMENT_SIZE as EC_SEGMENT_SIZE, index$m_EST_CORES as EST_CORES, index$m_EST_EPOCH_LENGTH as EST_EPOCH_LENGTH, index$m_EST_VALIDATORS as EST_VALIDATORS, index$m_EST_VALIDATORS_SUPER_MAJORITY as EST_VALIDATORS_SUPER_MAJORITY, index$m_PvmBackend as PvmBackend, index$m_PvmBackendNames as PvmBackendNames, index$m_fullChainSpec as fullChainSpec, index$m_tinyChainSpec as tinyChainSpec };
|
|
5135
5145
|
export type { index$m_PeerAddress as PeerAddress, index$m_PeerId as PeerId };
|
|
5136
5146
|
}
|
|
5137
5147
|
|
|
@@ -8154,7 +8164,8 @@ declare const DEFAULT_CONFIG = "default";
|
|
|
8154
8164
|
|
|
8155
8165
|
declare const NODE_DEFAULTS = {
|
|
8156
8166
|
name: isBrowser() ? "browser" : os.hostname(),
|
|
8157
|
-
config: DEFAULT_CONFIG,
|
|
8167
|
+
config: [DEFAULT_CONFIG],
|
|
8168
|
+
pvm: PvmBackend.BuiltIn,
|
|
8158
8169
|
};
|
|
8159
8170
|
|
|
8160
8171
|
/** Chain spec chooser. */
|
|
@@ -8207,52 +8218,173 @@ declare class NodeConfiguration {
|
|
|
8207
8218
|
) {}
|
|
8208
8219
|
}
|
|
8209
8220
|
|
|
8210
|
-
declare function loadConfig(
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8221
|
+
declare function loadConfig(config: string[], withRelPath: (p: string) => string): NodeConfiguration {
|
|
8222
|
+
logger.log`🔧 Loading config`;
|
|
8223
|
+
let mergedJson: AnyJsonObject = {};
|
|
8224
|
+
|
|
8225
|
+
for (const entry of config) {
|
|
8226
|
+
logger.log`🔧 Applying '${entry}'`;
|
|
8227
|
+
|
|
8228
|
+
if (entry === DEV_CONFIG) {
|
|
8229
|
+
mergedJson = structuredClone(configs.dev); // clone to avoid mutating the original config. not doing a merge since dev and default should theoretically replace all properties.
|
|
8230
|
+
continue;
|
|
8231
|
+
}
|
|
8232
|
+
|
|
8233
|
+
if (entry === DEFAULT_CONFIG) {
|
|
8234
|
+
mergedJson = structuredClone(configs.default);
|
|
8235
|
+
continue;
|
|
8236
|
+
}
|
|
8215
8237
|
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8238
|
+
// try to parse as JSON
|
|
8239
|
+
try {
|
|
8240
|
+
const parsed = JSON.parse(entry);
|
|
8241
|
+
deepMerge(mergedJson, parsed);
|
|
8242
|
+
continue;
|
|
8243
|
+
} catch {}
|
|
8244
|
+
|
|
8245
|
+
// if not, try to load as file
|
|
8246
|
+
if (entry.indexOf("=") === -1 && entry.endsWith(".json")) {
|
|
8247
|
+
try {
|
|
8248
|
+
const configFile = fs.readFileSync(withRelPath(entry), "utf8");
|
|
8249
|
+
const parsed = JSON.parse(configFile);
|
|
8250
|
+
deepMerge(mergedJson, parsed);
|
|
8251
|
+
} catch (e) {
|
|
8252
|
+
throw new Error(`Unable to load config from ${entry}: ${e}`);
|
|
8253
|
+
}
|
|
8254
|
+
} else {
|
|
8255
|
+
// finally try to process as a pseudo-jq query
|
|
8256
|
+
try {
|
|
8257
|
+
processQuery(mergedJson, entry, withRelPath);
|
|
8258
|
+
} catch (e) {
|
|
8259
|
+
throw new Error(`Error while processing '${entry}': ${e}`);
|
|
8260
|
+
}
|
|
8261
|
+
}
|
|
8219
8262
|
}
|
|
8220
8263
|
|
|
8221
8264
|
try {
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
return parseFromJson(parsed, NodeConfiguration.fromJson);
|
|
8265
|
+
const parsed = parseFromJson(mergedJson, NodeConfiguration.fromJson);
|
|
8266
|
+
logger.log`🔧 Config ready`;
|
|
8267
|
+
return parsed;
|
|
8226
8268
|
} catch (e) {
|
|
8227
|
-
throw new Error(`Unable to
|
|
8269
|
+
throw new Error(`Unable to parse config: ${e}`);
|
|
8270
|
+
}
|
|
8271
|
+
}
|
|
8272
|
+
|
|
8273
|
+
declare function deepMerge(target: AnyJsonObject, source: JsonValue): void {
|
|
8274
|
+
if (!isJsonObject(source)) {
|
|
8275
|
+
throw new Error(`Expected object, got ${source}`);
|
|
8276
|
+
}
|
|
8277
|
+
for (const key in source) {
|
|
8278
|
+
if (isJsonObject(source[key])) {
|
|
8279
|
+
if (!isJsonObject(target[key])) {
|
|
8280
|
+
target[key] = {};
|
|
8281
|
+
}
|
|
8282
|
+
deepMerge(target[key], source[key]);
|
|
8283
|
+
} else {
|
|
8284
|
+
target[key] = source[key];
|
|
8285
|
+
}
|
|
8286
|
+
}
|
|
8287
|
+
}
|
|
8288
|
+
|
|
8289
|
+
/**
|
|
8290
|
+
* Caution: updates input directly.
|
|
8291
|
+
* Processes a pseudo-jq query. Syntax:
|
|
8292
|
+
* .path.to.value = { ... } - updates value with the specified object by replacement
|
|
8293
|
+
* .path.to.value += { ... } - updates value with the specified object by merging
|
|
8294
|
+
* .path.to.value = file.json - updates value with the contents of file.json
|
|
8295
|
+
* .path.to.value += file.json - merges the contents of file.json onto value
|
|
8296
|
+
*/
|
|
8297
|
+
declare function processQuery(input: AnyJsonObject, query: string, withRelPath: (p: string) => string): void {
|
|
8298
|
+
const queryParts = query.split("=");
|
|
8299
|
+
|
|
8300
|
+
if (queryParts.length === 2) {
|
|
8301
|
+
let [path, value] = queryParts.map((part) => part.trim());
|
|
8302
|
+
let merge = false;
|
|
8303
|
+
|
|
8304
|
+
// detect += syntax
|
|
8305
|
+
if (path.endsWith("+")) {
|
|
8306
|
+
merge = true;
|
|
8307
|
+
path = path.slice(0, -1);
|
|
8308
|
+
}
|
|
8309
|
+
|
|
8310
|
+
let parsedValue: JsonValue;
|
|
8311
|
+
if (value.endsWith(".json")) {
|
|
8312
|
+
try {
|
|
8313
|
+
const configFile = fs.readFileSync(withRelPath(value), "utf8");
|
|
8314
|
+
const parsed = JSON.parse(configFile);
|
|
8315
|
+
parsedValue = parsed;
|
|
8316
|
+
} catch (e) {
|
|
8317
|
+
throw new Error(`Unable to load config from ${value}: ${e}`);
|
|
8318
|
+
}
|
|
8319
|
+
} else {
|
|
8320
|
+
try {
|
|
8321
|
+
parsedValue = JSON.parse(value);
|
|
8322
|
+
} catch (e) {
|
|
8323
|
+
throw new Error(`Unrecognized syntax '${value}': ${e}`);
|
|
8324
|
+
}
|
|
8325
|
+
}
|
|
8326
|
+
|
|
8327
|
+
let pathParts = path.split(".");
|
|
8328
|
+
|
|
8329
|
+
// allow leading dot in path
|
|
8330
|
+
if (pathParts[0] === "") {
|
|
8331
|
+
pathParts = pathParts.slice(1);
|
|
8332
|
+
}
|
|
8333
|
+
|
|
8334
|
+
let target = input;
|
|
8335
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
8336
|
+
const part = pathParts[i];
|
|
8337
|
+
if (!isJsonObject(target[part])) {
|
|
8338
|
+
target[part] = {};
|
|
8339
|
+
}
|
|
8340
|
+
if (i === pathParts.length - 1) {
|
|
8341
|
+
if (merge) {
|
|
8342
|
+
deepMerge(target[part], parsedValue);
|
|
8343
|
+
} else {
|
|
8344
|
+
target[part] = parsedValue;
|
|
8345
|
+
}
|
|
8346
|
+
return;
|
|
8347
|
+
}
|
|
8348
|
+
target = target[part];
|
|
8349
|
+
}
|
|
8228
8350
|
}
|
|
8351
|
+
|
|
8352
|
+
throw new Error("Unrecognized syntax.");
|
|
8353
|
+
}
|
|
8354
|
+
|
|
8355
|
+
type JsonValue = string | number | boolean | null | AnyJsonObject | JsonArray;
|
|
8356
|
+
|
|
8357
|
+
interface AnyJsonObject {
|
|
8358
|
+
[key: string]: JsonValue;
|
|
8359
|
+
}
|
|
8360
|
+
|
|
8361
|
+
interface JsonArray extends Array<JsonValue> {}
|
|
8362
|
+
|
|
8363
|
+
declare function isJsonObject(value: JsonValue): value is AnyJsonObject {
|
|
8364
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8229
8365
|
}
|
|
8230
8366
|
|
|
8367
|
+
type index$h_AnyJsonObject = AnyJsonObject;
|
|
8231
8368
|
declare const index$h_DEFAULT_CONFIG: typeof DEFAULT_CONFIG;
|
|
8232
8369
|
declare const index$h_DEV_CONFIG: typeof DEV_CONFIG;
|
|
8233
8370
|
type index$h_JipChainSpec = JipChainSpec;
|
|
8234
8371
|
declare const index$h_JipChainSpec: typeof JipChainSpec;
|
|
8372
|
+
type index$h_JsonArray = JsonArray;
|
|
8373
|
+
type index$h_JsonValue = JsonValue;
|
|
8235
8374
|
type index$h_KnownChainSpec = KnownChainSpec;
|
|
8236
8375
|
declare const index$h_KnownChainSpec: typeof KnownChainSpec;
|
|
8237
8376
|
declare const index$h_NODE_DEFAULTS: typeof NODE_DEFAULTS;
|
|
8238
8377
|
type index$h_NodeConfiguration = NodeConfiguration;
|
|
8239
8378
|
declare const index$h_NodeConfiguration: typeof NodeConfiguration;
|
|
8379
|
+
declare const index$h_deepMerge: typeof deepMerge;
|
|
8380
|
+
declare const index$h_isJsonObject: typeof isJsonObject;
|
|
8240
8381
|
declare const index$h_knownChainSpecFromJson: typeof knownChainSpecFromJson;
|
|
8241
8382
|
declare const index$h_loadConfig: typeof loadConfig;
|
|
8242
8383
|
declare const index$h_parseBootnode: typeof parseBootnode;
|
|
8384
|
+
declare const index$h_processQuery: typeof processQuery;
|
|
8243
8385
|
declare namespace index$h {
|
|
8244
|
-
export {
|
|
8245
|
-
|
|
8246
|
-
index$h_DEV_CONFIG as DEV_CONFIG,
|
|
8247
|
-
index$h_JipChainSpec as JipChainSpec,
|
|
8248
|
-
index$h_KnownChainSpec as KnownChainSpec,
|
|
8249
|
-
index$h_NODE_DEFAULTS as NODE_DEFAULTS,
|
|
8250
|
-
index$h_NodeConfiguration as NodeConfiguration,
|
|
8251
|
-
index$h_knownChainSpecFromJson as knownChainSpecFromJson,
|
|
8252
|
-
index$h_loadConfig as loadConfig,
|
|
8253
|
-
logger$2 as logger,
|
|
8254
|
-
index$h_parseBootnode as parseBootnode,
|
|
8255
|
-
};
|
|
8386
|
+
export { index$h_DEFAULT_CONFIG as DEFAULT_CONFIG, index$h_DEV_CONFIG as DEV_CONFIG, index$h_JipChainSpec as JipChainSpec, index$h_KnownChainSpec as KnownChainSpec, index$h_NODE_DEFAULTS as NODE_DEFAULTS, index$h_NodeConfiguration as NodeConfiguration, index$h_deepMerge as deepMerge, index$h_isJsonObject as isJsonObject, index$h_knownChainSpecFromJson as knownChainSpecFromJson, index$h_loadConfig as loadConfig, logger$2 as logger, index$h_parseBootnode as parseBootnode, index$h_processQuery as processQuery };
|
|
8387
|
+
export type { index$h_AnyJsonObject as AnyJsonObject, index$h_JsonArray as JsonArray, index$h_JsonValue as JsonValue };
|
|
8256
8388
|
}
|
|
8257
8389
|
|
|
8258
8390
|
/**
|
|
@@ -12247,6 +12379,18 @@ declare class StateEntries {
|
|
|
12247
12379
|
return Object.fromEntries(this.entries);
|
|
12248
12380
|
}
|
|
12249
12381
|
|
|
12382
|
+
/** Dump state entries to JSON string (format compatible with stf vectors). */
|
|
12383
|
+
toString() {
|
|
12384
|
+
return JSON.stringify(
|
|
12385
|
+
Array.from(this.entries.entries()).map(([key, value]) => ({
|
|
12386
|
+
key,
|
|
12387
|
+
value,
|
|
12388
|
+
})),
|
|
12389
|
+
null,
|
|
12390
|
+
2,
|
|
12391
|
+
);
|
|
12392
|
+
}
|
|
12393
|
+
|
|
12250
12394
|
[Symbol.iterator]() {
|
|
12251
12395
|
return this.entries[Symbol.iterator]();
|
|
12252
12396
|
}
|
|
@@ -14322,48 +14466,133 @@ declare class PendingTransfer {
|
|
|
14322
14466
|
}
|
|
14323
14467
|
}
|
|
14324
14468
|
|
|
14325
|
-
/** Gas measuring type. Can be either U64 or U32 for performance reasons. */
|
|
14326
|
-
type Gas = BigGas | SmallGas;
|
|
14327
14469
|
/** A U64 version of `Gas`. */
|
|
14328
14470
|
type BigGas = Opaque<U64, "BigGas[U64]">;
|
|
14329
14471
|
/** A U32 version of `Gas`. */
|
|
14330
14472
|
type SmallGas = Opaque<U32, "SmallGas[U32]">;
|
|
14331
|
-
|
|
14332
|
-
|
|
14333
|
-
declare const tryAsSmallGas = (v: number): SmallGas => asOpaqueType(tryAsU32(v));
|
|
14334
|
-
|
|
14335
|
-
/** Attempt to convert given number into U64 gas representation. */
|
|
14336
|
-
declare const tryAsBigGas = (v: number | bigint): BigGas => asOpaqueType(tryAsU64(v));
|
|
14337
|
-
|
|
14338
|
-
/** Attempt to convert given number into gas. */
|
|
14339
|
-
declare const tryAsGas = (v: number | bigint): Gas =>
|
|
14340
|
-
typeof v === "number" && v < 2 ** 32 ? tryAsSmallGas(v) : tryAsBigGas(v);
|
|
14341
|
-
|
|
14342
|
-
/** Create a new gas counter instance depending on the gas value. */
|
|
14343
|
-
declare function gasCounter(gas: Gas): GasCounter {
|
|
14344
|
-
return new GasCounterU64(tryAsU64(gas));
|
|
14345
|
-
}
|
|
14473
|
+
/** Gas measuring type. Can be either U64 or U32 for performance reasons. */
|
|
14474
|
+
type Gas = BigGas | SmallGas;
|
|
14346
14475
|
|
|
14347
14476
|
/** An abstraction over gas counter.
|
|
14348
14477
|
*
|
|
14349
14478
|
* It can be optimized to use numbers instead of bigint in case of small gas.
|
|
14350
14479
|
*/
|
|
14351
|
-
interface
|
|
14480
|
+
interface IGasCounter {
|
|
14481
|
+
/**
|
|
14482
|
+
* Set during initialization of GasCounter.
|
|
14483
|
+
*
|
|
14484
|
+
* NOTE: Needed to calculate `used()` gas.
|
|
14485
|
+
*/
|
|
14486
|
+
initialGas: Gas;
|
|
14487
|
+
|
|
14352
14488
|
/** Return remaining gas. */
|
|
14353
14489
|
get(): Gas;
|
|
14354
14490
|
|
|
14355
|
-
/**
|
|
14491
|
+
/**
|
|
14492
|
+
* Overwrite remaining gas.
|
|
14493
|
+
*
|
|
14494
|
+
* NOTE: Could cause `used()` gas calculation to be incorrect.
|
|
14495
|
+
*
|
|
14496
|
+
* @see
|
|
14497
|
+
* Prefer sub method instead.
|
|
14498
|
+
*/
|
|
14356
14499
|
set(g: Gas): void;
|
|
14357
14500
|
|
|
14358
14501
|
/** Returns true if there was an underflow. */
|
|
14359
14502
|
sub(g: Gas): boolean;
|
|
14503
|
+
|
|
14504
|
+
/**
|
|
14505
|
+
* Calculates used gas since creation of GasCounter.
|
|
14506
|
+
*
|
|
14507
|
+
* The interface does not handle negative or more than `initialGas` values.
|
|
14508
|
+
*
|
|
14509
|
+
* NOTE: We can use at most `initialGas` and as little as `0`.
|
|
14510
|
+
*/
|
|
14511
|
+
used(): Gas;
|
|
14512
|
+
}
|
|
14513
|
+
|
|
14514
|
+
type PageFault$1 = {
|
|
14515
|
+
address: U32;
|
|
14516
|
+
};
|
|
14517
|
+
|
|
14518
|
+
/** Allows store and read segments of memory. */
|
|
14519
|
+
interface IMemory {
|
|
14520
|
+
/** Store bytes into memory at given address. */
|
|
14521
|
+
store(address: U32, bytes: Uint8Array): Result$2<OK, PageFault$1>;
|
|
14522
|
+
|
|
14523
|
+
/** Load bytes from memory from given address into given buffer. */
|
|
14524
|
+
read(address: U32, result: Uint8Array): Result$2<OK, PageFault$1>;
|
|
14360
14525
|
}
|
|
14361
14526
|
|
|
14362
14527
|
declare const NO_OF_REGISTERS$1 = 13;
|
|
14363
14528
|
|
|
14529
|
+
/** Allow to set and get all registers encoded into little-endian bytes. */
|
|
14530
|
+
interface IRegisters {
|
|
14531
|
+
/**
|
|
14532
|
+
* Get all registers encoded into little-endian bytes.
|
|
14533
|
+
*
|
|
14534
|
+
* NOTE: Total length of bytes must be NO_OF_REGISTERS * REGISTER_BYTE_SIZE.
|
|
14535
|
+
*/
|
|
14536
|
+
getAllEncoded(): Uint8Array;
|
|
14537
|
+
/**
|
|
14538
|
+
* Set all registers from little-endian encoded bytes.
|
|
14539
|
+
*
|
|
14540
|
+
* NOTE: Total length of bytes must be NO_OF_REGISTERS * REGISTER_BYTE_SIZE.
|
|
14541
|
+
*/
|
|
14542
|
+
setAllEncoded(bytes: Uint8Array): void;
|
|
14543
|
+
}
|
|
14544
|
+
|
|
14545
|
+
/**
|
|
14546
|
+
* Result codes for the PVM execution.
|
|
14547
|
+
*
|
|
14548
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/2e43002e4300?v=0.7.2
|
|
14549
|
+
*/
|
|
14550
|
+
declare enum Status {
|
|
14551
|
+
/** Continue */
|
|
14552
|
+
OK = 255,
|
|
14553
|
+
/** Finished */
|
|
14554
|
+
HALT = 0,
|
|
14555
|
+
/** Panic */
|
|
14556
|
+
PANIC = 1,
|
|
14557
|
+
/** Page-fault */
|
|
14558
|
+
FAULT = 2,
|
|
14559
|
+
/** Host-call */
|
|
14560
|
+
HOST = 3,
|
|
14561
|
+
/** Out of gas */
|
|
14562
|
+
OOG = 4,
|
|
14563
|
+
}
|
|
14564
|
+
|
|
14565
|
+
interface IPvmInterpreter {
|
|
14566
|
+
/** Manipulate gas. */
|
|
14567
|
+
readonly gas: IGasCounter;
|
|
14568
|
+
|
|
14569
|
+
/** Manipulate registers. */
|
|
14570
|
+
readonly registers: IRegisters;
|
|
14571
|
+
|
|
14572
|
+
/** Manipulate memory. */
|
|
14573
|
+
readonly memory: IMemory;
|
|
14574
|
+
|
|
14575
|
+
/** Prepare SPI program to be executed. */
|
|
14576
|
+
resetJam(program: Uint8Array, args: Uint8Array, pc: number, gas: Gas): void;
|
|
14577
|
+
|
|
14578
|
+
/** Execute loaded program. */
|
|
14579
|
+
runProgram(): void;
|
|
14580
|
+
|
|
14581
|
+
/** Get current Status. */
|
|
14582
|
+
getStatus(): Status;
|
|
14583
|
+
|
|
14584
|
+
/** Get current Program Counter. */
|
|
14585
|
+
getPC(): number;
|
|
14586
|
+
|
|
14587
|
+
/** Get exit args. Needed in case of HOST or FAULT. */
|
|
14588
|
+
getExitParam(): U32 | null;
|
|
14589
|
+
}
|
|
14590
|
+
|
|
14591
|
+
// x << 3 === x * 8
|
|
14592
|
+
|
|
14364
14593
|
type RegisterIndex = Opaque<number, "register index">;
|
|
14365
14594
|
|
|
14366
|
-
declare class Registers {
|
|
14595
|
+
declare class Registers implements IRegisters {
|
|
14367
14596
|
private asSigned: BigInt64Array;
|
|
14368
14597
|
private asUnsigned: BigUint64Array;
|
|
14369
14598
|
|
|
@@ -14373,6 +14602,15 @@ declare class Registers {
|
|
|
14373
14602
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14374
14603
|
}
|
|
14375
14604
|
|
|
14605
|
+
getAllEncoded(): Uint8Array {
|
|
14606
|
+
return this.bytes;
|
|
14607
|
+
}
|
|
14608
|
+
|
|
14609
|
+
setAllEncoded(bytes: Uint8Array): void {
|
|
14610
|
+
check`${bytes.length === this.bytes.length} Incorrect size of input registers. Got: ${bytes.length}, need: ${this.bytes.length}`;
|
|
14611
|
+
this.bytes.set(bytes, 0);
|
|
14612
|
+
}
|
|
14613
|
+
|
|
14376
14614
|
static fromBytes(bytes: Uint8Array) {
|
|
14377
14615
|
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14378
14616
|
return new Registers(bytes);
|
|
@@ -14383,10 +14621,6 @@ declare class Registers {
|
|
|
14383
14621
|
return this.bytes.subarray(offset, offset + len);
|
|
14384
14622
|
}
|
|
14385
14623
|
|
|
14386
|
-
getAllBytesAsLittleEndian() {
|
|
14387
|
-
return this.bytes;
|
|
14388
|
-
}
|
|
14389
|
-
|
|
14390
14624
|
copyFrom(regs: Registers | BigUint64Array) {
|
|
14391
14625
|
const array = regs instanceof BigUint64Array ? regs : regs.asUnsigned;
|
|
14392
14626
|
this.asUnsigned.set(array);
|
|
@@ -14435,1493 +14669,1856 @@ declare class Registers {
|
|
|
14435
14669
|
}
|
|
14436
14670
|
}
|
|
14437
14671
|
|
|
14438
|
-
|
|
14439
|
-
|
|
14440
|
-
|
|
14441
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/237201239801
|
|
14442
|
-
*/
|
|
14443
|
-
declare class Mask {
|
|
14672
|
+
declare class HostCallMemory {
|
|
14673
|
+
constructor(private readonly memory: IMemory) {}
|
|
14674
|
+
|
|
14444
14675
|
/**
|
|
14445
|
-
*
|
|
14446
|
-
* In case the value is non-zero it signifies the offset to the index with next instruction.
|
|
14676
|
+
* Save some bytes into memory under given address.
|
|
14447
14677
|
*
|
|
14448
|
-
*
|
|
14449
|
-
*
|
|
14450
|
-
* 0..1..2..3..4..5..6..7..8..9 # Indices
|
|
14451
|
-
* 0..2..1..0..1..0..3..2..1..0 # lookupTable forward values
|
|
14452
|
-
* ```
|
|
14453
|
-
* There are instructions at indices `0, 3, 5, 9`.
|
|
14678
|
+
* NOTE: Given address is U64 (pure register value),
|
|
14679
|
+
* but we use only lower 32-bits.
|
|
14454
14680
|
*/
|
|
14455
|
-
|
|
14456
|
-
|
|
14457
|
-
|
|
14458
|
-
|
|
14459
|
-
}
|
|
14460
|
-
|
|
14461
|
-
isInstruction(index: number) {
|
|
14462
|
-
return this.lookupTableForward[index] === 0;
|
|
14463
|
-
}
|
|
14681
|
+
storeFrom(regAddress: U64, bytes: Uint8Array): Result$2<OK, PageFault$1> {
|
|
14682
|
+
if (bytes.length === 0) {
|
|
14683
|
+
return Result.ok(OK);
|
|
14684
|
+
}
|
|
14464
14685
|
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
|
|
14686
|
+
// NOTE: We always take lower 32 bits from register value.
|
|
14687
|
+
//
|
|
14688
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
14689
|
+
const address = tryAsU32(Number(regAddress & 0xffff_ffffn));
|
|
14690
|
+
return this.memory.store(address, bytes);
|
|
14468
14691
|
}
|
|
14469
14692
|
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
table[i] = lastInstructionOffset;
|
|
14693
|
+
/**
|
|
14694
|
+
* Read some bytes from memory under given address.
|
|
14695
|
+
*
|
|
14696
|
+
* NOTE: Given address is U64 (pure register value),
|
|
14697
|
+
* but we use only lower 32-bits.
|
|
14698
|
+
*/
|
|
14699
|
+
loadInto(output: Uint8Array, regAddress: U64): Result$2<OK, PageFault$1> {
|
|
14700
|
+
if (output.length === 0) {
|
|
14701
|
+
return Result.ok(OK);
|
|
14480
14702
|
}
|
|
14481
|
-
return table;
|
|
14482
|
-
}
|
|
14483
14703
|
|
|
14484
|
-
|
|
14485
|
-
|
|
14704
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
14705
|
+
//
|
|
14706
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
14707
|
+
const address = tryAsU32(Number(regAddress & 0xffff_ffffn));
|
|
14708
|
+
return this.memory.read(address, output);
|
|
14486
14709
|
}
|
|
14487
14710
|
}
|
|
14488
14711
|
|
|
14489
|
-
declare
|
|
14490
|
-
|
|
14491
|
-
ONE_IMMEDIATE = 1,
|
|
14492
|
-
TWO_IMMEDIATES = 2,
|
|
14493
|
-
ONE_OFFSET = 3,
|
|
14494
|
-
ONE_REGISTER_ONE_IMMEDIATE = 4,
|
|
14495
|
-
ONE_REGISTER_TWO_IMMEDIATES = 5,
|
|
14496
|
-
ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET = 6,
|
|
14497
|
-
TWO_REGISTERS = 7,
|
|
14498
|
-
TWO_REGISTERS_ONE_IMMEDIATE = 8,
|
|
14499
|
-
TWO_REGISTERS_ONE_OFFSET = 9,
|
|
14500
|
-
TWO_REGISTERS_TWO_IMMEDIATES = 10,
|
|
14501
|
-
THREE_REGISTERS = 11,
|
|
14502
|
-
ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE = 12,
|
|
14503
|
-
}
|
|
14504
|
-
|
|
14505
|
-
declare class ExtendedWitdthImmediateDecoder {
|
|
14506
|
-
private unsignedImmediate: BigUint64Array;
|
|
14507
|
-
private bytes: Uint8Array;
|
|
14712
|
+
declare class HostCallRegisters {
|
|
14713
|
+
private readonly registers: DataView;
|
|
14508
14714
|
|
|
14509
|
-
constructor() {
|
|
14510
|
-
|
|
14511
|
-
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
14512
|
-
this.bytes = new Uint8Array(buffer);
|
|
14715
|
+
constructor(private readonly bytes: Uint8Array) {
|
|
14716
|
+
this.registers = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
14513
14717
|
}
|
|
14514
14718
|
|
|
14515
|
-
|
|
14516
|
-
|
|
14517
|
-
|
|
14518
|
-
this.bytes[i] = bytes[i];
|
|
14519
|
-
}
|
|
14520
|
-
|
|
14521
|
-
for (; i < IMMEDIATE_SIZE; i++) {
|
|
14522
|
-
this.bytes[i] = 0;
|
|
14523
|
-
}
|
|
14719
|
+
/** Get U64 register value. */
|
|
14720
|
+
get(registerIndex: number): U64 {
|
|
14721
|
+
return tryAsU64(this.registers.getBigUint64(registerIndex * REGISTER_BYTE_SIZE, true));
|
|
14524
14722
|
}
|
|
14525
14723
|
|
|
14526
|
-
|
|
14527
|
-
|
|
14724
|
+
/** Set U64 register value. */
|
|
14725
|
+
set(registerIndex: number, value: U64) {
|
|
14726
|
+
this.registers.setBigUint64(registerIndex * REGISTER_BYTE_SIZE, value, true);
|
|
14528
14727
|
}
|
|
14529
14728
|
|
|
14530
|
-
|
|
14531
|
-
|
|
14729
|
+
/** Get all registers encoded into little-endian bytes. */
|
|
14730
|
+
getEncoded(): Uint8Array {
|
|
14731
|
+
return this.bytes;
|
|
14532
14732
|
}
|
|
14533
14733
|
}
|
|
14534
14734
|
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
private i64: BigInt64Array;
|
|
14540
|
-
private view: DataView;
|
|
14541
|
-
private bytes: Uint8Array;
|
|
14735
|
+
/** Strictly-typed host call index. */
|
|
14736
|
+
type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
14737
|
+
/** Attempt to convert a number into `HostCallIndex`. */
|
|
14738
|
+
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
14542
14739
|
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
setBytes(bytes: Uint8Array) {
|
|
14554
|
-
const n = bytes.length;
|
|
14555
|
-
const msb = n > 0 ? bytes[n - 1] & 0x80 : 0;
|
|
14556
|
-
const noOfBytes = Math.min(n, BUFFER_SIZE);
|
|
14557
|
-
const prefix = msb !== 0 ? 0xff : 0x00;
|
|
14740
|
+
/**
|
|
14741
|
+
* Host-call exit reason.
|
|
14742
|
+
*
|
|
14743
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
14744
|
+
*/
|
|
14745
|
+
declare enum PvmExecution {
|
|
14746
|
+
Halt = 0,
|
|
14747
|
+
Panic = 1,
|
|
14748
|
+
OOG = 2, // out-of-gas
|
|
14749
|
+
}
|
|
14558
14750
|
|
|
14559
|
-
|
|
14560
|
-
|
|
14561
|
-
|
|
14751
|
+
/** A utility function to easily trace a bunch of registers. */
|
|
14752
|
+
declare function traceRegisters(...regs: number[]) {
|
|
14753
|
+
return regs.map(tryAsRegisterIndex);
|
|
14754
|
+
}
|
|
14562
14755
|
|
|
14563
|
-
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14756
|
+
/** An interface for a host call implementation */
|
|
14757
|
+
interface HostCallHandler {
|
|
14758
|
+
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
14759
|
+
readonly index: HostCallIndex;
|
|
14567
14760
|
|
|
14568
14761
|
/**
|
|
14569
|
-
*
|
|
14762
|
+
* The gas cost of invocation of that host call.
|
|
14763
|
+
*
|
|
14764
|
+
* NOTE: `((reg: HostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
14570
14765
|
*/
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14766
|
+
readonly basicGasCost: SmallGas | ((reg: HostCallRegisters) => Gas);
|
|
14767
|
+
|
|
14768
|
+
/** Currently executing service id. */
|
|
14769
|
+
readonly currentServiceId: U32;
|
|
14770
|
+
|
|
14771
|
+
/** Input&Output registers that we should add to tracing log. */
|
|
14772
|
+
readonly tracedRegisters: RegisterIndex[];
|
|
14574
14773
|
|
|
14575
14774
|
/**
|
|
14576
|
-
*
|
|
14775
|
+
* Actually execute the host call.
|
|
14776
|
+
*
|
|
14777
|
+
* NOTE the call is ALLOWED and expected to modify registers and memory.
|
|
14577
14778
|
*/
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
}
|
|
14779
|
+
execute(gas: IGasCounter, regs: HostCallRegisters, memory: HostCallMemory): Promise<undefined | PvmExecution>;
|
|
14780
|
+
}
|
|
14581
14781
|
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14782
|
+
/** Container for all available host calls. */
|
|
14783
|
+
declare class HostCallsManager {
|
|
14784
|
+
private readonly hostCalls = new Map<HostCallIndex, HostCallHandler>();
|
|
14785
|
+
private readonly missing;
|
|
14585
14786
|
|
|
14586
|
-
|
|
14587
|
-
|
|
14787
|
+
constructor({
|
|
14788
|
+
missing,
|
|
14789
|
+
handlers = [],
|
|
14790
|
+
}: {
|
|
14791
|
+
missing: HostCallHandler;
|
|
14792
|
+
handlers?: HostCallHandler[];
|
|
14793
|
+
}) {
|
|
14794
|
+
this.missing = missing;
|
|
14795
|
+
|
|
14796
|
+
for (const handler of handlers) {
|
|
14797
|
+
check`${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
14798
|
+
this.hostCalls.set(handler.index, handler);
|
|
14799
|
+
}
|
|
14588
14800
|
}
|
|
14589
14801
|
|
|
14590
|
-
|
|
14591
|
-
|
|
14802
|
+
/** Get a host call by index. */
|
|
14803
|
+
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
14804
|
+
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
14592
14805
|
}
|
|
14593
14806
|
|
|
14594
|
-
|
|
14595
|
-
|
|
14807
|
+
traceHostCall(
|
|
14808
|
+
context: string,
|
|
14809
|
+
hostCallIndex: HostCallIndex,
|
|
14810
|
+
hostCallHandler: HostCallHandler,
|
|
14811
|
+
registers: HostCallRegisters,
|
|
14812
|
+
gas: Gas,
|
|
14813
|
+
) {
|
|
14814
|
+
const { currentServiceId } = hostCallHandler;
|
|
14815
|
+
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
14816
|
+
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
14817
|
+
const registerValues = hostCallHandler.tracedRegisters
|
|
14818
|
+
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
14819
|
+
.filter((v) => v[1] !== 0n)
|
|
14820
|
+
.map(([idx, value]) => {
|
|
14821
|
+
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
14822
|
+
})
|
|
14823
|
+
.join(", ");
|
|
14824
|
+
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
14596
14825
|
}
|
|
14826
|
+
}
|
|
14597
14827
|
|
|
14598
|
-
|
|
14599
|
-
|
|
14828
|
+
/** Create a new gas counter instance depending on the gas value. */
|
|
14829
|
+
declare function gasCounter(gas: Gas): IGasCounter {
|
|
14830
|
+
return new GasCounterU64(tryAsU64(gas));
|
|
14831
|
+
}
|
|
14832
|
+
|
|
14833
|
+
type MemoryIndex = Opaque<number, "memory index">;
|
|
14834
|
+
|
|
14835
|
+
declare const tryAsMemoryIndex = (index: number): MemoryIndex => {
|
|
14836
|
+
check`${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
14837
|
+
return asOpaqueType(index);
|
|
14838
|
+
};
|
|
14839
|
+
|
|
14840
|
+
type SbrkIndex = Opaque<number, "sbrk index">;
|
|
14841
|
+
|
|
14842
|
+
declare const tryAsSbrkIndex = (index: number): SbrkIndex => {
|
|
14843
|
+
check`${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
14844
|
+
return asOpaqueType(index);
|
|
14845
|
+
};
|
|
14846
|
+
|
|
14847
|
+
type PageIndex = Opaque<number, "memory page index">;
|
|
14848
|
+
type PageNumber = Opaque<number, "memory page number">;
|
|
14849
|
+
|
|
14850
|
+
declare class PageFault implements PageFault$1 {
|
|
14851
|
+
private constructor(
|
|
14852
|
+
public address: U32,
|
|
14853
|
+
public isAccessFault = true,
|
|
14854
|
+
) {}
|
|
14855
|
+
|
|
14856
|
+
static fromPageNumber(maybePageNumber: number, isAccessFault = false) {
|
|
14857
|
+
const pageNumber = tryAsPageNumber(maybePageNumber);
|
|
14858
|
+
const startPageIndex = getStartPageIndexFromPageNumber(pageNumber);
|
|
14859
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
14600
14860
|
}
|
|
14601
14861
|
|
|
14602
|
-
|
|
14603
|
-
|
|
14862
|
+
static fromMemoryIndex(maybeMemoryIndex: number, isAccessFault = false) {
|
|
14863
|
+
const memoryIndex = tryAsMemoryIndex(maybeMemoryIndex % MEMORY_SIZE);
|
|
14864
|
+
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
14865
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
14604
14866
|
}
|
|
14605
14867
|
}
|
|
14606
14868
|
|
|
14607
|
-
|
|
14608
|
-
|
|
14869
|
+
/**
|
|
14870
|
+
* A representation of open-ended range of consecutive indices in memory,
|
|
14871
|
+
* possibly empty or wrapping around.
|
|
14872
|
+
*
|
|
14873
|
+
* `[start, start + length)`
|
|
14874
|
+
*/
|
|
14875
|
+
declare class MemoryRange {
|
|
14876
|
+
/**
|
|
14877
|
+
* Exclusive end index of the range.
|
|
14878
|
+
*
|
|
14879
|
+
* NOTE: The index may be wrapped around and smaller than `start`!
|
|
14880
|
+
*/
|
|
14881
|
+
public readonly end: MemoryIndex;
|
|
14882
|
+
/**
|
|
14883
|
+
* Inclusive last index of the range (present unless the range is empty).
|
|
14884
|
+
*
|
|
14885
|
+
* NOTE: the index may be wrapped around and smaller than `start`!
|
|
14886
|
+
*/
|
|
14887
|
+
public readonly lastIndex: MemoryIndex | null = null;
|
|
14609
14888
|
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
|
|
14889
|
+
private constructor(
|
|
14890
|
+
public readonly start: MemoryIndex,
|
|
14891
|
+
public readonly length: number,
|
|
14892
|
+
) {
|
|
14893
|
+
this.end = tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
14613
14894
|
|
|
14614
|
-
|
|
14615
|
-
|
|
14895
|
+
if (length > 0) {
|
|
14896
|
+
this.lastIndex = tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
14897
|
+
}
|
|
14616
14898
|
}
|
|
14617
14899
|
|
|
14618
|
-
|
|
14619
|
-
|
|
14900
|
+
/** Creates a memory range from given starting point and length */
|
|
14901
|
+
static fromStartAndLength(start: MemoryIndex, length: number) {
|
|
14902
|
+
if (!Number.isInteger(length) || length < 0 || length > MEMORY_SIZE) {
|
|
14903
|
+
throw new TypeError(`length must be a non-negative integer and less than ${MEMORY_SIZE}, got ${length}`);
|
|
14904
|
+
}
|
|
14905
|
+
|
|
14906
|
+
return new MemoryRange(start, length);
|
|
14620
14907
|
}
|
|
14621
14908
|
|
|
14622
|
-
|
|
14623
|
-
|
|
14909
|
+
/** Checks if a range is empty (`length === 0`) */
|
|
14910
|
+
isEmpty() {
|
|
14911
|
+
return this.length === 0;
|
|
14624
14912
|
}
|
|
14625
14913
|
|
|
14626
|
-
|
|
14627
|
-
|
|
14914
|
+
/** Returns true if the range is wrapped (`start` >= `end`) and is not empty */
|
|
14915
|
+
isWrapped() {
|
|
14916
|
+
return this.start >= this.end && !this.isEmpty();
|
|
14628
14917
|
}
|
|
14629
14918
|
|
|
14630
|
-
|
|
14631
|
-
|
|
14919
|
+
/** Checks if given memory address is within the range */
|
|
14920
|
+
isInRange(address: MemoryIndex) {
|
|
14921
|
+
if (this.isWrapped()) {
|
|
14922
|
+
return address >= this.start || address < this.end;
|
|
14923
|
+
}
|
|
14924
|
+
|
|
14925
|
+
return address >= this.start && address < this.end;
|
|
14632
14926
|
}
|
|
14633
14927
|
|
|
14634
|
-
|
|
14635
|
-
|
|
14928
|
+
/** Checks if this range overlaps with another range */
|
|
14929
|
+
overlapsWith(other: MemoryRange) {
|
|
14930
|
+
if (this.lastIndex === null || other.lastIndex === null) {
|
|
14931
|
+
return false;
|
|
14932
|
+
}
|
|
14933
|
+
|
|
14934
|
+
return (
|
|
14935
|
+
this.isInRange(other.start) ||
|
|
14936
|
+
this.isInRange(other.lastIndex) ||
|
|
14937
|
+
other.isInRange(this.start) ||
|
|
14938
|
+
other.isInRange(this.lastIndex)
|
|
14939
|
+
);
|
|
14636
14940
|
}
|
|
14637
14941
|
}
|
|
14638
14942
|
|
|
14639
|
-
|
|
14640
|
-
|
|
14641
|
-
noOfBytesToSkip: number;
|
|
14642
|
-
};
|
|
14943
|
+
declare abstract class MemoryPage {
|
|
14944
|
+
public start: MemoryIndex;
|
|
14643
14945
|
|
|
14644
|
-
|
|
14645
|
-
|
|
14646
|
-
|
|
14647
|
-
/** V_X */
|
|
14648
|
-
immediateDecoder: ImmediateDecoder;
|
|
14649
|
-
};
|
|
14946
|
+
constructor(pageNumber: PageNumber) {
|
|
14947
|
+
this.start = getStartPageIndexFromPageNumber(pageNumber);
|
|
14948
|
+
}
|
|
14650
14949
|
|
|
14651
|
-
|
|
14652
|
-
|
|
14653
|
-
noOfBytesToSkip: number;
|
|
14654
|
-
/** W_A */
|
|
14655
|
-
firstRegisterIndex: number;
|
|
14656
|
-
/** W_B */
|
|
14657
|
-
secondRegisterIndex: number;
|
|
14658
|
-
/** W_D */
|
|
14659
|
-
thirdRegisterIndex: number;
|
|
14660
|
-
};
|
|
14950
|
+
/** Returns `true` if the page is writeable. */
|
|
14951
|
+
abstract isWriteable(): boolean;
|
|
14661
14952
|
|
|
14662
|
-
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
|
|
14667
|
-
|
|
14668
|
-
|
|
14669
|
-
|
|
14953
|
+
/**
|
|
14954
|
+
* Load exactly `length` bytes from memory page, starting at index `address`
|
|
14955
|
+
* into the `res` array.
|
|
14956
|
+
*
|
|
14957
|
+
* Note that the `res` might be bigger than the number of bytes length, but cannot be smaller.
|
|
14958
|
+
*
|
|
14959
|
+
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
14960
|
+
* NOTE That the `result` might be partially modified in case `PageFault` occurs!
|
|
14961
|
+
*/
|
|
14962
|
+
abstract loadInto(res: Uint8Array, address: PageIndex, length: number): Result$2<OK, PageFault>;
|
|
14670
14963
|
|
|
14671
|
-
|
|
14672
|
-
|
|
14673
|
-
|
|
14674
|
-
|
|
14675
|
-
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
type OneRegisterOneImmediateArgs = {
|
|
14683
|
-
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
14684
|
-
noOfBytesToSkip: number;
|
|
14685
|
-
/** W_A */
|
|
14686
|
-
registerIndex: number;
|
|
14687
|
-
/** V_X */
|
|
14688
|
-
immediateDecoder: ImmediateDecoder;
|
|
14689
|
-
};
|
|
14964
|
+
/**
|
|
14965
|
+
* Copy all bytes from the `data` into the page at index `address`.
|
|
14966
|
+
*
|
|
14967
|
+
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
14968
|
+
*/
|
|
14969
|
+
abstract storeFrom(address: PageIndex, data: Uint8Array): Result$2<OK, PageFault>;
|
|
14970
|
+
/**
|
|
14971
|
+
* Get dump of the entire page. Should only be used for the debugger-adapter because it
|
|
14972
|
+
* might be inefficient.
|
|
14973
|
+
*/
|
|
14974
|
+
abstract getPageDump(): Uint8Array;
|
|
14690
14975
|
|
|
14691
|
-
|
|
14692
|
-
|
|
14693
|
-
noOfBytesToSkip: number;
|
|
14694
|
-
/** W_A */
|
|
14695
|
-
registerIndex: number;
|
|
14696
|
-
/** V_X */
|
|
14697
|
-
immediateDecoder: ExtendedWitdthImmediateDecoder;
|
|
14698
|
-
};
|
|
14976
|
+
abstract setData(pageIndex: PageIndex, data: Uint8Array): void;
|
|
14977
|
+
}
|
|
14699
14978
|
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
14707
|
-
|
|
14708
|
-
|
|
14709
|
-
|
|
14710
|
-
|
|
14711
|
-
|
|
14979
|
+
/**
|
|
14980
|
+
* I had to extend ArrayBuffer type to use resizable ArrayBuffer.
|
|
14981
|
+
* We will be able to remove it when this is merged: https://github.com/microsoft/TypeScript/pull/58573
|
|
14982
|
+
* And then a new version of TypeScript is released.
|
|
14983
|
+
*/
|
|
14984
|
+
declare global {
|
|
14985
|
+
interface ArrayBufferConstructor {
|
|
14986
|
+
new (length: number, options?: {
|
|
14987
|
+
maxByteLength: number;
|
|
14988
|
+
}): ArrayBuffer;
|
|
14989
|
+
}
|
|
14990
|
+
interface ArrayBuffer {
|
|
14991
|
+
resize(length: number): void;
|
|
14992
|
+
}
|
|
14993
|
+
}
|
|
14712
14994
|
|
|
14713
|
-
type
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
firstImmediateDecoder: ImmediateDecoder;
|
|
14718
|
-
/** V_Y */
|
|
14719
|
-
secondImmediateDecoder: ImmediateDecoder;
|
|
14995
|
+
type InitialMemoryState = {
|
|
14996
|
+
memory: Map<PageNumber, MemoryPage>;
|
|
14997
|
+
sbrkIndex: SbrkIndex;
|
|
14998
|
+
endHeapIndex: SbrkIndex;
|
|
14720
14999
|
};
|
|
14721
15000
|
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
firstRegisterIndex: number;
|
|
14727
|
-
/** W_B */
|
|
14728
|
-
secondRegisterIndex: number;
|
|
14729
|
-
nextPc: number;
|
|
14730
|
-
};
|
|
15001
|
+
declare enum AccessType {
|
|
15002
|
+
READ = 0,
|
|
15003
|
+
WRITE = 1,
|
|
15004
|
+
}
|
|
14731
15005
|
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
};
|
|
15006
|
+
declare class Memory implements IMemory {
|
|
15007
|
+
static fromInitialMemory(initialMemoryState: InitialMemoryState) {
|
|
15008
|
+
return new Memory(
|
|
15009
|
+
initialMemoryState?.sbrkIndex,
|
|
15010
|
+
initialMemoryState?.sbrkIndex,
|
|
15011
|
+
initialMemoryState?.endHeapIndex,
|
|
15012
|
+
initialMemoryState?.memory,
|
|
15013
|
+
);
|
|
15014
|
+
}
|
|
14742
15015
|
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
firstImmediateDecoder: ImmediateDecoder;
|
|
14750
|
-
/** V_Y */
|
|
14751
|
-
secondImmediateDecoder: ImmediateDecoder;
|
|
14752
|
-
};
|
|
15016
|
+
constructor(
|
|
15017
|
+
private sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
15018
|
+
private virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
15019
|
+
private endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX),
|
|
15020
|
+
private memory = new Map<PageNumber, MemoryPage>(),
|
|
15021
|
+
) {}
|
|
14753
15022
|
|
|
14754
|
-
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
/** V_X */
|
|
14758
|
-
nextPc: number;
|
|
14759
|
-
};
|
|
15023
|
+
store(address: U32, bytes: Uint8Array): Result$2<OK, PageFault$1> {
|
|
15024
|
+
return this.storeFrom(tryAsMemoryIndex(address), bytes);
|
|
15025
|
+
}
|
|
14760
15026
|
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
| TwoRegistersArgs
|
|
14765
|
-
| ThreeRegistersArgs
|
|
14766
|
-
| TwoRegistersOneImmediateArgs
|
|
14767
|
-
| TwoRegistersTwoImmediatesArgs
|
|
14768
|
-
| OneRegisterOneImmediateOneOffsetArgs
|
|
14769
|
-
| TwoRegistersOneOffsetArgs
|
|
14770
|
-
| OneRegisterOneImmediateArgs
|
|
14771
|
-
| OneOffsetArgs
|
|
14772
|
-
| TwoImmediatesArgs
|
|
14773
|
-
| OneRegisterTwoImmediatesArgs
|
|
14774
|
-
| OneRegisterOneExtendedWidthImmediateArgs;
|
|
15027
|
+
read(address: U32, output: Uint8Array): Result$2<OK, PageFault$1> {
|
|
15028
|
+
return this.loadInto(output, tryAsMemoryIndex(address));
|
|
15029
|
+
}
|
|
14775
15030
|
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
-
|
|
15031
|
+
reset() {
|
|
15032
|
+
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15033
|
+
this.virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15034
|
+
this.endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX);
|
|
15035
|
+
this.memory = new Map<PageNumber, MemoryPage>(); // TODO [MaSi]: We should keep allocated pages somewhere and reuse it when it is possible
|
|
15036
|
+
}
|
|
14781
15037
|
|
|
14782
|
-
|
|
14783
|
-
this.
|
|
14784
|
-
this.
|
|
15038
|
+
copyFrom(memory: Memory) {
|
|
15039
|
+
this.sbrkIndex = memory.sbrkIndex;
|
|
15040
|
+
this.virtualSbrkIndex = memory.virtualSbrkIndex;
|
|
15041
|
+
this.endHeapIndex = memory.endHeapIndex;
|
|
15042
|
+
this.memory = memory.memory;
|
|
14785
15043
|
}
|
|
14786
15044
|
|
|
14787
|
-
|
|
14788
|
-
|
|
14789
|
-
|
|
15045
|
+
storeFrom(address: MemoryIndex, bytes: Uint8Array): Result$2<OK, PageFault> {
|
|
15046
|
+
if (bytes.length === 0) {
|
|
15047
|
+
return Result.ok(OK);
|
|
15048
|
+
}
|
|
14790
15049
|
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
break;
|
|
15050
|
+
logger.insane`MEM[${address}] <- ${BytesBlob.blobFrom(bytes)}`;
|
|
15051
|
+
const pagesResult = this.getPages(address, bytes.length, AccessType.WRITE);
|
|
14794
15052
|
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
14798
|
-
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
14799
|
-
break;
|
|
14800
|
-
}
|
|
15053
|
+
if (pagesResult.isError) {
|
|
15054
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
15055
|
+
}
|
|
14801
15056
|
|
|
14802
|
-
|
|
14803
|
-
|
|
14804
|
-
|
|
14805
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14806
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14807
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14808
|
-
this.nibblesDecoder.setByte(secondByte);
|
|
14809
|
-
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14810
|
-
break;
|
|
14811
|
-
}
|
|
15057
|
+
const pages = pagesResult.ok;
|
|
15058
|
+
let currentPosition: number = address;
|
|
15059
|
+
let bytesLeft = bytes.length;
|
|
14812
15060
|
|
|
14813
|
-
|
|
14814
|
-
|
|
14815
|
-
|
|
14816
|
-
|
|
14817
|
-
|
|
15061
|
+
for (const page of pages) {
|
|
15062
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE);
|
|
15063
|
+
const bytesToWrite = Math.min(PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15064
|
+
const sourceStartIndex = currentPosition - address;
|
|
15065
|
+
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
14818
15066
|
|
|
14819
|
-
|
|
14820
|
-
const immediateStartIndex = pc + 2;
|
|
14821
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14822
|
-
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
14823
|
-
break;
|
|
14824
|
-
}
|
|
15067
|
+
page.storeFrom(pageStartIndex, source);
|
|
14825
15068
|
|
|
14826
|
-
|
|
14827
|
-
|
|
14828
|
-
|
|
14829
|
-
|
|
15069
|
+
currentPosition += bytesToWrite;
|
|
15070
|
+
bytesLeft -= bytesToWrite;
|
|
15071
|
+
}
|
|
15072
|
+
return Result.ok(OK);
|
|
15073
|
+
}
|
|
14830
15074
|
|
|
14831
|
-
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
15075
|
+
private getPages(startAddress: MemoryIndex, length: number, accessType: AccessType): Result$2<MemoryPage[], PageFault> {
|
|
15076
|
+
if (length === 0) {
|
|
15077
|
+
return Result.ok([]);
|
|
15078
|
+
}
|
|
14835
15079
|
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
15080
|
+
const memoryRange = MemoryRange.fromStartAndLength(startAddress, length);
|
|
15081
|
+
const pageRange = PageRange.fromMemoryRange(memoryRange);
|
|
15082
|
+
|
|
15083
|
+
const pages: MemoryPage[] = [];
|
|
15084
|
+
|
|
15085
|
+
for (const pageNumber of pageRange) {
|
|
15086
|
+
if (pageNumber < RESERVED_NUMBER_OF_PAGES) {
|
|
15087
|
+
return Result.error(
|
|
15088
|
+
PageFault.fromPageNumber(pageNumber, true),
|
|
15089
|
+
() => `Page fault: attempted to access reserved page ${pageNumber}`,
|
|
14839
15090
|
);
|
|
14840
|
-
|
|
14841
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14842
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15091
|
+
}
|
|
14843
15092
|
|
|
14844
|
-
|
|
14845
|
-
|
|
15093
|
+
const page = this.memory.get(pageNumber);
|
|
15094
|
+
|
|
15095
|
+
if (page === undefined) {
|
|
15096
|
+
return Result.error(PageFault.fromPageNumber(pageNumber), () => `Page fault: page ${pageNumber} not allocated`);
|
|
14846
15097
|
}
|
|
14847
15098
|
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
15099
|
+
if (accessType === AccessType.WRITE && !page.isWriteable()) {
|
|
15100
|
+
return Result.error(
|
|
15101
|
+
PageFault.fromPageNumber(pageNumber, true),
|
|
15102
|
+
() => `Page fault: attempted to write to read-only page ${pageNumber}`,
|
|
15103
|
+
);
|
|
15104
|
+
}
|
|
14853
15105
|
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14857
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15106
|
+
pages.push(page);
|
|
15107
|
+
}
|
|
14858
15108
|
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
15109
|
+
return Result.ok(pages);
|
|
15110
|
+
}
|
|
15111
|
+
/**
|
|
15112
|
+
* Read content of the memory at `[address, address + result.length)` and
|
|
15113
|
+
* write the result into the `result` buffer.
|
|
15114
|
+
*
|
|
15115
|
+
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
15116
|
+
*/
|
|
15117
|
+
loadInto(result: Uint8Array, startAddress: MemoryIndex): Result$2<OK, PageFault> {
|
|
15118
|
+
if (result.length === 0) {
|
|
15119
|
+
return Result.ok(OK);
|
|
15120
|
+
}
|
|
14862
15121
|
|
|
14863
|
-
|
|
14864
|
-
const firstByte = this.code[pc + 1];
|
|
14865
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14866
|
-
result.firstRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14867
|
-
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14868
|
-
break;
|
|
14869
|
-
}
|
|
15122
|
+
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
14870
15123
|
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14875
|
-
const offsetBytes = this.code.subarray(offsetStartIndex, offsetEndIndex);
|
|
14876
|
-
this.offsetDecoder.setBytes(offsetBytes);
|
|
14877
|
-
const offsetValue = this.offsetDecoder.getSigned();
|
|
14878
|
-
result.nextPc = pc + offsetValue;
|
|
14879
|
-
break;
|
|
14880
|
-
}
|
|
15124
|
+
if (pagesResult.isError) {
|
|
15125
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
15126
|
+
}
|
|
14881
15127
|
|
|
14882
|
-
|
|
14883
|
-
const firstByte = this.code[pc + 1];
|
|
14884
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14885
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15128
|
+
const pages = pagesResult.ok;
|
|
14886
15129
|
|
|
14887
|
-
|
|
14888
|
-
|
|
14889
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14890
|
-
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
14891
|
-
result.immediateDecoder.setBytes(immediateBytes);
|
|
14892
|
-
break;
|
|
14893
|
-
}
|
|
15130
|
+
let currentPosition: number = startAddress;
|
|
15131
|
+
let bytesLeft = result.length;
|
|
14894
15132
|
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14901
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14902
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15133
|
+
for (const page of pages) {
|
|
15134
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE);
|
|
15135
|
+
const bytesToRead = Math.min(PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15136
|
+
const destinationStartIndex = currentPosition - startAddress;
|
|
15137
|
+
const destination = result.subarray(destinationStartIndex);
|
|
14903
15138
|
|
|
14904
|
-
|
|
14905
|
-
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
14906
|
-
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
14907
|
-
);
|
|
14908
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14909
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14910
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14911
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14912
|
-
break;
|
|
14913
|
-
}
|
|
15139
|
+
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
14914
15140
|
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15141
|
+
currentPosition += bytesToRead;
|
|
15142
|
+
bytesLeft -= bytesToRead;
|
|
15143
|
+
}
|
|
14919
15144
|
|
|
14920
|
-
|
|
14921
|
-
|
|
14922
|
-
|
|
14923
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14924
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15145
|
+
logger.insane`MEM[${startAddress}] => ${BytesBlob.blobFrom(result)}`;
|
|
15146
|
+
return Result.ok(OK);
|
|
15147
|
+
}
|
|
14925
15148
|
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
);
|
|
14930
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14931
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14932
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14933
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14934
|
-
break;
|
|
14935
|
-
}
|
|
15149
|
+
sbrk(length: number): SbrkIndex {
|
|
15150
|
+
const currentSbrkIndex = this.sbrkIndex;
|
|
15151
|
+
const currentVirtualSbrkIndex = this.virtualSbrkIndex;
|
|
14936
15152
|
|
|
14937
|
-
|
|
14938
|
-
|
|
14939
|
-
|
|
14940
|
-
|
|
14941
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15153
|
+
// new sbrk index is bigger than 2 ** 32 or endHeapIndex
|
|
15154
|
+
if (MAX_MEMORY_INDEX < currentVirtualSbrkIndex + length || currentVirtualSbrkIndex + length > this.endHeapIndex) {
|
|
15155
|
+
throw new OutOfMemory();
|
|
15156
|
+
}
|
|
14942
15157
|
|
|
14943
|
-
|
|
14944
|
-
this.nibblesDecoder.setByte(secondByte);
|
|
14945
|
-
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
14946
|
-
const firstImmediateStartIndex = pc + 3;
|
|
14947
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14948
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14949
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15158
|
+
const newVirtualSbrkIndex = tryAsSbrkIndex(this.virtualSbrkIndex + length);
|
|
14950
15159
|
|
|
14951
|
-
|
|
14952
|
-
|
|
14953
|
-
|
|
14954
|
-
|
|
14955
|
-
|
|
14956
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14957
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14958
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14959
|
-
break;
|
|
14960
|
-
}
|
|
15160
|
+
// no alllocation needed
|
|
15161
|
+
if (newVirtualSbrkIndex <= currentSbrkIndex) {
|
|
15162
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
15163
|
+
return currentVirtualSbrkIndex;
|
|
15164
|
+
}
|
|
14961
15165
|
|
|
14962
|
-
|
|
14963
|
-
|
|
14964
|
-
|
|
14965
|
-
|
|
15166
|
+
// standard allocation using "Writeable" pages
|
|
15167
|
+
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize(newVirtualSbrkIndex));
|
|
15168
|
+
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
15169
|
+
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15170
|
+
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE;
|
|
15171
|
+
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
14966
15172
|
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
14970
|
-
result.immediateDecoder.setBytes(immediateBytes);
|
|
14971
|
-
break;
|
|
14972
|
-
}
|
|
15173
|
+
for (const pageNumber of rangeToAllocate) {
|
|
15174
|
+
const page = new WriteablePage(pageNumber);
|
|
15175
|
+
this.memory.set(pageNumber, page);
|
|
14973
15176
|
}
|
|
15177
|
+
|
|
15178
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
15179
|
+
this.sbrkIndex = newSbrkIndex;
|
|
15180
|
+
return currentVirtualSbrkIndex;
|
|
15181
|
+
}
|
|
15182
|
+
|
|
15183
|
+
getPageDump(pageNumber: PageNumber) {
|
|
15184
|
+
const page = this.memory.get(pageNumber);
|
|
15185
|
+
return page?.getPageDump() ?? null;
|
|
15186
|
+
}
|
|
15187
|
+
|
|
15188
|
+
getDirtyPages() {
|
|
15189
|
+
return this.memory.keys();
|
|
14974
15190
|
}
|
|
14975
15191
|
}
|
|
14976
15192
|
|
|
14977
|
-
declare
|
|
14978
|
-
|
|
15193
|
+
declare class MemoryBuilder {
|
|
15194
|
+
private readonly initialMemory: Map<PageNumber, MemoryPage> = new Map();
|
|
15195
|
+
private isFinalized = false;
|
|
14979
15196
|
|
|
14980
|
-
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
|
|
15197
|
+
private ensureNotFinalized() {
|
|
15198
|
+
if (this.isFinalized) {
|
|
15199
|
+
throw new FinalizedBuilderModification();
|
|
15200
|
+
}
|
|
15201
|
+
}
|
|
14984
15202
|
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
}
|
|
15203
|
+
private ensureNoReservedMemoryUsage(range: MemoryRange) {
|
|
15204
|
+
if (range.overlapsWith(RESERVED_MEMORY_RANGE)) {
|
|
15205
|
+
throw new ReservedMemoryFault();
|
|
15206
|
+
}
|
|
15207
|
+
}
|
|
14990
15208
|
|
|
14991
|
-
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
14996
|
-
|
|
15209
|
+
/**
|
|
15210
|
+
* Create entire readable pages to handle the `[start, end)` range.
|
|
15211
|
+
*
|
|
15212
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
15213
|
+
* they need to be the start indices of the pages.
|
|
15214
|
+
*
|
|
15215
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
15216
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
15217
|
+
*/
|
|
15218
|
+
setReadablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15219
|
+
this.ensureNotFinalized();
|
|
15220
|
+
check`${start < end} end has to be bigger than start`;
|
|
15221
|
+
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15222
|
+
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15223
|
+
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
14997
15224
|
|
|
14998
|
-
|
|
14999
|
-
|
|
15000
|
-
noOfBytesToSkip: 1,
|
|
15001
|
-
firstRegisterIndex: 0,
|
|
15002
|
-
secondRegisterIndex: 0,
|
|
15003
|
-
thirdRegisterIndex: 0,
|
|
15004
|
-
};
|
|
15225
|
+
const length = end - start;
|
|
15226
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15005
15227
|
|
|
15006
|
-
|
|
15007
|
-
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET,
|
|
15008
|
-
noOfBytesToSkip: 1,
|
|
15009
|
-
registerIndex: 0,
|
|
15010
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
15011
|
-
nextPc: 0,
|
|
15012
|
-
};
|
|
15228
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15013
15229
|
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
noOfBytesToSkip: 1,
|
|
15017
|
-
firstRegisterIndex: 0,
|
|
15018
|
-
secondRegisterIndex: 0,
|
|
15019
|
-
nextPc: 0,
|
|
15020
|
-
};
|
|
15230
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
15231
|
+
const noOfPages = pages.length;
|
|
15021
15232
|
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
};
|
|
15233
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
15234
|
+
const pageNumber = pages[i];
|
|
15235
|
+
const dataChunk = data.subarray(i * PAGE_SIZE, (i + 1) * PAGE_SIZE);
|
|
15236
|
+
const page = new ReadablePage(pageNumber, dataChunk);
|
|
15237
|
+
this.initialMemory.set(pageNumber, page);
|
|
15238
|
+
}
|
|
15029
15239
|
|
|
15030
|
-
|
|
15031
|
-
|
|
15032
|
-
noOfBytesToSkip: 1,
|
|
15033
|
-
registerIndex: 0,
|
|
15034
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
15035
|
-
};
|
|
15240
|
+
return this;
|
|
15241
|
+
}
|
|
15036
15242
|
|
|
15037
|
-
|
|
15038
|
-
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
15043
|
-
|
|
15243
|
+
/**
|
|
15244
|
+
* Create entire writeable pages to handle the `[start, end)` range.
|
|
15245
|
+
*
|
|
15246
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
15247
|
+
* they need to be the start indices of the pages.
|
|
15248
|
+
*
|
|
15249
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
15250
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
15251
|
+
*/
|
|
15252
|
+
setWriteablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15253
|
+
this.ensureNotFinalized();
|
|
15254
|
+
check`${start < end} end has to be bigger than start`;
|
|
15255
|
+
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15256
|
+
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15257
|
+
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15044
15258
|
|
|
15045
|
-
|
|
15046
|
-
|
|
15047
|
-
noOfBytesToSkip: 1,
|
|
15048
|
-
nextPc: 0,
|
|
15049
|
-
};
|
|
15259
|
+
const length = end - start;
|
|
15260
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15050
15261
|
|
|
15051
|
-
|
|
15052
|
-
type: ArgumentType.TWO_IMMEDIATES,
|
|
15053
|
-
noOfBytesToSkip: 1,
|
|
15054
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
15055
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
15056
|
-
};
|
|
15262
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15057
15263
|
|
|
15058
|
-
|
|
15059
|
-
|
|
15060
|
-
noOfBytesToSkip: 1,
|
|
15061
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
15062
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
15063
|
-
firstRegisterIndex: 0,
|
|
15064
|
-
secondRegisterIndex: 0,
|
|
15065
|
-
};
|
|
15264
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
15265
|
+
const noOfPages = pages.length;
|
|
15066
15266
|
|
|
15067
|
-
|
|
15068
|
-
|
|
15069
|
-
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
15267
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
15268
|
+
const pageNumber = pages[i];
|
|
15269
|
+
const dataChunk = data.subarray(i * PAGE_SIZE, (i + 1) * PAGE_SIZE);
|
|
15270
|
+
const page = new WriteablePage(pageNumber, dataChunk);
|
|
15271
|
+
this.initialMemory.set(pageNumber, page);
|
|
15272
|
+
}
|
|
15073
15273
|
|
|
15074
|
-
|
|
15075
|
-
}
|
|
15274
|
+
return this;
|
|
15275
|
+
}
|
|
15076
15276
|
|
|
15077
|
-
|
|
15078
|
-
|
|
15079
|
-
|
|
15080
|
-
|
|
15081
|
-
|
|
15082
|
-
|
|
15083
|
-
|
|
15084
|
-
|
|
15085
|
-
|
|
15086
|
-
JUMP = 40,
|
|
15087
|
-
JUMP_IND = 50,
|
|
15088
|
-
LOAD_IMM = 51,
|
|
15089
|
-
LOAD_U8 = 52,
|
|
15090
|
-
LOAD_I8 = 53,
|
|
15091
|
-
LOAD_U16 = 54,
|
|
15092
|
-
LOAD_I16 = 55,
|
|
15093
|
-
LOAD_U32 = 56,
|
|
15094
|
-
LOAD_I32 = 57,
|
|
15095
|
-
LOAD_U64 = 58,
|
|
15096
|
-
STORE_U8 = 59,
|
|
15097
|
-
STORE_U16 = 60,
|
|
15098
|
-
STORE_U32 = 61,
|
|
15099
|
-
STORE_U64 = 62,
|
|
15100
|
-
STORE_IMM_IND_U8 = 70,
|
|
15101
|
-
STORE_IMM_IND_U16 = 71,
|
|
15102
|
-
STORE_IMM_IND_U32 = 72,
|
|
15103
|
-
STORE_IMM_IND_U64 = 73,
|
|
15104
|
-
LOAD_IMM_JUMP = 80,
|
|
15105
|
-
BRANCH_EQ_IMM = 81,
|
|
15106
|
-
BRANCH_NE_IMM = 82,
|
|
15107
|
-
BRANCH_LT_U_IMM = 83,
|
|
15108
|
-
BRANCH_LE_U_IMM = 84,
|
|
15109
|
-
BRANCH_GE_U_IMM = 85,
|
|
15110
|
-
BRANCH_GT_U_IMM = 86,
|
|
15111
|
-
BRANCH_LT_S_IMM = 87,
|
|
15112
|
-
BRANCH_LE_S_IMM = 88,
|
|
15113
|
-
BRANCH_GE_S_IMM = 89,
|
|
15114
|
-
BRANCH_GT_S_IMM = 90,
|
|
15115
|
-
MOVE_REG = 100,
|
|
15116
|
-
SBRK = 101,
|
|
15117
|
-
COUNT_SET_BITS_64 = 102,
|
|
15118
|
-
COUNT_SET_BITS_32 = 103,
|
|
15119
|
-
LEADING_ZERO_BITS_64 = 104,
|
|
15120
|
-
LEADING_ZERO_BITS_32 = 105,
|
|
15121
|
-
TRAILING_ZERO_BITS_64 = 106,
|
|
15122
|
-
TRAILING_ZERO_BITS_32 = 107,
|
|
15123
|
-
SIGN_EXTEND_8 = 108,
|
|
15124
|
-
SIGN_EXTEND_16 = 109,
|
|
15125
|
-
ZERO_EXTEND_16 = 110,
|
|
15126
|
-
REVERSE_BYTES = 111,
|
|
15127
|
-
STORE_IND_U8 = 120,
|
|
15128
|
-
STORE_IND_U16 = 121,
|
|
15129
|
-
STORE_IND_U32 = 122,
|
|
15130
|
-
STORE_IND_U64 = 123,
|
|
15131
|
-
LOAD_IND_U8 = 124,
|
|
15132
|
-
LOAD_IND_I8 = 125,
|
|
15133
|
-
LOAD_IND_U16 = 126,
|
|
15134
|
-
LOAD_IND_I16 = 127,
|
|
15135
|
-
LOAD_IND_U32 = 128,
|
|
15136
|
-
LOAD_IND_I32 = 129,
|
|
15137
|
-
LOAD_IND_U64 = 130,
|
|
15138
|
-
ADD_IMM_32 = 131,
|
|
15139
|
-
AND_IMM = 132,
|
|
15140
|
-
XOR_IMM = 133,
|
|
15141
|
-
OR_IMM = 134,
|
|
15142
|
-
MUL_IMM_32 = 135,
|
|
15143
|
-
SET_LT_U_IMM = 136,
|
|
15144
|
-
SET_LT_S_IMM = 137,
|
|
15145
|
-
SHLO_L_IMM_32 = 138,
|
|
15146
|
-
SHLO_R_IMM_32 = 139,
|
|
15147
|
-
SHAR_R_IMM_32 = 140,
|
|
15148
|
-
NEG_ADD_IMM_32 = 141,
|
|
15149
|
-
SET_GT_U_IMM = 142,
|
|
15150
|
-
SET_GT_S_IMM = 143,
|
|
15151
|
-
SHLO_L_IMM_ALT_32 = 144,
|
|
15152
|
-
SHLO_R_IMM_ALT_32 = 145,
|
|
15153
|
-
SHAR_R_IMM_ALT_32 = 146,
|
|
15154
|
-
CMOV_IZ_IMM = 147,
|
|
15155
|
-
CMOV_NZ_IMM = 148,
|
|
15156
|
-
ADD_IMM_64 = 149,
|
|
15157
|
-
MUL_IMM_64 = 150,
|
|
15158
|
-
SHLO_L_IMM_64 = 151,
|
|
15159
|
-
SHLO_R_IMM_64 = 152,
|
|
15160
|
-
SHAR_R_IMM_64 = 153,
|
|
15161
|
-
NEG_ADD_IMM_64 = 154,
|
|
15162
|
-
SHLO_L_IMM_ALT_64 = 155,
|
|
15163
|
-
SHLO_R_IMM_ALT_64 = 156,
|
|
15164
|
-
SHAR_R_IMM_ALT_64 = 157,
|
|
15165
|
-
ROT_R_64_IMM = 158,
|
|
15166
|
-
ROT_R_64_IMM_ALT = 159,
|
|
15167
|
-
ROT_R_32_IMM = 160,
|
|
15168
|
-
ROT_R_32_IMM_ALT = 161,
|
|
15169
|
-
BRANCH_EQ = 170,
|
|
15170
|
-
BRANCH_NE = 171,
|
|
15171
|
-
BRANCH_LT_U = 172,
|
|
15172
|
-
BRANCH_LT_S = 173,
|
|
15173
|
-
BRANCH_GE_U = 174,
|
|
15174
|
-
BRANCH_GE_S = 175,
|
|
15175
|
-
LOAD_IMM_JUMP_IND = 180,
|
|
15176
|
-
ADD_32 = 190,
|
|
15177
|
-
SUB_32 = 191,
|
|
15178
|
-
MUL_32 = 192,
|
|
15179
|
-
DIV_U_32 = 193,
|
|
15180
|
-
DIV_S_32 = 194,
|
|
15181
|
-
REM_U_32 = 195,
|
|
15182
|
-
REM_S_32 = 196,
|
|
15183
|
-
SHLO_L_32 = 197,
|
|
15184
|
-
SHLO_R_32 = 198,
|
|
15185
|
-
SHAR_R_32 = 199,
|
|
15186
|
-
ADD_64 = 200,
|
|
15187
|
-
SUB_64 = 201,
|
|
15188
|
-
MUL_64 = 202,
|
|
15189
|
-
DIV_U_64 = 203,
|
|
15190
|
-
DIV_S_64 = 204,
|
|
15191
|
-
REM_U_64 = 205,
|
|
15192
|
-
REM_S_64 = 206,
|
|
15193
|
-
SHLO_L_64 = 207,
|
|
15194
|
-
SHLO_R_64 = 208,
|
|
15195
|
-
SHAR_R_64 = 209,
|
|
15196
|
-
AND = 210,
|
|
15197
|
-
XOR = 211,
|
|
15198
|
-
OR = 212,
|
|
15199
|
-
MUL_UPPER_S_S = 213,
|
|
15200
|
-
MUL_UPPER_U_U = 214,
|
|
15201
|
-
MUL_UPPER_S_U = 215,
|
|
15202
|
-
SET_LT_U = 216,
|
|
15203
|
-
SET_LT_S = 217,
|
|
15204
|
-
CMOV_IZ = 218,
|
|
15205
|
-
CMOV_NZ = 219,
|
|
15206
|
-
ROT_L_64 = 220,
|
|
15207
|
-
ROT_L_32 = 221,
|
|
15208
|
-
ROT_R_64 = 222,
|
|
15209
|
-
ROT_R_32 = 223,
|
|
15210
|
-
AND_INV = 224,
|
|
15211
|
-
OR_INV = 225,
|
|
15212
|
-
XNOR = 226,
|
|
15213
|
-
MAX = 227,
|
|
15214
|
-
MAX_U = 228,
|
|
15215
|
-
MIN = 229,
|
|
15216
|
-
MIN_U = 230,
|
|
15217
|
-
}
|
|
15277
|
+
/**
|
|
15278
|
+
* This function can be useful when page map and initial memory data are provided separatelly.
|
|
15279
|
+
* You can use setWriteablePages/setReadablePages to create empty pages and then setData to fill them
|
|
15280
|
+
*/
|
|
15281
|
+
setData(start: MemoryIndex, data: Uint8Array) {
|
|
15282
|
+
this.ensureNotFinalized();
|
|
15283
|
+
const pageOffset = start % PAGE_SIZE;
|
|
15284
|
+
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15285
|
+
check`${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15218
15286
|
|
|
15219
|
-
|
|
15220
|
-
|
|
15287
|
+
const length = data.length;
|
|
15288
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15221
15289
|
|
|
15222
|
-
|
|
15223
|
-
instructionArgumentTypeMap[Instruction.FALLTHROUGH] = ArgumentType.NO_ARGUMENTS;
|
|
15290
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15224
15291
|
|
|
15225
|
-
|
|
15292
|
+
const pageNumber = getPageNumber(start);
|
|
15293
|
+
const page = this.initialMemory.get(pageNumber);
|
|
15226
15294
|
|
|
15227
|
-
|
|
15295
|
+
if (page === undefined) {
|
|
15296
|
+
throw new PageNotExist();
|
|
15297
|
+
}
|
|
15228
15298
|
|
|
15229
|
-
|
|
15230
|
-
|
|
15231
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U32] = ArgumentType.TWO_IMMEDIATES;
|
|
15232
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U64] = ArgumentType.TWO_IMMEDIATES;
|
|
15299
|
+
const startPageIndex = tryAsPageIndex(start - page.start);
|
|
15300
|
+
page.setData(startPageIndex, data);
|
|
15233
15301
|
|
|
15234
|
-
|
|
15302
|
+
return this;
|
|
15303
|
+
}
|
|
15235
15304
|
|
|
15236
|
-
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
|
|
15240
|
-
|
|
15241
|
-
|
|
15242
|
-
instructionArgumentTypeMap[Instruction.LOAD_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15243
|
-
instructionArgumentTypeMap[Instruction.LOAD_I32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15244
|
-
instructionArgumentTypeMap[Instruction.LOAD_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15245
|
-
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15246
|
-
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15247
|
-
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15248
|
-
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15249
|
-
|
|
15250
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U8] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15251
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U16] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15252
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15253
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15254
|
-
|
|
15255
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15256
|
-
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15257
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15258
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15259
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15260
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15261
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15262
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15263
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15264
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15265
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15266
|
-
|
|
15267
|
-
instructionArgumentTypeMap[Instruction.MOVE_REG] = ArgumentType.TWO_REGISTERS;
|
|
15268
|
-
instructionArgumentTypeMap[Instruction.SBRK] = ArgumentType.TWO_REGISTERS;
|
|
15269
|
-
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
15270
|
-
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
15271
|
-
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
15272
|
-
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
15273
|
-
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
15274
|
-
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
15275
|
-
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_8] = ArgumentType.TWO_REGISTERS;
|
|
15276
|
-
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
15277
|
-
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
15278
|
-
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
15279
|
-
|
|
15280
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15281
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15282
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15283
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15284
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15285
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15286
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15287
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15288
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15289
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15290
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15291
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15292
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15293
|
-
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15294
|
-
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15295
|
-
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15296
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15297
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15298
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15299
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15300
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15301
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15302
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15303
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15304
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15305
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15306
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15307
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15308
|
-
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15309
|
-
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15310
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15311
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15312
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15313
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15314
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15315
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15316
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15317
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15318
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15319
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15320
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15321
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15322
|
-
|
|
15323
|
-
instructionArgumentTypeMap[Instruction.BRANCH_EQ] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15324
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15325
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15326
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15327
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15328
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15329
|
-
|
|
15330
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP_IND] = ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
15331
|
-
|
|
15332
|
-
instructionArgumentTypeMap[Instruction.ADD_32] = ArgumentType.THREE_REGISTERS;
|
|
15333
|
-
instructionArgumentTypeMap[Instruction.ADD_64] = ArgumentType.THREE_REGISTERS;
|
|
15334
|
-
instructionArgumentTypeMap[Instruction.SUB_32] = ArgumentType.THREE_REGISTERS;
|
|
15335
|
-
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
15336
|
-
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
15337
|
-
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
15338
|
-
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
15339
|
-
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
15340
|
-
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
15341
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
15342
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
15343
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
15344
|
-
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
15345
|
-
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
15346
|
-
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
15347
|
-
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
15348
|
-
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
15349
|
-
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
15350
|
-
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
15351
|
-
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
15352
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
15353
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
15354
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
15355
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15356
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15357
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
15358
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15359
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15360
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
15361
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
15362
|
-
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
15363
|
-
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
15364
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15365
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15366
|
-
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
15367
|
-
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
15368
|
-
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
15369
|
-
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
15370
|
-
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
15371
|
-
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
15372
|
-
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
15373
|
-
|
|
15374
|
-
return instructionArgumentTypeMap;
|
|
15375
|
-
})();
|
|
15376
|
-
|
|
15377
|
-
declare class BasicBlocks {
|
|
15378
|
-
private basicBlocks: Set<number> = new Set();
|
|
15379
|
-
|
|
15380
|
-
reset(code: Uint8Array, mask: Mask) {
|
|
15381
|
-
this.basicBlocks.clear();
|
|
15382
|
-
this.basicBlocks.add(0);
|
|
15383
|
-
const codeLength = code.length;
|
|
15305
|
+
finalize(startHeapIndex: MemoryIndex, endHeapIndex: SbrkIndex): Memory {
|
|
15306
|
+
check`
|
|
15307
|
+
${startHeapIndex <= endHeapIndex}
|
|
15308
|
+
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
15309
|
+
`;
|
|
15310
|
+
this.ensureNotFinalized();
|
|
15384
15311
|
|
|
15385
|
-
const
|
|
15386
|
-
|
|
15312
|
+
const heapRange = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
15313
|
+
const heapPagesRange = PageRange.fromMemoryRange(heapRange);
|
|
15314
|
+
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
15387
15315
|
|
|
15388
|
-
for (
|
|
15389
|
-
if (
|
|
15390
|
-
|
|
15316
|
+
for (const pageNumber of initializedPageNumbers) {
|
|
15317
|
+
if (heapPagesRange.isInRange(pageNumber)) {
|
|
15318
|
+
throw new IncorrectSbrkIndex();
|
|
15391
15319
|
}
|
|
15392
15320
|
}
|
|
15393
|
-
}
|
|
15394
|
-
|
|
15395
|
-
isBeginningOfBasicBlock(index: number) {
|
|
15396
|
-
return this.basicBlocks.has(index);
|
|
15397
|
-
}
|
|
15398
|
-
}
|
|
15399
|
-
|
|
15400
|
-
declare enum Result {
|
|
15401
|
-
HALT = 0,
|
|
15402
|
-
PANIC = 1,
|
|
15403
|
-
FAULT_ACCESS = 2,
|
|
15404
|
-
FAULT = 3,
|
|
15405
|
-
HOST = 4,
|
|
15406
|
-
}
|
|
15407
15321
|
|
|
15408
|
-
|
|
15409
|
-
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
|
|
15413
|
-
*
|
|
15414
|
-
* In case of a `status === Result.FAULT` this will be the memory address
|
|
15415
|
-
* that triggered the fault.
|
|
15416
|
-
* In case of a `status === Result.HOST` this will be the host call index
|
|
15417
|
-
* that should be invoked.
|
|
15418
|
-
*
|
|
15419
|
-
* In any other circumstance the value should be `null`.
|
|
15420
|
-
*/
|
|
15421
|
-
public exitParam: number | null = null;
|
|
15322
|
+
const memory = Memory.fromInitialMemory({
|
|
15323
|
+
memory: this.initialMemory,
|
|
15324
|
+
sbrkIndex: tryAsSbrkIndex(startHeapIndex),
|
|
15325
|
+
endHeapIndex,
|
|
15326
|
+
});
|
|
15422
15327
|
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
this.status = null;
|
|
15426
|
-
this.exitParam = null;
|
|
15328
|
+
this.isFinalized = true;
|
|
15329
|
+
return memory;
|
|
15427
15330
|
}
|
|
15428
15331
|
}
|
|
15429
15332
|
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
declare const tryAsMemoryIndex = (index: number): MemoryIndex => {
|
|
15433
|
-
check`${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15434
|
-
return asOpaqueType(index);
|
|
15435
|
-
};
|
|
15436
|
-
|
|
15437
|
-
type SbrkIndex = Opaque<number, "sbrk index">;
|
|
15438
|
-
|
|
15439
|
-
declare const tryAsSbrkIndex = (index: number): SbrkIndex => {
|
|
15440
|
-
check`${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
15441
|
-
return asOpaqueType(index);
|
|
15442
|
-
};
|
|
15443
|
-
|
|
15444
|
-
type PageIndex = Opaque<number, "memory page index">;
|
|
15445
|
-
type PageNumber = Opaque<number, "memory page number">;
|
|
15446
|
-
|
|
15447
|
-
declare class PageFault {
|
|
15448
|
-
private constructor(
|
|
15449
|
-
public address: MemoryIndex,
|
|
15450
|
-
public isAccessFault = true,
|
|
15451
|
-
) {}
|
|
15333
|
+
declare const NO_OF_REGISTERS = 13;
|
|
15452
15334
|
|
|
15453
|
-
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
return new PageFault(startPageIndex, isAccessFault);
|
|
15335
|
+
declare class MemorySegment extends WithDebug {
|
|
15336
|
+
static from({ start, end, data }: Omit<MemorySegment, never>) {
|
|
15337
|
+
return new MemorySegment(start, end, data);
|
|
15457
15338
|
}
|
|
15458
15339
|
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
|
|
15340
|
+
constructor(
|
|
15341
|
+
public readonly start: number,
|
|
15342
|
+
public readonly end: number,
|
|
15343
|
+
public readonly data: Uint8Array | null,
|
|
15344
|
+
) {
|
|
15345
|
+
super();
|
|
15346
|
+
}
|
|
15347
|
+
}
|
|
15348
|
+
declare class SpiMemory extends WithDebug {
|
|
15349
|
+
constructor(
|
|
15350
|
+
public readonly readable: MemorySegment[],
|
|
15351
|
+
public readonly writeable: MemorySegment[],
|
|
15352
|
+
public readonly sbrkIndex: number,
|
|
15353
|
+
public readonly heapEnd: number,
|
|
15354
|
+
) {
|
|
15355
|
+
super();
|
|
15463
15356
|
}
|
|
15464
15357
|
}
|
|
15465
15358
|
|
|
15466
|
-
declare class
|
|
15467
|
-
constructor(
|
|
15468
|
-
|
|
15359
|
+
declare class SpiProgram extends WithDebug {
|
|
15360
|
+
constructor(
|
|
15361
|
+
public readonly code: Uint8Array,
|
|
15362
|
+
public readonly memory: SpiMemory,
|
|
15363
|
+
public readonly registers: BigUint64Array,
|
|
15364
|
+
) {
|
|
15365
|
+
super();
|
|
15469
15366
|
}
|
|
15470
15367
|
}
|
|
15471
15368
|
|
|
15472
15369
|
/**
|
|
15473
|
-
*
|
|
15474
|
-
* possibly empty or wrapping around.
|
|
15370
|
+
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
15475
15371
|
*
|
|
15476
|
-
*
|
|
15372
|
+
* E_n - little endian encoding, n - length
|
|
15373
|
+
* o - initial read only data
|
|
15374
|
+
* w - initial heap
|
|
15375
|
+
* z - heap pages filled with zeros
|
|
15376
|
+
* s - stack size
|
|
15377
|
+
* c - program code
|
|
15378
|
+
*
|
|
15379
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
15477
15380
|
*/
|
|
15478
|
-
declare
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15381
|
+
declare function decodeStandardProgram(program: Uint8Array, args: Uint8Array) {
|
|
15382
|
+
const decoder = Decoder.fromBlob(program);
|
|
15383
|
+
const oLength = decoder.u24();
|
|
15384
|
+
const wLength = decoder.u24();
|
|
15385
|
+
check`${args.length <= DATA_LENGTH} Incorrect arguments length`;
|
|
15386
|
+
check`${oLength <= DATA_LENGTH} Incorrect readonly segment length`;
|
|
15387
|
+
const readOnlyLength = oLength;
|
|
15388
|
+
check`${wLength <= DATA_LENGTH} Incorrect heap segment length`;
|
|
15389
|
+
const heapLength = wLength;
|
|
15390
|
+
const noOfHeapZerosPages = decoder.u16();
|
|
15391
|
+
const stackSize = decoder.u24();
|
|
15392
|
+
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
15393
|
+
const initialHeap = decoder.bytes(heapLength).raw;
|
|
15394
|
+
const codeLength = decoder.u32();
|
|
15395
|
+
const code = decoder.bytes(codeLength).raw;
|
|
15396
|
+
decoder.finish();
|
|
15491
15397
|
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
15495
|
-
)
|
|
15496
|
-
|
|
15398
|
+
const readonlyDataStart = SEGMENT_SIZE;
|
|
15399
|
+
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
15400
|
+
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
15401
|
+
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
15402
|
+
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
15403
|
+
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
15404
|
+
const stackEnd = STACK_SEGMENT;
|
|
15405
|
+
const argsStart = ARGS_SEGMENT;
|
|
15406
|
+
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
15407
|
+
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
15497
15408
|
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
}
|
|
15409
|
+
function nonEmpty(s: MemorySegment | false): s is MemorySegment {
|
|
15410
|
+
return s !== false;
|
|
15501
15411
|
}
|
|
15502
15412
|
|
|
15503
|
-
|
|
15504
|
-
|
|
15505
|
-
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15413
|
+
const readableMemory = [
|
|
15414
|
+
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
15415
|
+
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
15416
|
+
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
15417
|
+
].filter(nonEmpty);
|
|
15418
|
+
const writeableMemory = [
|
|
15419
|
+
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
15420
|
+
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
15421
|
+
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
15422
|
+
].filter(nonEmpty);
|
|
15511
15423
|
|
|
15512
|
-
|
|
15513
|
-
|
|
15514
|
-
|
|
15515
|
-
|
|
15424
|
+
return new SpiProgram(
|
|
15425
|
+
code,
|
|
15426
|
+
new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart),
|
|
15427
|
+
getRegisters(args.length),
|
|
15428
|
+
);
|
|
15429
|
+
}
|
|
15516
15430
|
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
}
|
|
15431
|
+
declare function getMemorySegment(start: number, end: number, data: Uint8Array | null = null) {
|
|
15432
|
+
return new MemorySegment(start, end, data);
|
|
15433
|
+
}
|
|
15521
15434
|
|
|
15522
|
-
|
|
15523
|
-
|
|
15524
|
-
if (this.isWrapped()) {
|
|
15525
|
-
return address >= this.start || address < this.end;
|
|
15526
|
-
}
|
|
15435
|
+
declare function getRegisters(argsLength: number) {
|
|
15436
|
+
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
15527
15437
|
|
|
15528
|
-
|
|
15529
|
-
|
|
15438
|
+
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
15439
|
+
regs[0] = BigInt(LAST_PAGE);
|
|
15440
|
+
regs[1] = BigInt(STACK_SEGMENT);
|
|
15441
|
+
regs[7] = BigInt(ARGS_SEGMENT);
|
|
15442
|
+
regs[8] = BigInt(argsLength);
|
|
15530
15443
|
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
if (this.lastIndex === null || other.lastIndex === null) {
|
|
15534
|
-
return false;
|
|
15535
|
-
}
|
|
15444
|
+
return regs;
|
|
15445
|
+
}
|
|
15536
15446
|
|
|
15537
|
-
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15447
|
+
type index$8_MemorySegment = MemorySegment;
|
|
15448
|
+
declare const index$8_MemorySegment: typeof MemorySegment;
|
|
15449
|
+
declare const index$8_NO_OF_REGISTERS: typeof NO_OF_REGISTERS;
|
|
15450
|
+
type index$8_SpiMemory = SpiMemory;
|
|
15451
|
+
declare const index$8_SpiMemory: typeof SpiMemory;
|
|
15452
|
+
type index$8_SpiProgram = SpiProgram;
|
|
15453
|
+
declare const index$8_SpiProgram: typeof SpiProgram;
|
|
15454
|
+
declare const index$8_decodeStandardProgram: typeof decodeStandardProgram;
|
|
15455
|
+
declare const index$8_getMemorySegment: typeof getMemorySegment;
|
|
15456
|
+
declare const index$8_getRegisters: typeof getRegisters;
|
|
15457
|
+
declare namespace index$8 {
|
|
15458
|
+
export {
|
|
15459
|
+
index$8_MemorySegment as MemorySegment,
|
|
15460
|
+
index$8_NO_OF_REGISTERS as NO_OF_REGISTERS,
|
|
15461
|
+
index$8_SpiMemory as SpiMemory,
|
|
15462
|
+
index$8_SpiProgram as SpiProgram,
|
|
15463
|
+
index$8_decodeStandardProgram as decodeStandardProgram,
|
|
15464
|
+
index$8_getMemorySegment as getMemorySegment,
|
|
15465
|
+
index$8_getRegisters as getRegisters,
|
|
15466
|
+
};
|
|
15544
15467
|
}
|
|
15545
15468
|
|
|
15546
|
-
declare
|
|
15547
|
-
|
|
15469
|
+
declare class Program {
|
|
15470
|
+
static fromSpi(blob: Uint8Array, args: Uint8Array, hasMetadata: boolean) {
|
|
15471
|
+
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15472
|
+
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
15473
|
+
const regs = new Registers();
|
|
15474
|
+
regs.copyFrom(registers);
|
|
15475
|
+
const memoryBuilder = new MemoryBuilder();
|
|
15548
15476
|
|
|
15549
|
-
|
|
15550
|
-
|
|
15551
|
-
|
|
15477
|
+
for (const { start, end, data } of rawMemory.readable) {
|
|
15478
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
15479
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
15480
|
+
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15481
|
+
}
|
|
15552
15482
|
|
|
15553
|
-
|
|
15554
|
-
|
|
15483
|
+
for (const { start, end, data } of rawMemory.writeable) {
|
|
15484
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
15485
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
15486
|
+
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15487
|
+
}
|
|
15555
15488
|
|
|
15556
|
-
|
|
15557
|
-
|
|
15558
|
-
|
|
15559
|
-
*
|
|
15560
|
-
* Note that the `res` might be bigger than the number of bytes length, but cannot be smaller.
|
|
15561
|
-
*
|
|
15562
|
-
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
15563
|
-
* NOTE That the `result` might be partially modified in case `PageFault` occurs!
|
|
15564
|
-
*/
|
|
15565
|
-
abstract loadInto(res: Uint8Array, address: PageIndex, length: number): Result$2<OK, PageFault>;
|
|
15489
|
+
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
15490
|
+
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
15491
|
+
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
15566
15492
|
|
|
15567
|
-
|
|
15568
|
-
|
|
15569
|
-
*
|
|
15570
|
-
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
15571
|
-
*/
|
|
15572
|
-
abstract storeFrom(address: PageIndex, data: Uint8Array): Result$2<OK, PageFault>;
|
|
15573
|
-
/**
|
|
15574
|
-
* Get dump of the entire page. Should only be used for the debugger-adapter because it
|
|
15575
|
-
* might be inefficient.
|
|
15576
|
-
*/
|
|
15577
|
-
abstract getPageDump(): Uint8Array;
|
|
15493
|
+
return new Program(code, regs, memory, metadata);
|
|
15494
|
+
}
|
|
15578
15495
|
|
|
15579
|
-
|
|
15496
|
+
static fromGeneric(blob: Uint8Array, hasMetadata: boolean) {
|
|
15497
|
+
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15498
|
+
const regs = new Registers();
|
|
15499
|
+
const memory = new Memory();
|
|
15500
|
+
return new Program(code, regs, memory, metadata);
|
|
15501
|
+
}
|
|
15502
|
+
|
|
15503
|
+
private constructor(
|
|
15504
|
+
public readonly code: Uint8Array,
|
|
15505
|
+
public readonly registers: Registers,
|
|
15506
|
+
public readonly memory: Memory,
|
|
15507
|
+
public metadata: Uint8Array = new Uint8Array(),
|
|
15508
|
+
) {}
|
|
15580
15509
|
}
|
|
15581
15510
|
|
|
15582
15511
|
/**
|
|
15583
|
-
*
|
|
15584
|
-
*
|
|
15585
|
-
*
|
|
15512
|
+
* A function that splits preimage into metadata and code.
|
|
15513
|
+
*
|
|
15514
|
+
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
15586
15515
|
*/
|
|
15587
|
-
declare
|
|
15588
|
-
|
|
15589
|
-
|
|
15590
|
-
|
|
15591
|
-
|
|
15592
|
-
}
|
|
15593
|
-
interface ArrayBuffer {
|
|
15594
|
-
resize(length: number): void;
|
|
15595
|
-
}
|
|
15516
|
+
declare function extractCodeAndMetadata(blobWithMetadata: Uint8Array) {
|
|
15517
|
+
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
15518
|
+
const metadata = decoder.bytesBlob().raw;
|
|
15519
|
+
const code = decoder.remainingBytes().raw;
|
|
15520
|
+
return { metadata, code };
|
|
15596
15521
|
}
|
|
15597
15522
|
|
|
15598
|
-
type
|
|
15599
|
-
|
|
15600
|
-
|
|
15601
|
-
|
|
15602
|
-
|
|
15603
|
-
|
|
15604
|
-
|
|
15605
|
-
|
|
15606
|
-
WRITE = 1,
|
|
15523
|
+
type index$7_Program = Program;
|
|
15524
|
+
declare const index$7_Program: typeof Program;
|
|
15525
|
+
declare const index$7_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
15526
|
+
declare namespace index$7 {
|
|
15527
|
+
export {
|
|
15528
|
+
index$7_Program as Program,
|
|
15529
|
+
index$7_extractCodeAndMetadata as extractCodeAndMetadata,
|
|
15530
|
+
};
|
|
15607
15531
|
}
|
|
15608
15532
|
|
|
15609
|
-
|
|
15610
|
-
|
|
15611
|
-
|
|
15612
|
-
|
|
15613
|
-
|
|
15614
|
-
|
|
15615
|
-
|
|
15616
|
-
|
|
15533
|
+
/**
|
|
15534
|
+
* Mask class is an implementation of skip function defined in GP.
|
|
15535
|
+
*
|
|
15536
|
+
* https://graypaper.fluffylabs.dev/#/5f542d7/237201239801
|
|
15537
|
+
*/
|
|
15538
|
+
declare class Mask {
|
|
15539
|
+
/**
|
|
15540
|
+
* The lookup table will have `0` at the index which corresponds to an instruction on the same index in the bytecode.
|
|
15541
|
+
* In case the value is non-zero it signifies the offset to the index with next instruction.
|
|
15542
|
+
*
|
|
15543
|
+
* Example:
|
|
15544
|
+
* ```
|
|
15545
|
+
* 0..1..2..3..4..5..6..7..8..9 # Indices
|
|
15546
|
+
* 0..2..1..0..1..0..3..2..1..0 # lookupTable forward values
|
|
15547
|
+
* ```
|
|
15548
|
+
* There are instructions at indices `0, 3, 5, 9`.
|
|
15549
|
+
*/
|
|
15550
|
+
private lookupTableForward: Uint8Array;
|
|
15551
|
+
|
|
15552
|
+
constructor(mask: BitVec) {
|
|
15553
|
+
this.lookupTableForward = this.buildLookupTableForward(mask);
|
|
15617
15554
|
}
|
|
15618
15555
|
|
|
15619
|
-
|
|
15620
|
-
|
|
15621
|
-
private virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
15622
|
-
private endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX),
|
|
15623
|
-
private memory = new Map<PageNumber, MemoryPage>(),
|
|
15624
|
-
) {}
|
|
15625
|
-
|
|
15626
|
-
reset() {
|
|
15627
|
-
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15628
|
-
this.virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15629
|
-
this.endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX);
|
|
15630
|
-
this.memory = new Map<PageNumber, MemoryPage>(); // TODO [MaSi]: We should keep allocated pages somewhere and reuse it when it is possible
|
|
15556
|
+
isInstruction(index: number) {
|
|
15557
|
+
return this.lookupTableForward[index] === 0;
|
|
15631
15558
|
}
|
|
15632
15559
|
|
|
15633
|
-
|
|
15634
|
-
|
|
15635
|
-
this.
|
|
15636
|
-
this.endHeapIndex = memory.endHeapIndex;
|
|
15637
|
-
this.memory = memory.memory;
|
|
15560
|
+
getNoOfBytesToNextInstruction(index: number) {
|
|
15561
|
+
check`${index >= 0} index (${index}) cannot be a negative number`;
|
|
15562
|
+
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
15638
15563
|
}
|
|
15639
15564
|
|
|
15640
|
-
|
|
15641
|
-
|
|
15642
|
-
|
|
15643
|
-
|
|
15644
|
-
|
|
15645
|
-
|
|
15646
|
-
|
|
15647
|
-
|
|
15648
|
-
|
|
15649
|
-
|
|
15565
|
+
private buildLookupTableForward(mask: BitVec) {
|
|
15566
|
+
const table = safeAllocUint8Array(mask.bitLength);
|
|
15567
|
+
let lastInstructionOffset = 0;
|
|
15568
|
+
for (let i = mask.bitLength - 1; i >= 0; i--) {
|
|
15569
|
+
if (mask.isSet(i)) {
|
|
15570
|
+
lastInstructionOffset = 0;
|
|
15571
|
+
} else {
|
|
15572
|
+
lastInstructionOffset++;
|
|
15573
|
+
}
|
|
15574
|
+
table[i] = lastInstructionOffset;
|
|
15650
15575
|
}
|
|
15576
|
+
return table;
|
|
15577
|
+
}
|
|
15651
15578
|
|
|
15652
|
-
|
|
15653
|
-
|
|
15654
|
-
|
|
15579
|
+
static empty() {
|
|
15580
|
+
return new Mask(BitVec.empty(0));
|
|
15581
|
+
}
|
|
15582
|
+
}
|
|
15655
15583
|
|
|
15656
|
-
|
|
15657
|
-
|
|
15658
|
-
|
|
15659
|
-
|
|
15660
|
-
|
|
15584
|
+
declare enum ArgumentType {
|
|
15585
|
+
NO_ARGUMENTS = 0,
|
|
15586
|
+
ONE_IMMEDIATE = 1,
|
|
15587
|
+
TWO_IMMEDIATES = 2,
|
|
15588
|
+
ONE_OFFSET = 3,
|
|
15589
|
+
ONE_REGISTER_ONE_IMMEDIATE = 4,
|
|
15590
|
+
ONE_REGISTER_TWO_IMMEDIATES = 5,
|
|
15591
|
+
ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET = 6,
|
|
15592
|
+
TWO_REGISTERS = 7,
|
|
15593
|
+
TWO_REGISTERS_ONE_IMMEDIATE = 8,
|
|
15594
|
+
TWO_REGISTERS_ONE_OFFSET = 9,
|
|
15595
|
+
TWO_REGISTERS_TWO_IMMEDIATES = 10,
|
|
15596
|
+
THREE_REGISTERS = 11,
|
|
15597
|
+
ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE = 12,
|
|
15598
|
+
}
|
|
15661
15599
|
|
|
15662
|
-
|
|
15600
|
+
declare class ExtendedWitdthImmediateDecoder {
|
|
15601
|
+
private unsignedImmediate: BigUint64Array;
|
|
15602
|
+
private bytes: Uint8Array;
|
|
15663
15603
|
|
|
15664
|
-
|
|
15665
|
-
|
|
15666
|
-
|
|
15667
|
-
|
|
15604
|
+
constructor() {
|
|
15605
|
+
const buffer = new ArrayBuffer(IMMEDIATE_SIZE);
|
|
15606
|
+
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
15607
|
+
this.bytes = new Uint8Array(buffer);
|
|
15668
15608
|
}
|
|
15669
15609
|
|
|
15670
|
-
|
|
15671
|
-
|
|
15672
|
-
|
|
15610
|
+
setBytes(bytes: Uint8Array) {
|
|
15611
|
+
let i = 0;
|
|
15612
|
+
for (; i < bytes.length; i++) {
|
|
15613
|
+
this.bytes[i] = bytes[i];
|
|
15673
15614
|
}
|
|
15674
15615
|
|
|
15675
|
-
|
|
15676
|
-
|
|
15616
|
+
for (; i < IMMEDIATE_SIZE; i++) {
|
|
15617
|
+
this.bytes[i] = 0;
|
|
15618
|
+
}
|
|
15619
|
+
}
|
|
15677
15620
|
|
|
15678
|
-
|
|
15621
|
+
getValue() {
|
|
15622
|
+
return this.unsignedImmediate[0];
|
|
15623
|
+
}
|
|
15679
15624
|
|
|
15680
|
-
|
|
15681
|
-
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
() => `Page fault: attempted to access reserved page ${pageNumber}`,
|
|
15685
|
-
);
|
|
15686
|
-
}
|
|
15625
|
+
getBytesAsLittleEndian() {
|
|
15626
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE);
|
|
15627
|
+
}
|
|
15628
|
+
}
|
|
15687
15629
|
|
|
15688
|
-
|
|
15630
|
+
declare class ImmediateDecoder {
|
|
15631
|
+
private u32: Uint32Array;
|
|
15632
|
+
private i32: Int32Array;
|
|
15633
|
+
private u64: BigUint64Array;
|
|
15634
|
+
private i64: BigInt64Array;
|
|
15635
|
+
private view: DataView;
|
|
15636
|
+
private bytes: Uint8Array;
|
|
15689
15637
|
|
|
15690
|
-
|
|
15691
|
-
|
|
15692
|
-
|
|
15638
|
+
constructor() {
|
|
15639
|
+
const buffer = new ArrayBuffer(BUFFER_SIZE);
|
|
15640
|
+
this.u32 = new Uint32Array(buffer);
|
|
15641
|
+
this.i32 = new Int32Array(buffer);
|
|
15642
|
+
this.u64 = new BigUint64Array(buffer);
|
|
15643
|
+
this.i64 = new BigInt64Array(buffer);
|
|
15644
|
+
this.view = new DataView(buffer);
|
|
15645
|
+
this.bytes = new Uint8Array(buffer);
|
|
15646
|
+
}
|
|
15693
15647
|
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
|
|
15699
|
-
}
|
|
15648
|
+
setBytes(bytes: Uint8Array) {
|
|
15649
|
+
const n = bytes.length;
|
|
15650
|
+
const msb = n > 0 ? bytes[n - 1] & 0x80 : 0;
|
|
15651
|
+
const noOfBytes = Math.min(n, BUFFER_SIZE);
|
|
15652
|
+
const prefix = msb !== 0 ? 0xff : 0x00;
|
|
15700
15653
|
|
|
15701
|
-
|
|
15654
|
+
for (let i = 0; i < noOfBytes; i++) {
|
|
15655
|
+
this.view.setUint8(i, bytes[i]);
|
|
15702
15656
|
}
|
|
15703
15657
|
|
|
15704
|
-
|
|
15658
|
+
for (let i = n; i < BUFFER_SIZE; i++) {
|
|
15659
|
+
this.view.setUint8(i, prefix);
|
|
15660
|
+
}
|
|
15705
15661
|
}
|
|
15662
|
+
|
|
15706
15663
|
/**
|
|
15707
|
-
*
|
|
15708
|
-
* write the result into the `result` buffer.
|
|
15709
|
-
*
|
|
15710
|
-
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
15664
|
+
* @deprecated Use getU32 instead
|
|
15711
15665
|
*/
|
|
15712
|
-
|
|
15713
|
-
|
|
15714
|
-
|
|
15715
|
-
}
|
|
15716
|
-
|
|
15717
|
-
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
15718
|
-
|
|
15719
|
-
if (pagesResult.isError) {
|
|
15720
|
-
return Result.error(pagesResult.error, pagesResult.details);
|
|
15721
|
-
}
|
|
15666
|
+
getUnsigned() {
|
|
15667
|
+
return this.u32[U32_INDEX];
|
|
15668
|
+
}
|
|
15722
15669
|
|
|
15723
|
-
|
|
15670
|
+
/**
|
|
15671
|
+
* @deprecated Use getI32 instead
|
|
15672
|
+
*/
|
|
15673
|
+
getSigned() {
|
|
15674
|
+
return this.i32[U32_INDEX];
|
|
15675
|
+
}
|
|
15724
15676
|
|
|
15725
|
-
|
|
15726
|
-
|
|
15677
|
+
getU32(): number {
|
|
15678
|
+
return this.u32[U32_INDEX];
|
|
15679
|
+
}
|
|
15727
15680
|
|
|
15728
|
-
|
|
15729
|
-
|
|
15730
|
-
|
|
15731
|
-
const destinationStartIndex = currentPosition - startAddress;
|
|
15732
|
-
const destination = result.subarray(destinationStartIndex);
|
|
15681
|
+
getI32(): number {
|
|
15682
|
+
return this.i32[U32_INDEX];
|
|
15683
|
+
}
|
|
15733
15684
|
|
|
15734
|
-
|
|
15685
|
+
getU64(): bigint {
|
|
15686
|
+
return this.u64[U64_INDEX];
|
|
15687
|
+
}
|
|
15735
15688
|
|
|
15736
|
-
|
|
15737
|
-
|
|
15738
|
-
|
|
15689
|
+
getI64(): bigint {
|
|
15690
|
+
return this.i64[U64_INDEX];
|
|
15691
|
+
}
|
|
15739
15692
|
|
|
15740
|
-
|
|
15741
|
-
return
|
|
15693
|
+
getBytesAsLittleEndian() {
|
|
15694
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE);
|
|
15742
15695
|
}
|
|
15743
15696
|
|
|
15744
|
-
|
|
15745
|
-
|
|
15746
|
-
|
|
15697
|
+
getExtendedBytesAsLittleEndian() {
|
|
15698
|
+
return this.bytes;
|
|
15699
|
+
}
|
|
15700
|
+
}
|
|
15747
15701
|
|
|
15748
|
-
|
|
15749
|
-
|
|
15750
|
-
throw new OutOfMemory();
|
|
15751
|
-
}
|
|
15702
|
+
declare class NibblesDecoder {
|
|
15703
|
+
private byte = new Int8Array(1);
|
|
15752
15704
|
|
|
15753
|
-
|
|
15705
|
+
setByte(byte: number) {
|
|
15706
|
+
this.byte[0] = byte;
|
|
15707
|
+
}
|
|
15754
15708
|
|
|
15755
|
-
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
return currentVirtualSbrkIndex;
|
|
15759
|
-
}
|
|
15709
|
+
getHighNibble() {
|
|
15710
|
+
return (this.byte[0] & 0xf0) >>> 4;
|
|
15711
|
+
}
|
|
15760
15712
|
|
|
15761
|
-
|
|
15762
|
-
|
|
15763
|
-
|
|
15764
|
-
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15765
|
-
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE;
|
|
15766
|
-
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
15713
|
+
getLowNibble() {
|
|
15714
|
+
return this.byte[0] & 0x0f;
|
|
15715
|
+
}
|
|
15767
15716
|
|
|
15768
|
-
|
|
15769
|
-
|
|
15770
|
-
|
|
15771
|
-
}
|
|
15717
|
+
getHighNibbleAsRegisterIndex() {
|
|
15718
|
+
return Math.min(this.getHighNibble(), MAX_REGISTER_INDEX);
|
|
15719
|
+
}
|
|
15772
15720
|
|
|
15773
|
-
|
|
15774
|
-
this.
|
|
15775
|
-
return currentVirtualSbrkIndex;
|
|
15721
|
+
getLowNibbleAsRegisterIndex() {
|
|
15722
|
+
return Math.min(this.getLowNibble(), MAX_REGISTER_INDEX);
|
|
15776
15723
|
}
|
|
15777
15724
|
|
|
15778
|
-
|
|
15779
|
-
|
|
15780
|
-
return page?.getPageDump() ?? null;
|
|
15725
|
+
getHighNibbleAsLength() {
|
|
15726
|
+
return Math.min(this.getHighNibble(), MAX_LENGTH);
|
|
15781
15727
|
}
|
|
15782
15728
|
|
|
15783
|
-
|
|
15784
|
-
return this.
|
|
15729
|
+
getLowNibbleAsLength() {
|
|
15730
|
+
return Math.min(this.getLowNibble(), MAX_LENGTH);
|
|
15785
15731
|
}
|
|
15786
15732
|
}
|
|
15787
15733
|
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
|
|
15791
|
-
|
|
15792
|
-
private ensureNotFinalized() {
|
|
15793
|
-
if (this.isFinalized) {
|
|
15794
|
-
throw new FinalizedBuilderModification();
|
|
15795
|
-
}
|
|
15796
|
-
}
|
|
15734
|
+
type EmptyArgs = {
|
|
15735
|
+
type: ArgumentType.NO_ARGUMENTS;
|
|
15736
|
+
noOfBytesToSkip: number;
|
|
15737
|
+
};
|
|
15797
15738
|
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
|
|
15801
|
-
|
|
15802
|
-
|
|
15739
|
+
type OneImmediateArgs = {
|
|
15740
|
+
type: ArgumentType.ONE_IMMEDIATE;
|
|
15741
|
+
noOfBytesToSkip: number;
|
|
15742
|
+
/** V_X */
|
|
15743
|
+
immediateDecoder: ImmediateDecoder;
|
|
15744
|
+
};
|
|
15803
15745
|
|
|
15804
|
-
|
|
15805
|
-
|
|
15806
|
-
|
|
15807
|
-
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
this.ensureNotFinalized();
|
|
15815
|
-
check`${start < end} end has to be bigger than start`;
|
|
15816
|
-
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15817
|
-
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15818
|
-
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15746
|
+
type ThreeRegistersArgs = {
|
|
15747
|
+
type: ArgumentType.THREE_REGISTERS;
|
|
15748
|
+
noOfBytesToSkip: number;
|
|
15749
|
+
/** W_A */
|
|
15750
|
+
firstRegisterIndex: number;
|
|
15751
|
+
/** W_B */
|
|
15752
|
+
secondRegisterIndex: number;
|
|
15753
|
+
/** W_D */
|
|
15754
|
+
thirdRegisterIndex: number;
|
|
15755
|
+
};
|
|
15819
15756
|
|
|
15820
|
-
|
|
15821
|
-
|
|
15757
|
+
type TwoRegistersArgs = {
|
|
15758
|
+
type: ArgumentType.TWO_REGISTERS;
|
|
15759
|
+
noOfBytesToSkip: number;
|
|
15760
|
+
/** W_A */
|
|
15761
|
+
firstRegisterIndex: number;
|
|
15762
|
+
/** W_D */
|
|
15763
|
+
secondRegisterIndex: number;
|
|
15764
|
+
};
|
|
15822
15765
|
|
|
15823
|
-
|
|
15766
|
+
type TwoRegistersOneImmediateArgs = {
|
|
15767
|
+
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15768
|
+
noOfBytesToSkip: number;
|
|
15769
|
+
/** W_A */
|
|
15770
|
+
firstRegisterIndex: number;
|
|
15771
|
+
/** W_B */
|
|
15772
|
+
secondRegisterIndex: number;
|
|
15773
|
+
/** V_X */
|
|
15774
|
+
immediateDecoder: ImmediateDecoder;
|
|
15775
|
+
};
|
|
15824
15776
|
|
|
15825
|
-
|
|
15826
|
-
|
|
15777
|
+
type OneRegisterOneImmediateArgs = {
|
|
15778
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15779
|
+
noOfBytesToSkip: number;
|
|
15780
|
+
/** W_A */
|
|
15781
|
+
registerIndex: number;
|
|
15782
|
+
/** V_X */
|
|
15783
|
+
immediateDecoder: ImmediateDecoder;
|
|
15784
|
+
};
|
|
15827
15785
|
|
|
15828
|
-
|
|
15829
|
-
|
|
15830
|
-
|
|
15831
|
-
|
|
15832
|
-
|
|
15833
|
-
|
|
15786
|
+
type OneRegisterOneExtendedWidthImmediateArgs = {
|
|
15787
|
+
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
15788
|
+
noOfBytesToSkip: number;
|
|
15789
|
+
/** W_A */
|
|
15790
|
+
registerIndex: number;
|
|
15791
|
+
/** V_X */
|
|
15792
|
+
immediateDecoder: ExtendedWitdthImmediateDecoder;
|
|
15793
|
+
};
|
|
15834
15794
|
|
|
15835
|
-
|
|
15836
|
-
|
|
15795
|
+
type TwoRegistersTwoImmediatesArgs = {
|
|
15796
|
+
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
15797
|
+
noOfBytesToSkip: number;
|
|
15798
|
+
/** W_A */
|
|
15799
|
+
firstRegisterIndex: number;
|
|
15800
|
+
/** W_B */
|
|
15801
|
+
secondRegisterIndex: number;
|
|
15802
|
+
/** V_X */
|
|
15803
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15804
|
+
/** V_Y */
|
|
15805
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15806
|
+
};
|
|
15837
15807
|
|
|
15838
|
-
|
|
15839
|
-
|
|
15840
|
-
|
|
15841
|
-
|
|
15842
|
-
|
|
15843
|
-
|
|
15844
|
-
|
|
15845
|
-
|
|
15846
|
-
*/
|
|
15847
|
-
setWriteablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15848
|
-
this.ensureNotFinalized();
|
|
15849
|
-
check`${start < end} end has to be bigger than start`;
|
|
15850
|
-
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15851
|
-
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15852
|
-
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15808
|
+
type TwoImmediatesArgs = {
|
|
15809
|
+
type: ArgumentType.TWO_IMMEDIATES;
|
|
15810
|
+
noOfBytesToSkip: number;
|
|
15811
|
+
/** V_X */
|
|
15812
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15813
|
+
/** V_Y */
|
|
15814
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15815
|
+
};
|
|
15853
15816
|
|
|
15854
|
-
|
|
15855
|
-
|
|
15817
|
+
type TwoRegistersOneOffsetArgs = {
|
|
15818
|
+
type: ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15819
|
+
noOfBytesToSkip: number;
|
|
15820
|
+
/** W_A */
|
|
15821
|
+
firstRegisterIndex: number;
|
|
15822
|
+
/** W_B */
|
|
15823
|
+
secondRegisterIndex: number;
|
|
15824
|
+
nextPc: number;
|
|
15825
|
+
};
|
|
15856
15826
|
|
|
15857
|
-
|
|
15827
|
+
type OneRegisterOneImmediateOneOffsetArgs = {
|
|
15828
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15829
|
+
noOfBytesToSkip: number;
|
|
15830
|
+
/** W_A */
|
|
15831
|
+
registerIndex: number;
|
|
15832
|
+
/** V_X */
|
|
15833
|
+
immediateDecoder: ImmediateDecoder;
|
|
15834
|
+
/** V_Y */
|
|
15835
|
+
nextPc: number;
|
|
15836
|
+
};
|
|
15858
15837
|
|
|
15859
|
-
|
|
15860
|
-
|
|
15838
|
+
type OneRegisterTwoImmediatesArgs = {
|
|
15839
|
+
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15840
|
+
noOfBytesToSkip: number;
|
|
15841
|
+
/** W_A */
|
|
15842
|
+
registerIndex: number;
|
|
15843
|
+
/** V_X */
|
|
15844
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15845
|
+
/** V_Y */
|
|
15846
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15847
|
+
};
|
|
15861
15848
|
|
|
15862
|
-
|
|
15863
|
-
|
|
15864
|
-
|
|
15865
|
-
|
|
15866
|
-
|
|
15867
|
-
|
|
15849
|
+
type OneOffsetArgs = {
|
|
15850
|
+
type: ArgumentType.ONE_OFFSET;
|
|
15851
|
+
noOfBytesToSkip: number;
|
|
15852
|
+
/** V_X */
|
|
15853
|
+
nextPc: number;
|
|
15854
|
+
};
|
|
15868
15855
|
|
|
15869
|
-
|
|
15856
|
+
type Args =
|
|
15857
|
+
| EmptyArgs
|
|
15858
|
+
| OneImmediateArgs
|
|
15859
|
+
| TwoRegistersArgs
|
|
15860
|
+
| ThreeRegistersArgs
|
|
15861
|
+
| TwoRegistersOneImmediateArgs
|
|
15862
|
+
| TwoRegistersTwoImmediatesArgs
|
|
15863
|
+
| OneRegisterOneImmediateOneOffsetArgs
|
|
15864
|
+
| TwoRegistersOneOffsetArgs
|
|
15865
|
+
| OneRegisterOneImmediateArgs
|
|
15866
|
+
| OneOffsetArgs
|
|
15867
|
+
| TwoImmediatesArgs
|
|
15868
|
+
| OneRegisterTwoImmediatesArgs
|
|
15869
|
+
| OneRegisterOneExtendedWidthImmediateArgs;
|
|
15870
|
+
|
|
15871
|
+
declare class ArgsDecoder {
|
|
15872
|
+
private nibblesDecoder = new NibblesDecoder();
|
|
15873
|
+
private offsetDecoder = new ImmediateDecoder();
|
|
15874
|
+
private code: Uint8Array = new Uint8Array();
|
|
15875
|
+
private mask: Mask = Mask.empty();
|
|
15876
|
+
|
|
15877
|
+
reset(code: Uint8Array, mask: Mask) {
|
|
15878
|
+
this.code = code;
|
|
15879
|
+
this.mask = mask;
|
|
15870
15880
|
}
|
|
15871
15881
|
|
|
15872
|
-
|
|
15873
|
-
|
|
15874
|
-
|
|
15875
|
-
*/
|
|
15876
|
-
setData(start: MemoryIndex, data: Uint8Array) {
|
|
15877
|
-
this.ensureNotFinalized();
|
|
15878
|
-
const pageOffset = start % PAGE_SIZE;
|
|
15879
|
-
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15880
|
-
check`${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15882
|
+
fillArgs<T extends Args>(pc: number, result: T): void {
|
|
15883
|
+
const nextInstructionDistance = 1 + this.mask.getNoOfBytesToNextInstruction(pc + 1);
|
|
15884
|
+
result.noOfBytesToSkip = nextInstructionDistance;
|
|
15881
15885
|
|
|
15882
|
-
|
|
15883
|
-
|
|
15886
|
+
switch (result.type) {
|
|
15887
|
+
case ArgumentType.NO_ARGUMENTS:
|
|
15888
|
+
break;
|
|
15889
|
+
|
|
15890
|
+
case ArgumentType.ONE_IMMEDIATE: {
|
|
15891
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
15892
|
+
const argsStartIndex = pc + 1;
|
|
15893
|
+
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
15894
|
+
break;
|
|
15895
|
+
}
|
|
15896
|
+
|
|
15897
|
+
case ArgumentType.THREE_REGISTERS: {
|
|
15898
|
+
const firstByte = this.code[pc + 1];
|
|
15899
|
+
const secondByte = this.code[pc + 2];
|
|
15900
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15901
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15902
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15903
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
15904
|
+
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15905
|
+
break;
|
|
15906
|
+
}
|
|
15907
|
+
|
|
15908
|
+
case ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE: {
|
|
15909
|
+
const firstByte = this.code[pc + 1];
|
|
15910
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15911
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15912
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15913
|
+
|
|
15914
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15915
|
+
const immediateStartIndex = pc + 2;
|
|
15916
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15917
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
15918
|
+
break;
|
|
15919
|
+
}
|
|
15920
|
+
|
|
15921
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET: {
|
|
15922
|
+
const firstByte = this.code[pc + 1];
|
|
15923
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15924
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15925
|
+
|
|
15926
|
+
const immediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
15927
|
+
const immediateStartIndex = pc + 2;
|
|
15928
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15929
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
15930
|
+
|
|
15931
|
+
const offsetLength = Math.min(
|
|
15932
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
15933
|
+
Math.max(0, nextInstructionDistance - 2 - immediateLength),
|
|
15934
|
+
);
|
|
15935
|
+
const offsetStartIndex = pc + 2 + immediateLength;
|
|
15936
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15937
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15938
|
+
|
|
15939
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
15940
|
+
break;
|
|
15941
|
+
}
|
|
15942
|
+
|
|
15943
|
+
case ArgumentType.TWO_REGISTERS_ONE_OFFSET: {
|
|
15944
|
+
const firstByte = this.code[pc + 1];
|
|
15945
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15946
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15947
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15948
|
+
|
|
15949
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15950
|
+
const offsetStartIndex = pc + 2;
|
|
15951
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15952
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15953
|
+
|
|
15954
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
15955
|
+
break;
|
|
15956
|
+
}
|
|
15957
|
+
|
|
15958
|
+
case ArgumentType.TWO_REGISTERS: {
|
|
15959
|
+
const firstByte = this.code[pc + 1];
|
|
15960
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15961
|
+
result.firstRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15962
|
+
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15963
|
+
break;
|
|
15964
|
+
}
|
|
15965
|
+
|
|
15966
|
+
case ArgumentType.ONE_OFFSET: {
|
|
15967
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
15968
|
+
const offsetStartIndex = pc + 1;
|
|
15969
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15970
|
+
const offsetBytes = this.code.subarray(offsetStartIndex, offsetEndIndex);
|
|
15971
|
+
this.offsetDecoder.setBytes(offsetBytes);
|
|
15972
|
+
const offsetValue = this.offsetDecoder.getSigned();
|
|
15973
|
+
result.nextPc = pc + offsetValue;
|
|
15974
|
+
break;
|
|
15975
|
+
}
|
|
15976
|
+
|
|
15977
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE: {
|
|
15978
|
+
const firstByte = this.code[pc + 1];
|
|
15979
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15980
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15981
|
+
|
|
15982
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15983
|
+
const immediateStartIndex = pc + 2;
|
|
15984
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15985
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
15986
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
15987
|
+
break;
|
|
15988
|
+
}
|
|
15989
|
+
|
|
15990
|
+
case ArgumentType.TWO_IMMEDIATES: {
|
|
15991
|
+
const firstByte = this.code[pc + 1];
|
|
15992
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15993
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
15994
|
+
const firstImmediateStartIndex = pc + 2;
|
|
15995
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
15996
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
15997
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15998
|
+
|
|
15999
|
+
const secondImmediateLength = Math.min(
|
|
16000
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
16001
|
+
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
16002
|
+
);
|
|
16003
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
16004
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
16005
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
16006
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
16007
|
+
break;
|
|
16008
|
+
}
|
|
16009
|
+
|
|
16010
|
+
case ArgumentType.ONE_REGISTER_TWO_IMMEDIATES: {
|
|
16011
|
+
const firstByte = this.code[pc + 1];
|
|
16012
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
16013
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
16014
|
+
|
|
16015
|
+
const firstImmediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
16016
|
+
const firstImmediateStartIndex = pc + 2;
|
|
16017
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
16018
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
16019
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
16020
|
+
|
|
16021
|
+
const secondImmediateLength = Math.min(
|
|
16022
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
16023
|
+
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
16024
|
+
);
|
|
16025
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
16026
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
16027
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
16028
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
16029
|
+
break;
|
|
16030
|
+
}
|
|
16031
|
+
|
|
16032
|
+
case ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES: {
|
|
16033
|
+
const firstByte = this.code[pc + 1];
|
|
16034
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
16035
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
16036
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
16037
|
+
|
|
16038
|
+
const secondByte = this.code[pc + 2];
|
|
16039
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
16040
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
16041
|
+
const firstImmediateStartIndex = pc + 3;
|
|
16042
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
16043
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
16044
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
16045
|
+
|
|
16046
|
+
const secondImmediateLength = Math.min(
|
|
16047
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
16048
|
+
Math.max(0, nextInstructionDistance - 3 - firstImmediateLength),
|
|
16049
|
+
);
|
|
16050
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
16051
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
16052
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
16053
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
16054
|
+
break;
|
|
16055
|
+
}
|
|
16056
|
+
|
|
16057
|
+
case ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE: {
|
|
16058
|
+
const firstByte = this.code[pc + 1];
|
|
16059
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
16060
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
16061
|
+
|
|
16062
|
+
const immediateStartIndex = pc + 2;
|
|
16063
|
+
const immediateEndIndex = immediateStartIndex + 8;
|
|
16064
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
16065
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
16066
|
+
break;
|
|
16067
|
+
}
|
|
16068
|
+
}
|
|
16069
|
+
}
|
|
16070
|
+
}
|
|
16071
|
+
|
|
16072
|
+
declare const createResults = () => {
|
|
16073
|
+
const results = new Array(ARGUMENT_TYPE_LENGTH) as Results;
|
|
16074
|
+
|
|
16075
|
+
results[ArgumentType.NO_ARGUMENTS] = {
|
|
16076
|
+
type: ArgumentType.NO_ARGUMENTS,
|
|
16077
|
+
noOfBytesToSkip: 1,
|
|
16078
|
+
};
|
|
16079
|
+
|
|
16080
|
+
results[ArgumentType.ONE_IMMEDIATE] = {
|
|
16081
|
+
type: ArgumentType.ONE_IMMEDIATE,
|
|
16082
|
+
noOfBytesToSkip: 1,
|
|
16083
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16084
|
+
};
|
|
16085
|
+
|
|
16086
|
+
results[ArgumentType.TWO_REGISTERS] = {
|
|
16087
|
+
type: ArgumentType.TWO_REGISTERS,
|
|
16088
|
+
noOfBytesToSkip: 1,
|
|
16089
|
+
firstRegisterIndex: 0,
|
|
16090
|
+
secondRegisterIndex: 0,
|
|
16091
|
+
};
|
|
16092
|
+
|
|
16093
|
+
results[ArgumentType.THREE_REGISTERS] = {
|
|
16094
|
+
type: ArgumentType.THREE_REGISTERS,
|
|
16095
|
+
noOfBytesToSkip: 1,
|
|
16096
|
+
firstRegisterIndex: 0,
|
|
16097
|
+
secondRegisterIndex: 0,
|
|
16098
|
+
thirdRegisterIndex: 0,
|
|
16099
|
+
};
|
|
16100
|
+
|
|
16101
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET] = {
|
|
16102
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET,
|
|
16103
|
+
noOfBytesToSkip: 1,
|
|
16104
|
+
registerIndex: 0,
|
|
16105
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16106
|
+
nextPc: 0,
|
|
16107
|
+
};
|
|
16108
|
+
|
|
16109
|
+
results[ArgumentType.TWO_REGISTERS_ONE_OFFSET] = {
|
|
16110
|
+
type: ArgumentType.TWO_REGISTERS_ONE_OFFSET,
|
|
16111
|
+
noOfBytesToSkip: 1,
|
|
16112
|
+
firstRegisterIndex: 0,
|
|
16113
|
+
secondRegisterIndex: 0,
|
|
16114
|
+
nextPc: 0,
|
|
16115
|
+
};
|
|
16116
|
+
|
|
16117
|
+
results[ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE] = {
|
|
16118
|
+
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE,
|
|
16119
|
+
noOfBytesToSkip: 1,
|
|
16120
|
+
firstRegisterIndex: 0,
|
|
16121
|
+
secondRegisterIndex: 0,
|
|
16122
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16123
|
+
};
|
|
16124
|
+
|
|
16125
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE] = {
|
|
16126
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE,
|
|
16127
|
+
noOfBytesToSkip: 1,
|
|
16128
|
+
registerIndex: 0,
|
|
16129
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16130
|
+
};
|
|
16131
|
+
|
|
16132
|
+
results[ArgumentType.ONE_REGISTER_TWO_IMMEDIATES] = {
|
|
16133
|
+
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES,
|
|
16134
|
+
noOfBytesToSkip: 1,
|
|
16135
|
+
registerIndex: 0,
|
|
16136
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16137
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16138
|
+
};
|
|
16139
|
+
|
|
16140
|
+
results[ArgumentType.ONE_OFFSET] = {
|
|
16141
|
+
type: ArgumentType.ONE_OFFSET,
|
|
16142
|
+
noOfBytesToSkip: 1,
|
|
16143
|
+
nextPc: 0,
|
|
16144
|
+
};
|
|
16145
|
+
|
|
16146
|
+
results[ArgumentType.TWO_IMMEDIATES] = {
|
|
16147
|
+
type: ArgumentType.TWO_IMMEDIATES,
|
|
16148
|
+
noOfBytesToSkip: 1,
|
|
16149
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16150
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16151
|
+
};
|
|
16152
|
+
|
|
16153
|
+
results[ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES] = {
|
|
16154
|
+
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES,
|
|
16155
|
+
noOfBytesToSkip: 1,
|
|
16156
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16157
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16158
|
+
firstRegisterIndex: 0,
|
|
16159
|
+
secondRegisterIndex: 0,
|
|
16160
|
+
};
|
|
16161
|
+
|
|
16162
|
+
results[ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE] = {
|
|
16163
|
+
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE,
|
|
16164
|
+
noOfBytesToSkip: 9,
|
|
16165
|
+
registerIndex: 0,
|
|
16166
|
+
immediateDecoder: new ExtendedWitdthImmediateDecoder(),
|
|
16167
|
+
};
|
|
16168
|
+
|
|
16169
|
+
return results;
|
|
16170
|
+
};
|
|
16171
|
+
|
|
16172
|
+
declare enum Instruction {
|
|
16173
|
+
TRAP = 0,
|
|
16174
|
+
FALLTHROUGH = 1,
|
|
16175
|
+
ECALLI = 10,
|
|
16176
|
+
LOAD_IMM_64 = 20,
|
|
16177
|
+
STORE_IMM_U8 = 30,
|
|
16178
|
+
STORE_IMM_U16 = 31,
|
|
16179
|
+
STORE_IMM_U32 = 32,
|
|
16180
|
+
STORE_IMM_U64 = 33,
|
|
16181
|
+
JUMP = 40,
|
|
16182
|
+
JUMP_IND = 50,
|
|
16183
|
+
LOAD_IMM = 51,
|
|
16184
|
+
LOAD_U8 = 52,
|
|
16185
|
+
LOAD_I8 = 53,
|
|
16186
|
+
LOAD_U16 = 54,
|
|
16187
|
+
LOAD_I16 = 55,
|
|
16188
|
+
LOAD_U32 = 56,
|
|
16189
|
+
LOAD_I32 = 57,
|
|
16190
|
+
LOAD_U64 = 58,
|
|
16191
|
+
STORE_U8 = 59,
|
|
16192
|
+
STORE_U16 = 60,
|
|
16193
|
+
STORE_U32 = 61,
|
|
16194
|
+
STORE_U64 = 62,
|
|
16195
|
+
STORE_IMM_IND_U8 = 70,
|
|
16196
|
+
STORE_IMM_IND_U16 = 71,
|
|
16197
|
+
STORE_IMM_IND_U32 = 72,
|
|
16198
|
+
STORE_IMM_IND_U64 = 73,
|
|
16199
|
+
LOAD_IMM_JUMP = 80,
|
|
16200
|
+
BRANCH_EQ_IMM = 81,
|
|
16201
|
+
BRANCH_NE_IMM = 82,
|
|
16202
|
+
BRANCH_LT_U_IMM = 83,
|
|
16203
|
+
BRANCH_LE_U_IMM = 84,
|
|
16204
|
+
BRANCH_GE_U_IMM = 85,
|
|
16205
|
+
BRANCH_GT_U_IMM = 86,
|
|
16206
|
+
BRANCH_LT_S_IMM = 87,
|
|
16207
|
+
BRANCH_LE_S_IMM = 88,
|
|
16208
|
+
BRANCH_GE_S_IMM = 89,
|
|
16209
|
+
BRANCH_GT_S_IMM = 90,
|
|
16210
|
+
MOVE_REG = 100,
|
|
16211
|
+
SBRK = 101,
|
|
16212
|
+
COUNT_SET_BITS_64 = 102,
|
|
16213
|
+
COUNT_SET_BITS_32 = 103,
|
|
16214
|
+
LEADING_ZERO_BITS_64 = 104,
|
|
16215
|
+
LEADING_ZERO_BITS_32 = 105,
|
|
16216
|
+
TRAILING_ZERO_BITS_64 = 106,
|
|
16217
|
+
TRAILING_ZERO_BITS_32 = 107,
|
|
16218
|
+
SIGN_EXTEND_8 = 108,
|
|
16219
|
+
SIGN_EXTEND_16 = 109,
|
|
16220
|
+
ZERO_EXTEND_16 = 110,
|
|
16221
|
+
REVERSE_BYTES = 111,
|
|
16222
|
+
STORE_IND_U8 = 120,
|
|
16223
|
+
STORE_IND_U16 = 121,
|
|
16224
|
+
STORE_IND_U32 = 122,
|
|
16225
|
+
STORE_IND_U64 = 123,
|
|
16226
|
+
LOAD_IND_U8 = 124,
|
|
16227
|
+
LOAD_IND_I8 = 125,
|
|
16228
|
+
LOAD_IND_U16 = 126,
|
|
16229
|
+
LOAD_IND_I16 = 127,
|
|
16230
|
+
LOAD_IND_U32 = 128,
|
|
16231
|
+
LOAD_IND_I32 = 129,
|
|
16232
|
+
LOAD_IND_U64 = 130,
|
|
16233
|
+
ADD_IMM_32 = 131,
|
|
16234
|
+
AND_IMM = 132,
|
|
16235
|
+
XOR_IMM = 133,
|
|
16236
|
+
OR_IMM = 134,
|
|
16237
|
+
MUL_IMM_32 = 135,
|
|
16238
|
+
SET_LT_U_IMM = 136,
|
|
16239
|
+
SET_LT_S_IMM = 137,
|
|
16240
|
+
SHLO_L_IMM_32 = 138,
|
|
16241
|
+
SHLO_R_IMM_32 = 139,
|
|
16242
|
+
SHAR_R_IMM_32 = 140,
|
|
16243
|
+
NEG_ADD_IMM_32 = 141,
|
|
16244
|
+
SET_GT_U_IMM = 142,
|
|
16245
|
+
SET_GT_S_IMM = 143,
|
|
16246
|
+
SHLO_L_IMM_ALT_32 = 144,
|
|
16247
|
+
SHLO_R_IMM_ALT_32 = 145,
|
|
16248
|
+
SHAR_R_IMM_ALT_32 = 146,
|
|
16249
|
+
CMOV_IZ_IMM = 147,
|
|
16250
|
+
CMOV_NZ_IMM = 148,
|
|
16251
|
+
ADD_IMM_64 = 149,
|
|
16252
|
+
MUL_IMM_64 = 150,
|
|
16253
|
+
SHLO_L_IMM_64 = 151,
|
|
16254
|
+
SHLO_R_IMM_64 = 152,
|
|
16255
|
+
SHAR_R_IMM_64 = 153,
|
|
16256
|
+
NEG_ADD_IMM_64 = 154,
|
|
16257
|
+
SHLO_L_IMM_ALT_64 = 155,
|
|
16258
|
+
SHLO_R_IMM_ALT_64 = 156,
|
|
16259
|
+
SHAR_R_IMM_ALT_64 = 157,
|
|
16260
|
+
ROT_R_64_IMM = 158,
|
|
16261
|
+
ROT_R_64_IMM_ALT = 159,
|
|
16262
|
+
ROT_R_32_IMM = 160,
|
|
16263
|
+
ROT_R_32_IMM_ALT = 161,
|
|
16264
|
+
BRANCH_EQ = 170,
|
|
16265
|
+
BRANCH_NE = 171,
|
|
16266
|
+
BRANCH_LT_U = 172,
|
|
16267
|
+
BRANCH_LT_S = 173,
|
|
16268
|
+
BRANCH_GE_U = 174,
|
|
16269
|
+
BRANCH_GE_S = 175,
|
|
16270
|
+
LOAD_IMM_JUMP_IND = 180,
|
|
16271
|
+
ADD_32 = 190,
|
|
16272
|
+
SUB_32 = 191,
|
|
16273
|
+
MUL_32 = 192,
|
|
16274
|
+
DIV_U_32 = 193,
|
|
16275
|
+
DIV_S_32 = 194,
|
|
16276
|
+
REM_U_32 = 195,
|
|
16277
|
+
REM_S_32 = 196,
|
|
16278
|
+
SHLO_L_32 = 197,
|
|
16279
|
+
SHLO_R_32 = 198,
|
|
16280
|
+
SHAR_R_32 = 199,
|
|
16281
|
+
ADD_64 = 200,
|
|
16282
|
+
SUB_64 = 201,
|
|
16283
|
+
MUL_64 = 202,
|
|
16284
|
+
DIV_U_64 = 203,
|
|
16285
|
+
DIV_S_64 = 204,
|
|
16286
|
+
REM_U_64 = 205,
|
|
16287
|
+
REM_S_64 = 206,
|
|
16288
|
+
SHLO_L_64 = 207,
|
|
16289
|
+
SHLO_R_64 = 208,
|
|
16290
|
+
SHAR_R_64 = 209,
|
|
16291
|
+
AND = 210,
|
|
16292
|
+
XOR = 211,
|
|
16293
|
+
OR = 212,
|
|
16294
|
+
MUL_UPPER_S_S = 213,
|
|
16295
|
+
MUL_UPPER_U_U = 214,
|
|
16296
|
+
MUL_UPPER_S_U = 215,
|
|
16297
|
+
SET_LT_U = 216,
|
|
16298
|
+
SET_LT_S = 217,
|
|
16299
|
+
CMOV_IZ = 218,
|
|
16300
|
+
CMOV_NZ = 219,
|
|
16301
|
+
ROT_L_64 = 220,
|
|
16302
|
+
ROT_L_32 = 221,
|
|
16303
|
+
ROT_R_64 = 222,
|
|
16304
|
+
ROT_R_32 = 223,
|
|
16305
|
+
AND_INV = 224,
|
|
16306
|
+
OR_INV = 225,
|
|
16307
|
+
XNOR = 226,
|
|
16308
|
+
MAX = 227,
|
|
16309
|
+
MAX_U = 228,
|
|
16310
|
+
MIN = 229,
|
|
16311
|
+
MIN_U = 230,
|
|
16312
|
+
}
|
|
16313
|
+
|
|
16314
|
+
declare const instructionArgumentTypeMap = (() => {
|
|
16315
|
+
const instructionArgumentTypeMap = new Array<ArgumentType>(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
16316
|
+
|
|
16317
|
+
instructionArgumentTypeMap[Instruction.TRAP] = ArgumentType.NO_ARGUMENTS;
|
|
16318
|
+
instructionArgumentTypeMap[Instruction.FALLTHROUGH] = ArgumentType.NO_ARGUMENTS;
|
|
16319
|
+
|
|
16320
|
+
instructionArgumentTypeMap[Instruction.ECALLI] = ArgumentType.ONE_IMMEDIATE;
|
|
16321
|
+
|
|
16322
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_64] = ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
16323
|
+
|
|
16324
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U8] = ArgumentType.TWO_IMMEDIATES;
|
|
16325
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U16] = ArgumentType.TWO_IMMEDIATES;
|
|
16326
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U32] = ArgumentType.TWO_IMMEDIATES;
|
|
16327
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U64] = ArgumentType.TWO_IMMEDIATES;
|
|
16328
|
+
|
|
16329
|
+
instructionArgumentTypeMap[Instruction.JUMP] = ArgumentType.ONE_OFFSET;
|
|
16330
|
+
|
|
16331
|
+
instructionArgumentTypeMap[Instruction.JUMP_IND] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16332
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16333
|
+
instructionArgumentTypeMap[Instruction.LOAD_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16334
|
+
instructionArgumentTypeMap[Instruction.LOAD_I8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16335
|
+
instructionArgumentTypeMap[Instruction.LOAD_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16336
|
+
instructionArgumentTypeMap[Instruction.LOAD_I16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16337
|
+
instructionArgumentTypeMap[Instruction.LOAD_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16338
|
+
instructionArgumentTypeMap[Instruction.LOAD_I32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16339
|
+
instructionArgumentTypeMap[Instruction.LOAD_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16340
|
+
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16341
|
+
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16342
|
+
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16343
|
+
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16344
|
+
|
|
16345
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U8] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16346
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U16] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16347
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16348
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16349
|
+
|
|
16350
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16351
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16352
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16353
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16354
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16355
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16356
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16357
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16358
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16359
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16360
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16361
|
+
|
|
16362
|
+
instructionArgumentTypeMap[Instruction.MOVE_REG] = ArgumentType.TWO_REGISTERS;
|
|
16363
|
+
instructionArgumentTypeMap[Instruction.SBRK] = ArgumentType.TWO_REGISTERS;
|
|
16364
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16365
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16366
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16367
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16368
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16369
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16370
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_8] = ArgumentType.TWO_REGISTERS;
|
|
16371
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
16372
|
+
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
16373
|
+
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
16374
|
+
|
|
16375
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16376
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16377
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16378
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16379
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16380
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16381
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16382
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16383
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16384
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16385
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16386
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16387
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16388
|
+
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16389
|
+
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16390
|
+
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16391
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16392
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16393
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16394
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16395
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16396
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16397
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16398
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16399
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16400
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16401
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16402
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16403
|
+
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16404
|
+
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16405
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16406
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16407
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16408
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16409
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16410
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16411
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16412
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16413
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16414
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16415
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16416
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15884
16417
|
|
|
15885
|
-
|
|
16418
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16419
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16420
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16421
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16422
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16423
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15886
16424
|
|
|
15887
|
-
|
|
15888
|
-
const page = this.initialMemory.get(pageNumber);
|
|
16425
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP_IND] = ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
15889
16426
|
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
16427
|
+
instructionArgumentTypeMap[Instruction.ADD_32] = ArgumentType.THREE_REGISTERS;
|
|
16428
|
+
instructionArgumentTypeMap[Instruction.ADD_64] = ArgumentType.THREE_REGISTERS;
|
|
16429
|
+
instructionArgumentTypeMap[Instruction.SUB_32] = ArgumentType.THREE_REGISTERS;
|
|
16430
|
+
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
16431
|
+
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
16432
|
+
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
16433
|
+
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
16434
|
+
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
16435
|
+
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
16436
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
16437
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
16438
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
16439
|
+
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
16440
|
+
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
16441
|
+
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
16442
|
+
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
16443
|
+
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
16444
|
+
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
16445
|
+
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
16446
|
+
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
16447
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
16448
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
16449
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
16450
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16451
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16452
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
16453
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16454
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16455
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
16456
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
16457
|
+
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
16458
|
+
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
16459
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16460
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16461
|
+
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
16462
|
+
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
16463
|
+
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
16464
|
+
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
16465
|
+
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
16466
|
+
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
16467
|
+
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
15893
16468
|
|
|
15894
|
-
|
|
15895
|
-
|
|
16469
|
+
return instructionArgumentTypeMap;
|
|
16470
|
+
})();
|
|
15896
16471
|
|
|
15897
|
-
|
|
15898
|
-
|
|
16472
|
+
declare class BasicBlocks {
|
|
16473
|
+
private basicBlocks: Set<number> = new Set();
|
|
15899
16474
|
|
|
15900
|
-
|
|
15901
|
-
|
|
15902
|
-
|
|
15903
|
-
|
|
15904
|
-
`;
|
|
15905
|
-
this.ensureNotFinalized();
|
|
16475
|
+
reset(code: Uint8Array, mask: Mask) {
|
|
16476
|
+
this.basicBlocks.clear();
|
|
16477
|
+
this.basicBlocks.add(0);
|
|
16478
|
+
const codeLength = code.length;
|
|
15906
16479
|
|
|
15907
|
-
const
|
|
15908
|
-
|
|
15909
|
-
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
16480
|
+
const isBasicBlockTermination = (index: number) =>
|
|
16481
|
+
mask.isInstruction(index) && terminationInstructions[code[index]];
|
|
15910
16482
|
|
|
15911
|
-
for (
|
|
15912
|
-
if (
|
|
15913
|
-
|
|
16483
|
+
for (let i = 0; i < codeLength; i++) {
|
|
16484
|
+
if (mask.isInstruction(i) && isBasicBlockTermination(i)) {
|
|
16485
|
+
this.basicBlocks.add(i + 1 + mask.getNoOfBytesToNextInstruction(i + 1));
|
|
15914
16486
|
}
|
|
15915
16487
|
}
|
|
16488
|
+
}
|
|
15916
16489
|
|
|
15917
|
-
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
});
|
|
16490
|
+
isBeginningOfBasicBlock(index: number) {
|
|
16491
|
+
return this.basicBlocks.has(index);
|
|
16492
|
+
}
|
|
16493
|
+
}
|
|
15922
16494
|
|
|
15923
|
-
|
|
15924
|
-
|
|
16495
|
+
declare enum Result {
|
|
16496
|
+
HALT = 0,
|
|
16497
|
+
PANIC = 1,
|
|
16498
|
+
FAULT_ACCESS = 2,
|
|
16499
|
+
FAULT = 3,
|
|
16500
|
+
HOST = 4,
|
|
16501
|
+
}
|
|
16502
|
+
|
|
16503
|
+
declare class InstructionResult {
|
|
16504
|
+
public nextPc = 0;
|
|
16505
|
+
public status: Result | null = null;
|
|
16506
|
+
/**
|
|
16507
|
+
* A numeric exit parameter of the PVM.
|
|
16508
|
+
*
|
|
16509
|
+
* In case of a `status === Result.FAULT` this will be the memory address
|
|
16510
|
+
* that triggered the fault.
|
|
16511
|
+
* In case of a `status === Result.HOST` this will be the host call index
|
|
16512
|
+
* that should be invoked.
|
|
16513
|
+
*
|
|
16514
|
+
* In any other circumstance the value should be `null`.
|
|
16515
|
+
*/
|
|
16516
|
+
public exitParam: number | null = null;
|
|
16517
|
+
|
|
16518
|
+
reset() {
|
|
16519
|
+
this.nextPc = 0;
|
|
16520
|
+
this.status = null;
|
|
16521
|
+
this.exitParam = null;
|
|
15925
16522
|
}
|
|
15926
16523
|
}
|
|
15927
16524
|
|
|
@@ -16906,7 +17503,7 @@ declare class StoreOps {
|
|
|
16906
17503
|
this.instructionResult.status = Result.FAULT_ACCESS;
|
|
16907
17504
|
} else {
|
|
16908
17505
|
this.instructionResult.status = Result.FAULT;
|
|
16909
|
-
this.instructionResult.exitParam = getStartPageIndex(storeResult.error.address);
|
|
17506
|
+
this.instructionResult.exitParam = getStartPageIndex(tryAsMemoryIndex(storeResult.error.address));
|
|
16910
17507
|
}
|
|
16911
17508
|
}
|
|
16912
17509
|
}
|
|
@@ -17707,34 +18304,20 @@ declare class ProgramDecoder {
|
|
|
17707
18304
|
}
|
|
17708
18305
|
}
|
|
17709
18306
|
|
|
17710
|
-
/**
|
|
17711
|
-
* Inner status codes for the PVM
|
|
17712
|
-
*
|
|
17713
|
-
* https://graypaper.fluffylabs.dev/#/85129da/2cae022cae02?v=0.6.3
|
|
17714
|
-
*/
|
|
17715
|
-
declare enum Status {
|
|
17716
|
-
OK = 255,
|
|
17717
|
-
HALT = 0,
|
|
17718
|
-
PANIC = 1,
|
|
17719
|
-
FAULT = 2,
|
|
17720
|
-
HOST = 3,
|
|
17721
|
-
OOG = 4,
|
|
17722
|
-
}
|
|
17723
|
-
|
|
17724
18307
|
type InterpreterOptions = {
|
|
17725
18308
|
useSbrkGas?: boolean;
|
|
17726
18309
|
};
|
|
17727
18310
|
|
|
17728
18311
|
declare const logger = Logger.new(import.meta.filename, "pvm");
|
|
17729
18312
|
|
|
17730
|
-
declare class Interpreter {
|
|
18313
|
+
declare class Interpreter implements IPvmInterpreter {
|
|
17731
18314
|
private readonly useSbrkGas: boolean;
|
|
17732
|
-
|
|
18315
|
+
readonly registers = new Registers();
|
|
18316
|
+
readonly memory = new Memory();
|
|
18317
|
+
gas = gasCounter(tryAsGas(0));
|
|
17733
18318
|
private code: Uint8Array = new Uint8Array();
|
|
17734
18319
|
private mask = Mask.empty();
|
|
17735
18320
|
private pc = 0;
|
|
17736
|
-
private gas = gasCounter(tryAsGas(0));
|
|
17737
|
-
private initialGas = gasCounter(tryAsGas(0));
|
|
17738
18321
|
private argsDecoder: ArgsDecoder;
|
|
17739
18322
|
private threeRegsDispatcher: ThreeRegsDispatcher;
|
|
17740
18323
|
private twoRegsOneImmDispatcher: TwoRegsOneImmDispatcher;
|
|
@@ -17744,7 +18327,6 @@ declare class Interpreter {
|
|
|
17744
18327
|
private oneOffsetDispatcher: OneOffsetDispatcher;
|
|
17745
18328
|
private oneRegOneImmDispatcher: OneRegOneImmDispatcher;
|
|
17746
18329
|
private instructionResult = new InstructionResult();
|
|
17747
|
-
private memory = new Memory();
|
|
17748
18330
|
private twoImmsDispatcher: TwoImmsDispatcher;
|
|
17749
18331
|
private oneRegTwoImmsDispatcher: OneRegTwoImmsDispatcher;
|
|
17750
18332
|
private noArgsDispatcher: NoArgsDispatcher;
|
|
@@ -17798,7 +18380,12 @@ declare class Interpreter {
|
|
|
17798
18380
|
this.oneRegOneExtImmDispatcher = new OneRegOneExtImmDispatcher(loadOps);
|
|
17799
18381
|
}
|
|
17800
18382
|
|
|
17801
|
-
|
|
18383
|
+
resetJam(program: Uint8Array, args: Uint8Array, pc: number, gas: Gas) {
|
|
18384
|
+
const p = Program.fromSpi(program, args, true);
|
|
18385
|
+
this.resetGeneric(p.code, pc, gas, p.registers, p.memory);
|
|
18386
|
+
}
|
|
18387
|
+
|
|
18388
|
+
resetGeneric(rawProgram: Uint8Array, pc: number, gas: Gas, maybeRegisters?: Registers, maybeMemory?: Memory) {
|
|
17802
18389
|
const programDecoder = new ProgramDecoder(rawProgram);
|
|
17803
18390
|
this.code = programDecoder.getCode();
|
|
17804
18391
|
this.mask = programDecoder.getMask();
|
|
@@ -17806,7 +18393,6 @@ declare class Interpreter {
|
|
|
17806
18393
|
|
|
17807
18394
|
this.pc = pc;
|
|
17808
18395
|
this.gas = gasCounter(gas);
|
|
17809
|
-
this.initialGas = gasCounter(gas);
|
|
17810
18396
|
this.status = Status.OK;
|
|
17811
18397
|
this.argsDecoder.reset(this.code, this.mask);
|
|
17812
18398
|
this.basicBlocks.reset(this.code, this.mask);
|
|
@@ -17948,10 +18534,6 @@ declare class Interpreter {
|
|
|
17948
18534
|
return this.status;
|
|
17949
18535
|
}
|
|
17950
18536
|
|
|
17951
|
-
getRegisters() {
|
|
17952
|
-
return this.registers;
|
|
17953
|
-
}
|
|
17954
|
-
|
|
17955
18537
|
getPC() {
|
|
17956
18538
|
return this.pc;
|
|
17957
18539
|
}
|
|
@@ -17960,258 +18542,91 @@ declare class Interpreter {
|
|
|
17960
18542
|
this.pc = nextPc;
|
|
17961
18543
|
}
|
|
17962
18544
|
|
|
17963
|
-
getGas(): Gas {
|
|
17964
|
-
return this.gas.get();
|
|
17965
|
-
}
|
|
17966
|
-
|
|
17967
|
-
getGasConsumed(): Gas {
|
|
17968
|
-
const gasConsumed = tryAsBigGas(this.initialGas.get()) - tryAsBigGas(this.gas.get());
|
|
17969
|
-
|
|
17970
|
-
if (gasConsumed < 0) {
|
|
17971
|
-
return this.initialGas.get();
|
|
17972
|
-
}
|
|
17973
|
-
|
|
17974
|
-
return tryAsBigGas(gasConsumed);
|
|
17975
|
-
}
|
|
17976
|
-
|
|
17977
|
-
getGasCounter(): GasCounter {
|
|
17978
|
-
return this.gas;
|
|
17979
|
-
}
|
|
17980
|
-
|
|
17981
18545
|
getStatus() {
|
|
17982
18546
|
return this.status;
|
|
17983
18547
|
}
|
|
17984
18548
|
|
|
17985
18549
|
getExitParam(): null | U32 {
|
|
17986
18550
|
const p = this.instructionResult.exitParam;
|
|
17987
|
-
return p !== null ? tryAsU32(p) : p;
|
|
17988
|
-
}
|
|
17989
|
-
|
|
17990
|
-
getMemory() {
|
|
17991
|
-
return this.memory;
|
|
17992
|
-
}
|
|
17993
|
-
|
|
17994
|
-
getMemoryPage(pageNumber: number): null | Uint8Array {
|
|
17995
|
-
return this.memory.getPageDump(tryAsPageNumber(pageNumber));
|
|
17996
|
-
}
|
|
17997
|
-
|
|
17998
|
-
calculateBlockGasCost(): Map<string, number> {
|
|
17999
|
-
const codeLength = this.code.length;
|
|
18000
|
-
const blocks: Map<string, number> = new Map();
|
|
18001
|
-
let currentBlock = "0";
|
|
18002
|
-
let gasCost = 0;
|
|
18003
|
-
const getNextIstructionIndex = (index: number) => index + 1 + this.mask.getNoOfBytesToNextInstruction(index + 1);
|
|
18004
|
-
|
|
18005
|
-
for (let index = 0; index < codeLength; index = getNextIstructionIndex(index)) {
|
|
18006
|
-
const instruction = this.code[index];
|
|
18007
|
-
if (this.basicBlocks.isBeginningOfBasicBlock(index)) {
|
|
18008
|
-
blocks.set(currentBlock, gasCost);
|
|
18009
|
-
currentBlock = index.toString();
|
|
18010
|
-
gasCost = 0;
|
|
18011
|
-
}
|
|
18012
|
-
|
|
18013
|
-
gasCost += instructionGasMap[instruction];
|
|
18014
|
-
}
|
|
18015
|
-
|
|
18016
|
-
blocks.set(currentBlock, gasCost);
|
|
18017
|
-
|
|
18018
|
-
return blocks;
|
|
18019
|
-
}
|
|
18020
|
-
}
|
|
18021
|
-
|
|
18022
|
-
type index$8_BigGas = BigGas;
|
|
18023
|
-
type index$8_Gas = Gas;
|
|
18024
|
-
type index$8_GasCounter = GasCounter;
|
|
18025
|
-
type index$8_Interpreter = Interpreter;
|
|
18026
|
-
declare const index$8_Interpreter: typeof Interpreter;
|
|
18027
|
-
type index$8_InterpreterOptions = InterpreterOptions;
|
|
18028
|
-
type index$8_Memory = Memory;
|
|
18029
|
-
declare const index$8_Memory: typeof Memory;
|
|
18030
|
-
type index$8_MemoryBuilder = MemoryBuilder;
|
|
18031
|
-
declare const index$8_MemoryBuilder: typeof MemoryBuilder;
|
|
18032
|
-
type index$8_MemoryIndex = MemoryIndex;
|
|
18033
|
-
type index$8_Registers = Registers;
|
|
18034
|
-
declare const index$8_Registers: typeof Registers;
|
|
18035
|
-
type index$8_SbrkIndex = SbrkIndex;
|
|
18036
|
-
type index$8_SmallGas = SmallGas;
|
|
18037
|
-
declare const index$8_gasCounter: typeof gasCounter;
|
|
18038
|
-
declare const index$8_logger: typeof logger;
|
|
18039
|
-
declare const index$8_tryAsBigGas: typeof tryAsBigGas;
|
|
18040
|
-
declare const index$8_tryAsGas: typeof tryAsGas;
|
|
18041
|
-
declare const index$8_tryAsMemoryIndex: typeof tryAsMemoryIndex;
|
|
18042
|
-
declare const index$8_tryAsSbrkIndex: typeof tryAsSbrkIndex;
|
|
18043
|
-
declare const index$8_tryAsSmallGas: typeof tryAsSmallGas;
|
|
18044
|
-
declare namespace index$8 {
|
|
18045
|
-
export { index$8_Interpreter as Interpreter, index$8_Memory as Memory, index$8_MemoryBuilder as MemoryBuilder, index$8_Registers as Registers, index$8_gasCounter as gasCounter, index$8_logger as logger, index$8_tryAsBigGas as tryAsBigGas, index$8_tryAsGas as tryAsGas, index$8_tryAsMemoryIndex as tryAsMemoryIndex, index$8_tryAsSbrkIndex as tryAsSbrkIndex, index$8_tryAsSmallGas as tryAsSmallGas };
|
|
18046
|
-
export type { index$8_BigGas as BigGas, index$8_Gas as Gas, index$8_GasCounter as GasCounter, index$8_InterpreterOptions as InterpreterOptions, index$8_MemoryIndex as MemoryIndex, index$8_SbrkIndex as SbrkIndex, index$8_SmallGas as SmallGas };
|
|
18047
|
-
}
|
|
18048
|
-
|
|
18049
|
-
interface IHostCallMemory {
|
|
18050
|
-
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds>;
|
|
18051
|
-
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds>;
|
|
18052
|
-
}
|
|
18053
|
-
|
|
18054
|
-
declare class HostCallMemory implements IHostCallMemory {
|
|
18055
|
-
constructor(private readonly memory: Memory) {}
|
|
18056
|
-
|
|
18057
|
-
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds> {
|
|
18058
|
-
if (bytes.length === 0) {
|
|
18059
|
-
return Result.ok(OK);
|
|
18060
|
-
}
|
|
18061
|
-
|
|
18062
|
-
if (address + tryAsU64(bytes.length) > MEMORY_SIZE) {
|
|
18063
|
-
return Result.error(
|
|
18064
|
-
new OutOfBounds(),
|
|
18065
|
-
() => `Memory access out of bounds: address ${address} + length ${bytes.length} exceeds memory size`,
|
|
18066
|
-
);
|
|
18067
|
-
}
|
|
18068
|
-
|
|
18069
|
-
return this.memory.storeFrom(tryAsMemoryIndex(Number(address)), bytes);
|
|
18070
|
-
}
|
|
18071
|
-
|
|
18072
|
-
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds> {
|
|
18073
|
-
if (result.length === 0) {
|
|
18074
|
-
return Result.ok(OK);
|
|
18075
|
-
}
|
|
18076
|
-
|
|
18077
|
-
if (startAddress + tryAsU64(result.length) > MEMORY_SIZE) {
|
|
18078
|
-
return Result.error(
|
|
18079
|
-
new OutOfBounds(),
|
|
18080
|
-
() => `Memory access out of bounds: address ${startAddress} + length ${result.length} exceeds memory size`,
|
|
18081
|
-
);
|
|
18082
|
-
}
|
|
18083
|
-
|
|
18084
|
-
return this.memory.loadInto(result, tryAsMemoryIndex(Number(startAddress)));
|
|
18085
|
-
}
|
|
18086
|
-
}
|
|
18087
|
-
|
|
18088
|
-
interface IHostCallRegisters {
|
|
18089
|
-
get(registerIndex: number): U64;
|
|
18090
|
-
set(registerIndex: number, value: U64): void;
|
|
18091
|
-
}
|
|
18092
|
-
|
|
18093
|
-
declare class HostCallRegisters implements IHostCallRegisters {
|
|
18094
|
-
constructor(private readonly registers: Registers) {}
|
|
18095
|
-
|
|
18096
|
-
get(registerIndex: number): U64 {
|
|
18097
|
-
return tryAsU64(this.registers.getU64(registerIndex));
|
|
18098
|
-
}
|
|
18099
|
-
|
|
18100
|
-
set(registerIndex: number, value: U64) {
|
|
18101
|
-
this.registers.setU64(registerIndex, value);
|
|
18102
|
-
}
|
|
18103
|
-
}
|
|
18104
|
-
|
|
18105
|
-
/** Strictly-typed host call index. */
|
|
18106
|
-
type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
18107
|
-
/** Attempt to convert a number into `HostCallIndex`. */
|
|
18108
|
-
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
18109
|
-
|
|
18110
|
-
/**
|
|
18111
|
-
* Host-call exit reason.
|
|
18112
|
-
*
|
|
18113
|
-
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
18114
|
-
*/
|
|
18115
|
-
declare enum PvmExecution {
|
|
18116
|
-
Halt = 0,
|
|
18117
|
-
Panic = 1,
|
|
18118
|
-
OOG = 2, // out-of-gas
|
|
18119
|
-
}
|
|
18120
|
-
|
|
18121
|
-
/** A utility function to easily trace a bunch of registers. */
|
|
18122
|
-
declare function traceRegisters(...regs: number[]) {
|
|
18123
|
-
return regs.map(tryAsRegisterIndex);
|
|
18124
|
-
}
|
|
18125
|
-
|
|
18126
|
-
/** An interface for a host call implementation */
|
|
18127
|
-
interface HostCallHandler {
|
|
18128
|
-
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
18129
|
-
readonly index: HostCallIndex;
|
|
18130
|
-
|
|
18131
|
-
/**
|
|
18132
|
-
* The gas cost of invocation of that host call.
|
|
18133
|
-
*
|
|
18134
|
-
* NOTE: `((reg: IHostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
18135
|
-
*/
|
|
18136
|
-
readonly basicGasCost: SmallGas | ((reg: IHostCallRegisters) => Gas);
|
|
18137
|
-
|
|
18138
|
-
/** Currently executing service id. */
|
|
18139
|
-
readonly currentServiceId: U32;
|
|
18140
|
-
|
|
18141
|
-
/** Input&Output registers that we should add to tracing log. */
|
|
18142
|
-
readonly tracedRegisters: RegisterIndex[];
|
|
18551
|
+
return p !== null ? tryAsU32(p) : p;
|
|
18552
|
+
}
|
|
18143
18553
|
|
|
18144
|
-
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
* NOTE the call is ALLOWED and expected to modify registers and memory.
|
|
18148
|
-
*/
|
|
18149
|
-
execute(gas: GasCounter, regs: IHostCallRegisters, memory: IHostCallMemory): Promise<undefined | PvmExecution>;
|
|
18150
|
-
}
|
|
18554
|
+
getMemoryPage(pageNumber: number): null | Uint8Array {
|
|
18555
|
+
return this.memory.getPageDump(tryAsPageNumber(pageNumber));
|
|
18556
|
+
}
|
|
18151
18557
|
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18558
|
+
calculateBlockGasCost(): Map<string, number> {
|
|
18559
|
+
const codeLength = this.code.length;
|
|
18560
|
+
const blocks: Map<string, number> = new Map();
|
|
18561
|
+
let currentBlock = "0";
|
|
18562
|
+
let gasCost = 0;
|
|
18563
|
+
const getNextIstructionIndex = (index: number) => index + 1 + this.mask.getNoOfBytesToNextInstruction(index + 1);
|
|
18156
18564
|
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
this.missing = missing;
|
|
18565
|
+
for (let index = 0; index < codeLength; index = getNextIstructionIndex(index)) {
|
|
18566
|
+
const instruction = this.code[index];
|
|
18567
|
+
if (this.basicBlocks.isBeginningOfBasicBlock(index)) {
|
|
18568
|
+
blocks.set(currentBlock, gasCost);
|
|
18569
|
+
currentBlock = index.toString();
|
|
18570
|
+
gasCost = 0;
|
|
18571
|
+
}
|
|
18165
18572
|
|
|
18166
|
-
|
|
18167
|
-
check`${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
18168
|
-
this.hostCalls.set(handler.index, handler);
|
|
18573
|
+
gasCost += instructionGasMap[instruction];
|
|
18169
18574
|
}
|
|
18170
|
-
}
|
|
18171
18575
|
|
|
18172
|
-
|
|
18173
|
-
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
18174
|
-
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
18175
|
-
}
|
|
18576
|
+
blocks.set(currentBlock, gasCost);
|
|
18176
18577
|
|
|
18177
|
-
|
|
18178
|
-
context: string,
|
|
18179
|
-
hostCallIndex: HostCallIndex,
|
|
18180
|
-
hostCallHandler: HostCallHandler,
|
|
18181
|
-
registers: IHostCallRegisters,
|
|
18182
|
-
gas: Gas,
|
|
18183
|
-
) {
|
|
18184
|
-
const { currentServiceId } = hostCallHandler;
|
|
18185
|
-
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
18186
|
-
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
18187
|
-
const registerValues = hostCallHandler.tracedRegisters
|
|
18188
|
-
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
18189
|
-
.filter((v) => v[1] !== 0n)
|
|
18190
|
-
.map(([idx, value]) => {
|
|
18191
|
-
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
18192
|
-
})
|
|
18193
|
-
.join(", ");
|
|
18194
|
-
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
18578
|
+
return blocks;
|
|
18195
18579
|
}
|
|
18196
18580
|
}
|
|
18197
18581
|
|
|
18198
|
-
type
|
|
18582
|
+
type index$6_Interpreter = Interpreter;
|
|
18583
|
+
declare const index$6_Interpreter: typeof Interpreter;
|
|
18584
|
+
type index$6_InterpreterOptions = InterpreterOptions;
|
|
18585
|
+
type index$6_Memory = Memory;
|
|
18586
|
+
declare const index$6_Memory: typeof Memory;
|
|
18587
|
+
type index$6_MemoryBuilder = MemoryBuilder;
|
|
18588
|
+
declare const index$6_MemoryBuilder: typeof MemoryBuilder;
|
|
18589
|
+
type index$6_MemoryIndex = MemoryIndex;
|
|
18590
|
+
type index$6_Registers = Registers;
|
|
18591
|
+
declare const index$6_Registers: typeof Registers;
|
|
18592
|
+
type index$6_SbrkIndex = SbrkIndex;
|
|
18593
|
+
declare const index$6_gasCounter: typeof gasCounter;
|
|
18594
|
+
declare const index$6_logger: typeof logger;
|
|
18595
|
+
declare const index$6_tryAsMemoryIndex: typeof tryAsMemoryIndex;
|
|
18596
|
+
declare const index$6_tryAsSbrkIndex: typeof tryAsSbrkIndex;
|
|
18597
|
+
declare namespace index$6 {
|
|
18598
|
+
export { index$6_Interpreter as Interpreter, index$6_Memory as Memory, index$6_MemoryBuilder as MemoryBuilder, index$6_Registers as Registers, index$6_gasCounter as gasCounter, index$6_logger as logger, index$6_tryAsMemoryIndex as tryAsMemoryIndex, index$6_tryAsSbrkIndex as tryAsSbrkIndex };
|
|
18599
|
+
export type { index$6_InterpreterOptions as InterpreterOptions, index$6_MemoryIndex as MemoryIndex, index$6_SbrkIndex as SbrkIndex };
|
|
18600
|
+
}
|
|
18199
18601
|
|
|
18602
|
+
type ResolveFn = (pvm: IPvmInterpreter) => void;
|
|
18603
|
+
|
|
18604
|
+
// TODO [MaSo] Delete this & also make host calls independent from intepreters.
|
|
18200
18605
|
declare class InterpreterInstanceManager {
|
|
18201
|
-
private instances: Interpreter[] = [];
|
|
18202
18606
|
private waitingQueue: ResolveFn[] = [];
|
|
18203
18607
|
|
|
18204
|
-
constructor(
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
|
|
18608
|
+
private constructor(private readonly instances: IPvmInterpreter[]) {}
|
|
18609
|
+
|
|
18610
|
+
static async new(interpreter: PvmBackend): Promise<InterpreterInstanceManager> {
|
|
18611
|
+
const instances: IPvmInterpreter[] = [];
|
|
18612
|
+
switch (interpreter) {
|
|
18613
|
+
case PvmBackend.BuiltIn:
|
|
18614
|
+
instances.push(
|
|
18615
|
+
new Interpreter({
|
|
18616
|
+
useSbrkGas: false,
|
|
18617
|
+
}),
|
|
18618
|
+
);
|
|
18619
|
+
break;
|
|
18620
|
+
case PvmBackend.Ananas:
|
|
18621
|
+
instances.push(await AnanasInterpreter.new());
|
|
18622
|
+
break;
|
|
18623
|
+
default:
|
|
18624
|
+
assertNever(interpreter);
|
|
18211
18625
|
}
|
|
18626
|
+
return new InterpreterInstanceManager(instances);
|
|
18212
18627
|
}
|
|
18213
18628
|
|
|
18214
|
-
async getInstance(): Promise<
|
|
18629
|
+
async getInstance(): Promise<IPvmInterpreter> {
|
|
18215
18630
|
const instance = this.instances.pop();
|
|
18216
18631
|
if (instance !== undefined) {
|
|
18217
18632
|
return Promise.resolve(instance);
|
|
@@ -18221,7 +18636,7 @@ declare class InterpreterInstanceManager {
|
|
|
18221
18636
|
});
|
|
18222
18637
|
}
|
|
18223
18638
|
|
|
18224
|
-
releaseInstance(pvm:
|
|
18639
|
+
releaseInstance(pvm: IPvmInterpreter) {
|
|
18225
18640
|
const waiting = this.waitingQueue.shift();
|
|
18226
18641
|
if (waiting !== undefined) {
|
|
18227
18642
|
return waiting(pvm);
|
|
@@ -18264,21 +18679,22 @@ declare class HostCalls {
|
|
|
18264
18679
|
private hostCalls: HostCallsManager,
|
|
18265
18680
|
) {}
|
|
18266
18681
|
|
|
18267
|
-
private getReturnValue(status: Status, pvmInstance:
|
|
18268
|
-
const gasConsumed = pvmInstance.
|
|
18682
|
+
private getReturnValue(status: Status, pvmInstance: IPvmInterpreter): ReturnValue {
|
|
18683
|
+
const gasConsumed = pvmInstance.gas.used();
|
|
18269
18684
|
if (status === Status.OOG) {
|
|
18270
18685
|
return ReturnValue.fromStatus(gasConsumed, status);
|
|
18271
18686
|
}
|
|
18272
18687
|
|
|
18273
18688
|
if (status === Status.HALT) {
|
|
18274
|
-
const
|
|
18275
|
-
const
|
|
18276
|
-
const
|
|
18277
|
-
|
|
18689
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
18690
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
18691
|
+
const address = regs.get(7);
|
|
18692
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
18693
|
+
const length = Number(regs.get(8) & 0xffff_ffffn);
|
|
18694
|
+
|
|
18695
|
+
const result = safeAllocUint8Array(length);
|
|
18278
18696
|
|
|
18279
|
-
const
|
|
18280
|
-
const startAddress = tryAsMemoryIndex(maybeAddress);
|
|
18281
|
-
const loadResult = memory.loadInto(result, startAddress);
|
|
18697
|
+
const loadResult = memory.loadInto(result, address);
|
|
18282
18698
|
|
|
18283
18699
|
if (loadResult.isError) {
|
|
18284
18700
|
return ReturnValue.fromMemorySlice(gasConsumed, new Uint8Array());
|
|
@@ -18290,7 +18706,7 @@ declare class HostCalls {
|
|
|
18290
18706
|
return ReturnValue.fromStatus(gasConsumed, Status.PANIC);
|
|
18291
18707
|
}
|
|
18292
18708
|
|
|
18293
|
-
private async execute(pvmInstance:
|
|
18709
|
+
private async execute(pvmInstance: IPvmInterpreter) {
|
|
18294
18710
|
pvmInstance.runProgram();
|
|
18295
18711
|
for (;;) {
|
|
18296
18712
|
let status = pvmInstance.getStatus();
|
|
@@ -18302,9 +18718,9 @@ declare class HostCalls {
|
|
|
18302
18718
|
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
18303
18719
|
`;
|
|
18304
18720
|
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
18305
|
-
const gas = pvmInstance.
|
|
18306
|
-
const regs = new HostCallRegisters(pvmInstance.
|
|
18307
|
-
const memory = new HostCallMemory(pvmInstance.
|
|
18721
|
+
const gas = pvmInstance.gas;
|
|
18722
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
18723
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
18308
18724
|
const index = tryAsHostCallIndex(hostCallIndex);
|
|
18309
18725
|
|
|
18310
18726
|
const hostCall = this.hostCalls.get(index);
|
|
@@ -18317,7 +18733,7 @@ declare class HostCalls {
|
|
|
18317
18733
|
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
18318
18734
|
if (underflow) {
|
|
18319
18735
|
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
18320
|
-
return ReturnValue.fromStatus(
|
|
18736
|
+
return ReturnValue.fromStatus(gas.used(), Status.OOG);
|
|
18321
18737
|
}
|
|
18322
18738
|
this.hostCalls.traceHostCall(`${pcLog} Invoking`, index, hostCall, regs, gasBefore);
|
|
18323
18739
|
const result = await hostCall.execute(gas, regs, memory);
|
|
@@ -18328,6 +18744,7 @@ declare class HostCalls {
|
|
|
18328
18744
|
regs,
|
|
18329
18745
|
gas.get(),
|
|
18330
18746
|
);
|
|
18747
|
+
pvmInstance.registers.setAllEncoded(regs.getEncoded());
|
|
18331
18748
|
|
|
18332
18749
|
if (result === PvmExecution.Halt) {
|
|
18333
18750
|
status = Status.HALT;
|
|
@@ -18354,15 +18771,9 @@ declare class HostCalls {
|
|
|
18354
18771
|
}
|
|
18355
18772
|
}
|
|
18356
18773
|
|
|
18357
|
-
async runProgram(
|
|
18358
|
-
rawProgram: Uint8Array,
|
|
18359
|
-
initialPc: number,
|
|
18360
|
-
initialGas: Gas,
|
|
18361
|
-
maybeRegisters?: Registers,
|
|
18362
|
-
maybeMemory?: Memory,
|
|
18363
|
-
): Promise<ReturnValue> {
|
|
18774
|
+
async runProgram(program: Uint8Array, args: Uint8Array, initialPc: number, initialGas: Gas): Promise<ReturnValue> {
|
|
18364
18775
|
const pvmInstance = await this.pvmInstanceManager.getInstance();
|
|
18365
|
-
pvmInstance.
|
|
18776
|
+
pvmInstance.resetJam(program, args, initialPc, initialGas);
|
|
18366
18777
|
try {
|
|
18367
18778
|
return await this.execute(pvmInstance);
|
|
18368
18779
|
} finally {
|
|
@@ -18371,20 +18782,18 @@ declare class HostCalls {
|
|
|
18371
18782
|
}
|
|
18372
18783
|
}
|
|
18373
18784
|
|
|
18374
|
-
type index$
|
|
18375
|
-
type index$
|
|
18376
|
-
declare const index$
|
|
18377
|
-
type index$
|
|
18378
|
-
declare const index$
|
|
18379
|
-
type index$
|
|
18380
|
-
|
|
18381
|
-
|
|
18382
|
-
declare const index$
|
|
18383
|
-
declare
|
|
18384
|
-
|
|
18385
|
-
|
|
18386
|
-
export { index$7_HostCallMemory as HostCallMemory, index$7_HostCallRegisters as HostCallRegisters, HostCallsManager as HostCalls, index$7_PvmExecution as PvmExecution, HostCalls as PvmHostCallExtension, InterpreterInstanceManager as PvmInstanceManager, index$7_traceRegisters as traceRegisters, index$7_tryAsHostCallIndex as tryAsHostCallIndex };
|
|
18387
|
-
export type { index$7_HostCallHandler as HostCallHandler, index$7_IHostCallMemory as IHostCallMemory, index$7_IHostCallRegisters as IHostCallRegisters };
|
|
18785
|
+
type index$5_HostCallHandler = HostCallHandler;
|
|
18786
|
+
type index$5_HostCallMemory = HostCallMemory;
|
|
18787
|
+
declare const index$5_HostCallMemory: typeof HostCallMemory;
|
|
18788
|
+
type index$5_HostCallRegisters = HostCallRegisters;
|
|
18789
|
+
declare const index$5_HostCallRegisters: typeof HostCallRegisters;
|
|
18790
|
+
type index$5_PvmExecution = PvmExecution;
|
|
18791
|
+
declare const index$5_PvmExecution: typeof PvmExecution;
|
|
18792
|
+
declare const index$5_traceRegisters: typeof traceRegisters;
|
|
18793
|
+
declare const index$5_tryAsHostCallIndex: typeof tryAsHostCallIndex;
|
|
18794
|
+
declare namespace index$5 {
|
|
18795
|
+
export { index$5_HostCallMemory as HostCallMemory, index$5_HostCallRegisters as HostCallRegisters, HostCallsManager as HostCalls, index$5_PvmExecution as PvmExecution, HostCalls as PvmHostCallExtension, InterpreterInstanceManager as PvmInstanceManager, index$5_traceRegisters as traceRegisters, index$5_tryAsHostCallIndex as tryAsHostCallIndex };
|
|
18796
|
+
export type { index$5_HostCallHandler as HostCallHandler };
|
|
18388
18797
|
}
|
|
18389
18798
|
|
|
18390
18799
|
/**
|
|
@@ -18402,7 +18811,7 @@ type MachineId = Opaque<U64, "MachineId[u64]">;
|
|
|
18402
18811
|
declare const tryAsMachineId = (v: number | bigint): MachineId => asOpaqueType(tryAsU64(v));
|
|
18403
18812
|
|
|
18404
18813
|
declare class MachineInstance {
|
|
18405
|
-
async run(gas: BigGas, registers:
|
|
18814
|
+
async run(gas: BigGas, registers: HostCallRegisters): Promise<MachineResult> {
|
|
18406
18815
|
return {
|
|
18407
18816
|
result: {
|
|
18408
18817
|
status: Status.OK,
|
|
@@ -18430,7 +18839,7 @@ type MachineStatus =
|
|
|
18430
18839
|
type MachineResult = {
|
|
18431
18840
|
result: MachineStatus;
|
|
18432
18841
|
gas: BigGas;
|
|
18433
|
-
registers:
|
|
18842
|
+
registers: HostCallRegisters;
|
|
18434
18843
|
};
|
|
18435
18844
|
|
|
18436
18845
|
/** Types of possbile operations to request by Pages host call. */
|
|
@@ -18502,7 +18911,7 @@ interface RefineExternalities {
|
|
|
18502
18911
|
destinationStart: U64,
|
|
18503
18912
|
sourceStart: U64,
|
|
18504
18913
|
length: U64,
|
|
18505
|
-
destination:
|
|
18914
|
+
destination: HostCallMemory,
|
|
18506
18915
|
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18507
18916
|
|
|
18508
18917
|
/** Write a fragment of memory into `machineIndex` from given source memory. */
|
|
@@ -18511,7 +18920,7 @@ interface RefineExternalities {
|
|
|
18511
18920
|
sourceStart: U64,
|
|
18512
18921
|
destinationStart: U64,
|
|
18513
18922
|
length: U64,
|
|
18514
|
-
source:
|
|
18923
|
+
source: HostCallMemory,
|
|
18515
18924
|
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18516
18925
|
|
|
18517
18926
|
/** Start an inner PVM instance with given entry point and starting code. */
|
|
@@ -18521,7 +18930,7 @@ interface RefineExternalities {
|
|
|
18521
18930
|
machineInvoke(
|
|
18522
18931
|
machineIndex: MachineId,
|
|
18523
18932
|
gas: BigGas,
|
|
18524
|
-
registers:
|
|
18933
|
+
registers: HostCallRegisters,
|
|
18525
18934
|
): Promise<Result$2<MachineResult, NoMachineError>>;
|
|
18526
18935
|
|
|
18527
18936
|
/**
|
|
@@ -18943,7 +19352,7 @@ declare const CURRENT_SERVICE_ID = tryAsServiceId(2 ** 32 - 1);
|
|
|
18943
19352
|
|
|
18944
19353
|
declare function getServiceIdOrCurrent(
|
|
18945
19354
|
regNumber: number,
|
|
18946
|
-
regs:
|
|
19355
|
+
regs: HostCallRegisters,
|
|
18947
19356
|
currentServiceId: ServiceId,
|
|
18948
19357
|
): ServiceId | null {
|
|
18949
19358
|
const regValue = regs.get(regNumber);
|
|
@@ -18974,270 +19383,75 @@ declare function clampU64ToU32(value: U64): U32 {
|
|
|
18974
19383
|
return value > MAX_U32_BIG_INT ? MAX_U32 : tryAsU32(Number(value));
|
|
18975
19384
|
}
|
|
18976
19385
|
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
declare const index$
|
|
18984
|
-
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
declare const index$
|
|
18988
|
-
|
|
18989
|
-
type index$
|
|
18990
|
-
declare const index$
|
|
18991
|
-
|
|
18992
|
-
type index$
|
|
18993
|
-
type index$
|
|
18994
|
-
declare const index$
|
|
18995
|
-
type index$
|
|
18996
|
-
|
|
18997
|
-
type index$
|
|
18998
|
-
|
|
18999
|
-
|
|
19000
|
-
|
|
19001
|
-
type index$
|
|
19002
|
-
|
|
19003
|
-
|
|
19004
|
-
|
|
19005
|
-
type index$
|
|
19006
|
-
declare const index$
|
|
19007
|
-
type index$
|
|
19008
|
-
|
|
19009
|
-
|
|
19010
|
-
|
|
19011
|
-
type index$
|
|
19012
|
-
|
|
19013
|
-
|
|
19014
|
-
type index$
|
|
19015
|
-
|
|
19016
|
-
declare const index$
|
|
19017
|
-
type index$
|
|
19018
|
-
type index$
|
|
19019
|
-
|
|
19020
|
-
|
|
19021
|
-
type index$
|
|
19022
|
-
|
|
19023
|
-
type index$
|
|
19024
|
-
type index$
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
|
|
19029
|
-
declare const index$
|
|
19030
|
-
|
|
19031
|
-
declare const index$
|
|
19032
|
-
declare const index$
|
|
19033
|
-
declare const index$
|
|
19034
|
-
declare const index$
|
|
19035
|
-
declare const index$
|
|
19036
|
-
declare const index$
|
|
19037
|
-
declare const index$
|
|
19038
|
-
declare
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19043
|
-
declare const NO_OF_REGISTERS = 13;
|
|
19044
|
-
|
|
19045
|
-
declare class MemorySegment extends WithDebug {
|
|
19046
|
-
static from({ start, end, data }: Omit<MemorySegment, never>) {
|
|
19047
|
-
return new MemorySegment(start, end, data);
|
|
19048
|
-
}
|
|
19049
|
-
|
|
19050
|
-
constructor(
|
|
19051
|
-
public readonly start: number,
|
|
19052
|
-
public readonly end: number,
|
|
19053
|
-
public readonly data: Uint8Array | null,
|
|
19054
|
-
) {
|
|
19055
|
-
super();
|
|
19056
|
-
}
|
|
19057
|
-
}
|
|
19058
|
-
declare class SpiMemory extends WithDebug {
|
|
19059
|
-
constructor(
|
|
19060
|
-
public readonly readable: MemorySegment[],
|
|
19061
|
-
public readonly writeable: MemorySegment[],
|
|
19062
|
-
public readonly sbrkIndex: number,
|
|
19063
|
-
public readonly heapEnd: number,
|
|
19064
|
-
) {
|
|
19065
|
-
super();
|
|
19066
|
-
}
|
|
19067
|
-
}
|
|
19068
|
-
|
|
19069
|
-
declare class SpiProgram extends WithDebug {
|
|
19070
|
-
constructor(
|
|
19071
|
-
public readonly code: Uint8Array,
|
|
19072
|
-
public readonly memory: SpiMemory,
|
|
19073
|
-
public readonly registers: BigUint64Array,
|
|
19074
|
-
) {
|
|
19075
|
-
super();
|
|
19076
|
-
}
|
|
19077
|
-
}
|
|
19078
|
-
|
|
19079
|
-
/**
|
|
19080
|
-
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
19081
|
-
*
|
|
19082
|
-
* E_n - little endian encoding, n - length
|
|
19083
|
-
* o - initial read only data
|
|
19084
|
-
* w - initial heap
|
|
19085
|
-
* z - heap pages filled with zeros
|
|
19086
|
-
* s - stack size
|
|
19087
|
-
* c - program code
|
|
19088
|
-
*
|
|
19089
|
-
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
19090
|
-
*/
|
|
19091
|
-
declare function decodeStandardProgram(program: Uint8Array, args: Uint8Array) {
|
|
19092
|
-
const decoder = Decoder.fromBlob(program);
|
|
19093
|
-
const oLength = decoder.u24();
|
|
19094
|
-
const wLength = decoder.u24();
|
|
19095
|
-
check`${args.length <= DATA_LENGTH} Incorrect arguments length`;
|
|
19096
|
-
check`${oLength <= DATA_LENGTH} Incorrect readonly segment length`;
|
|
19097
|
-
const readOnlyLength = oLength;
|
|
19098
|
-
check`${wLength <= DATA_LENGTH} Incorrect heap segment length`;
|
|
19099
|
-
const heapLength = wLength;
|
|
19100
|
-
const noOfHeapZerosPages = decoder.u16();
|
|
19101
|
-
const stackSize = decoder.u24();
|
|
19102
|
-
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
19103
|
-
const initialHeap = decoder.bytes(heapLength).raw;
|
|
19104
|
-
const codeLength = decoder.u32();
|
|
19105
|
-
const code = decoder.bytes(codeLength).raw;
|
|
19106
|
-
decoder.finish();
|
|
19107
|
-
|
|
19108
|
-
const readonlyDataStart = SEGMENT_SIZE;
|
|
19109
|
-
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
19110
|
-
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
19111
|
-
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
19112
|
-
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
19113
|
-
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
19114
|
-
const stackEnd = STACK_SEGMENT;
|
|
19115
|
-
const argsStart = ARGS_SEGMENT;
|
|
19116
|
-
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
19117
|
-
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
19118
|
-
|
|
19119
|
-
function nonEmpty(s: MemorySegment | false): s is MemorySegment {
|
|
19120
|
-
return s !== false;
|
|
19121
|
-
}
|
|
19122
|
-
|
|
19123
|
-
const readableMemory = [
|
|
19124
|
-
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
19125
|
-
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
19126
|
-
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
19127
|
-
].filter(nonEmpty);
|
|
19128
|
-
const writeableMemory = [
|
|
19129
|
-
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
19130
|
-
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
19131
|
-
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
19132
|
-
].filter(nonEmpty);
|
|
19133
|
-
|
|
19134
|
-
return new SpiProgram(
|
|
19135
|
-
code,
|
|
19136
|
-
new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart),
|
|
19137
|
-
getRegisters(args.length),
|
|
19138
|
-
);
|
|
19139
|
-
}
|
|
19140
|
-
|
|
19141
|
-
declare function getMemorySegment(start: number, end: number, data: Uint8Array | null = null) {
|
|
19142
|
-
return new MemorySegment(start, end, data);
|
|
19143
|
-
}
|
|
19144
|
-
|
|
19145
|
-
declare function getRegisters(argsLength: number) {
|
|
19146
|
-
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
19147
|
-
|
|
19148
|
-
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
19149
|
-
regs[0] = BigInt(LAST_PAGE);
|
|
19150
|
-
regs[1] = BigInt(STACK_SEGMENT);
|
|
19151
|
-
regs[7] = BigInt(ARGS_SEGMENT);
|
|
19152
|
-
regs[8] = BigInt(argsLength);
|
|
19153
|
-
|
|
19154
|
-
return regs;
|
|
19155
|
-
}
|
|
19156
|
-
|
|
19157
|
-
type index$5_MemorySegment = MemorySegment;
|
|
19158
|
-
declare const index$5_MemorySegment: typeof MemorySegment;
|
|
19159
|
-
declare const index$5_NO_OF_REGISTERS: typeof NO_OF_REGISTERS;
|
|
19160
|
-
type index$5_SpiMemory = SpiMemory;
|
|
19161
|
-
declare const index$5_SpiMemory: typeof SpiMemory;
|
|
19162
|
-
type index$5_SpiProgram = SpiProgram;
|
|
19163
|
-
declare const index$5_SpiProgram: typeof SpiProgram;
|
|
19164
|
-
declare const index$5_decodeStandardProgram: typeof decodeStandardProgram;
|
|
19165
|
-
declare const index$5_getMemorySegment: typeof getMemorySegment;
|
|
19166
|
-
declare const index$5_getRegisters: typeof getRegisters;
|
|
19167
|
-
declare namespace index$5 {
|
|
19168
|
-
export {
|
|
19169
|
-
index$5_MemorySegment as MemorySegment,
|
|
19170
|
-
index$5_NO_OF_REGISTERS as NO_OF_REGISTERS,
|
|
19171
|
-
index$5_SpiMemory as SpiMemory,
|
|
19172
|
-
index$5_SpiProgram as SpiProgram,
|
|
19173
|
-
index$5_decodeStandardProgram as decodeStandardProgram,
|
|
19174
|
-
index$5_getMemorySegment as getMemorySegment,
|
|
19175
|
-
index$5_getRegisters as getRegisters,
|
|
19176
|
-
};
|
|
19177
|
-
}
|
|
19178
|
-
|
|
19179
|
-
declare class Program {
|
|
19180
|
-
static fromSpi(blob: Uint8Array, args: Uint8Array, hasMetadata: boolean) {
|
|
19181
|
-
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
19182
|
-
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
19183
|
-
const regs = new Registers();
|
|
19184
|
-
regs.copyFrom(registers);
|
|
19185
|
-
const memoryBuilder = new MemoryBuilder();
|
|
19186
|
-
|
|
19187
|
-
for (const { start, end, data } of rawMemory.readable) {
|
|
19188
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
19189
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
19190
|
-
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
19191
|
-
}
|
|
19192
|
-
|
|
19193
|
-
for (const { start, end, data } of rawMemory.writeable) {
|
|
19194
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
19195
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
19196
|
-
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
19197
|
-
}
|
|
19198
|
-
|
|
19199
|
-
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
19200
|
-
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
19201
|
-
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
19202
|
-
|
|
19203
|
-
return new Program(code, regs, memory, metadata);
|
|
19204
|
-
}
|
|
19205
|
-
|
|
19206
|
-
static fromGeneric(blob: Uint8Array, hasMetadata: boolean) {
|
|
19207
|
-
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
19208
|
-
const regs = new Registers();
|
|
19209
|
-
const memory = new Memory();
|
|
19210
|
-
return new Program(code, regs, memory, metadata);
|
|
19211
|
-
}
|
|
19212
|
-
|
|
19213
|
-
private constructor(
|
|
19214
|
-
public readonly code: Uint8Array,
|
|
19215
|
-
public readonly registers: Registers,
|
|
19216
|
-
public readonly memory: Memory,
|
|
19217
|
-
public metadata: Uint8Array = new Uint8Array(),
|
|
19218
|
-
) {}
|
|
19219
|
-
}
|
|
19220
|
-
|
|
19221
|
-
/**
|
|
19222
|
-
* A function that splits preimage into metadata and code.
|
|
19223
|
-
*
|
|
19224
|
-
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
19225
|
-
*/
|
|
19226
|
-
declare function extractCodeAndMetadata(blobWithMetadata: Uint8Array) {
|
|
19227
|
-
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
19228
|
-
const metadata = decoder.bytesBlob().raw;
|
|
19229
|
-
const code = decoder.remainingBytes().raw;
|
|
19230
|
-
return { metadata, code };
|
|
19231
|
-
}
|
|
19232
|
-
|
|
19233
|
-
type index$4_Program = Program;
|
|
19234
|
-
declare const index$4_Program: typeof Program;
|
|
19235
|
-
declare const index$4_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
19386
|
+
declare function emptyRegistersBuffer(): Uint8Array {
|
|
19387
|
+
return safeAllocUint8Array(NO_OF_REGISTERS * REGISTER_BYTE_SIZE);
|
|
19388
|
+
}
|
|
19389
|
+
|
|
19390
|
+
type index$4_AccumulationStateUpdate = AccumulationStateUpdate;
|
|
19391
|
+
declare const index$4_AccumulationStateUpdate: typeof AccumulationStateUpdate;
|
|
19392
|
+
declare const index$4_CURRENT_SERVICE_ID: typeof CURRENT_SERVICE_ID;
|
|
19393
|
+
type index$4_EjectError = EjectError;
|
|
19394
|
+
declare const index$4_EjectError: typeof EjectError;
|
|
19395
|
+
type index$4_ForgetPreimageError = ForgetPreimageError;
|
|
19396
|
+
declare const index$4_ForgetPreimageError: typeof ForgetPreimageError;
|
|
19397
|
+
declare const index$4_HostCallResult: typeof HostCallResult;
|
|
19398
|
+
type index$4_InsufficientFundsError = InsufficientFundsError;
|
|
19399
|
+
declare const index$4_MAX_U32: typeof MAX_U32;
|
|
19400
|
+
declare const index$4_MAX_U32_BIG_INT: typeof MAX_U32_BIG_INT;
|
|
19401
|
+
type index$4_MachineId = MachineId;
|
|
19402
|
+
type index$4_MachineInstance = MachineInstance;
|
|
19403
|
+
declare const index$4_MachineInstance: typeof MachineInstance;
|
|
19404
|
+
type index$4_MachineResult = MachineResult;
|
|
19405
|
+
type index$4_MachineStatus = MachineStatus;
|
|
19406
|
+
type index$4_MemoryOperation = MemoryOperation;
|
|
19407
|
+
declare const index$4_MemoryOperation: typeof MemoryOperation;
|
|
19408
|
+
type index$4_NewServiceError = NewServiceError;
|
|
19409
|
+
declare const index$4_NewServiceError: typeof NewServiceError;
|
|
19410
|
+
type index$4_NoMachineError = NoMachineError;
|
|
19411
|
+
type index$4_PagesError = PagesError;
|
|
19412
|
+
declare const index$4_PagesError: typeof PagesError;
|
|
19413
|
+
type index$4_PartialState = PartialState;
|
|
19414
|
+
type index$4_PartiallyUpdatedState<T extends StateSlice = StateSlice> = PartiallyUpdatedState<T>;
|
|
19415
|
+
declare const index$4_PartiallyUpdatedState: typeof PartiallyUpdatedState;
|
|
19416
|
+
type index$4_PeekPokeError = PeekPokeError;
|
|
19417
|
+
declare const index$4_PeekPokeError: typeof PeekPokeError;
|
|
19418
|
+
type index$4_PendingTransfer = PendingTransfer;
|
|
19419
|
+
declare const index$4_PendingTransfer: typeof PendingTransfer;
|
|
19420
|
+
type index$4_PreimageStatus = PreimageStatus;
|
|
19421
|
+
type index$4_PreimageStatusKind = PreimageStatusKind;
|
|
19422
|
+
declare const index$4_PreimageStatusKind: typeof PreimageStatusKind;
|
|
19423
|
+
type index$4_ProgramCounter = ProgramCounter;
|
|
19424
|
+
type index$4_ProvidePreimageError = ProvidePreimageError;
|
|
19425
|
+
declare const index$4_ProvidePreimageError: typeof ProvidePreimageError;
|
|
19426
|
+
type index$4_RefineExternalities = RefineExternalities;
|
|
19427
|
+
type index$4_RequestPreimageError = RequestPreimageError;
|
|
19428
|
+
declare const index$4_RequestPreimageError: typeof RequestPreimageError;
|
|
19429
|
+
declare const index$4_SERVICE_ID_BYTES: typeof SERVICE_ID_BYTES;
|
|
19430
|
+
type index$4_SegmentExportError = SegmentExportError;
|
|
19431
|
+
type index$4_ServiceStateUpdate = ServiceStateUpdate;
|
|
19432
|
+
type index$4_StateSlice = StateSlice;
|
|
19433
|
+
type index$4_TRANSFER_MEMO_BYTES = TRANSFER_MEMO_BYTES;
|
|
19434
|
+
type index$4_TransferError = TransferError;
|
|
19435
|
+
declare const index$4_TransferError: typeof TransferError;
|
|
19436
|
+
type index$4_UnprivilegedError = UnprivilegedError;
|
|
19437
|
+
type index$4_UpdatePrivilegesError = UpdatePrivilegesError;
|
|
19438
|
+
declare const index$4_UpdatePrivilegesError: typeof UpdatePrivilegesError;
|
|
19439
|
+
type index$4_ZeroVoidError = ZeroVoidError;
|
|
19440
|
+
declare const index$4_ZeroVoidError: typeof ZeroVoidError;
|
|
19441
|
+
declare const index$4_clampU64ToU32: typeof clampU64ToU32;
|
|
19442
|
+
declare const index$4_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
19443
|
+
declare const index$4_emptyRegistersBuffer: typeof emptyRegistersBuffer;
|
|
19444
|
+
declare const index$4_getServiceId: typeof getServiceId;
|
|
19445
|
+
declare const index$4_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
19446
|
+
declare const index$4_preimageLenAsU32: typeof preimageLenAsU32;
|
|
19447
|
+
declare const index$4_slotsToPreimageStatus: typeof slotsToPreimageStatus;
|
|
19448
|
+
declare const index$4_toMemoryOperation: typeof toMemoryOperation;
|
|
19449
|
+
declare const index$4_tryAsMachineId: typeof tryAsMachineId;
|
|
19450
|
+
declare const index$4_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
19451
|
+
declare const index$4_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
19236
19452
|
declare namespace index$4 {
|
|
19237
|
-
export {
|
|
19238
|
-
|
|
19239
|
-
index$4_extractCodeAndMetadata as extractCodeAndMetadata,
|
|
19240
|
-
};
|
|
19453
|
+
export { index$4_AccumulationStateUpdate as AccumulationStateUpdate, index$4_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$4_EjectError as EjectError, index$4_ForgetPreimageError as ForgetPreimageError, index$4_HostCallResult as HostCallResult, index$4_MAX_U32 as MAX_U32, index$4_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$4_MachineInstance as MachineInstance, index$4_MemoryOperation as MemoryOperation, index$4_NewServiceError as NewServiceError, index$4_PagesError as PagesError, index$4_PartiallyUpdatedState as PartiallyUpdatedState, index$4_PeekPokeError as PeekPokeError, index$4_PendingTransfer as PendingTransfer, index$4_PreimageStatusKind as PreimageStatusKind, index$4_ProvidePreimageError as ProvidePreimageError, index$4_RequestPreimageError as RequestPreimageError, index$4_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$4_TransferError as TransferError, index$4_UpdatePrivilegesError as UpdatePrivilegesError, index$4_ZeroVoidError as ZeroVoidError, index$4_clampU64ToU32 as clampU64ToU32, index$4_deepCloneMapWithArray as deepCloneMapWithArray, index$4_emptyRegistersBuffer as emptyRegistersBuffer, index$4_getServiceId as getServiceId, index$4_getServiceIdOrCurrent as getServiceIdOrCurrent, index$4_preimageLenAsU32 as preimageLenAsU32, index$4_slotsToPreimageStatus as slotsToPreimageStatus, index$4_toMemoryOperation as toMemoryOperation, index$4_tryAsMachineId as tryAsMachineId, index$4_tryAsProgramCounter as tryAsProgramCounter, index$4_writeServiceIdAsLeBytes as writeServiceIdAsLeBytes };
|
|
19454
|
+
export type { index$4_InsufficientFundsError as InsufficientFundsError, index$4_MachineId as MachineId, index$4_MachineResult as MachineResult, index$4_MachineStatus as MachineStatus, index$4_NoMachineError as NoMachineError, index$4_PartialState as PartialState, index$4_PreimageStatus as PreimageStatus, index$4_ProgramCounter as ProgramCounter, index$4_RefineExternalities as RefineExternalities, index$4_SegmentExportError as SegmentExportError, index$4_ServiceStateUpdate as ServiceStateUpdate, index$4_StateSlice as StateSlice, index$4_TRANSFER_MEMO_BYTES as TRANSFER_MEMO_BYTES, index$4_UnprivilegedError as UnprivilegedError };
|
|
19241
19455
|
}
|
|
19242
19456
|
|
|
19243
19457
|
declare class DebuggerAdapter {
|
|
@@ -19253,11 +19467,11 @@ declare class DebuggerAdapter {
|
|
|
19253
19467
|
}
|
|
19254
19468
|
|
|
19255
19469
|
resetGeneric(rawProgram: Uint8Array, flatRegisters: Uint8Array, initialGas: bigint) {
|
|
19256
|
-
this.pvm.
|
|
19470
|
+
this.pvm.resetGeneric(rawProgram, 0, tryAsGas(initialGas), new Registers(flatRegisters));
|
|
19257
19471
|
}
|
|
19258
19472
|
|
|
19259
19473
|
reset(rawProgram: Uint8Array, pc: number, gas: bigint, maybeRegisters?: Registers, maybeMemory?: Memory) {
|
|
19260
|
-
this.pvm.
|
|
19474
|
+
this.pvm.resetGeneric(rawProgram, pc, tryAsGas(gas), maybeRegisters, maybeMemory);
|
|
19261
19475
|
}
|
|
19262
19476
|
|
|
19263
19477
|
getPageDump(pageNumber: number): null | Uint8Array {
|
|
@@ -19280,7 +19494,7 @@ declare class DebuggerAdapter {
|
|
|
19280
19494
|
}
|
|
19281
19495
|
|
|
19282
19496
|
setMemory(address: number, value: Uint8Array) {
|
|
19283
|
-
this.pvm.
|
|
19497
|
+
this.pvm.memory.storeFrom(tryAsMemoryIndex(address), value);
|
|
19284
19498
|
}
|
|
19285
19499
|
|
|
19286
19500
|
getExitArg(): number {
|
|
@@ -19307,11 +19521,11 @@ declare class DebuggerAdapter {
|
|
|
19307
19521
|
}
|
|
19308
19522
|
|
|
19309
19523
|
getRegisters(): BigUint64Array {
|
|
19310
|
-
return this.pvm.
|
|
19524
|
+
return this.pvm.registers.getAllU64();
|
|
19311
19525
|
}
|
|
19312
19526
|
|
|
19313
19527
|
setRegisters(registers: Uint8Array) {
|
|
19314
|
-
this.pvm.
|
|
19528
|
+
this.pvm.registers.copyFrom(new Registers(registers));
|
|
19315
19529
|
}
|
|
19316
19530
|
|
|
19317
19531
|
getProgramCounter(): number {
|
|
@@ -19323,11 +19537,11 @@ declare class DebuggerAdapter {
|
|
|
19323
19537
|
}
|
|
19324
19538
|
|
|
19325
19539
|
getGasLeft(): bigint {
|
|
19326
|
-
return BigInt(this.pvm.
|
|
19540
|
+
return BigInt(this.pvm.gas.get());
|
|
19327
19541
|
}
|
|
19328
19542
|
|
|
19329
19543
|
setGasLeft(gas: bigint) {
|
|
19330
|
-
this.pvm.
|
|
19544
|
+
this.pvm.gas.set(tryAsGas(gas));
|
|
19331
19545
|
}
|
|
19332
19546
|
}
|
|
19333
19547
|
|
|
@@ -19354,8 +19568,6 @@ declare const index$3_HostCallMemory: typeof HostCallMemory;
|
|
|
19354
19568
|
type index$3_HostCallRegisters = HostCallRegisters;
|
|
19355
19569
|
declare const index$3_HostCallRegisters: typeof HostCallRegisters;
|
|
19356
19570
|
declare const index$3_HostCallResult: typeof HostCallResult;
|
|
19357
|
-
type index$3_IHostCallMemory = IHostCallMemory;
|
|
19358
|
-
type index$3_IHostCallRegisters = IHostCallRegisters;
|
|
19359
19571
|
type index$3_ImmediateDecoder = ImmediateDecoder;
|
|
19360
19572
|
declare const index$3_ImmediateDecoder: typeof ImmediateDecoder;
|
|
19361
19573
|
type index$3_InsufficientFundsError = InsufficientFundsError;
|
|
@@ -19438,6 +19650,7 @@ declare const index$3_clampU64ToU32: typeof clampU64ToU32;
|
|
|
19438
19650
|
declare const index$3_createResults: typeof createResults;
|
|
19439
19651
|
declare const index$3_decodeStandardProgram: typeof decodeStandardProgram;
|
|
19440
19652
|
declare const index$3_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
19653
|
+
declare const index$3_emptyRegistersBuffer: typeof emptyRegistersBuffer;
|
|
19441
19654
|
declare const index$3_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
19442
19655
|
declare const index$3_getServiceId: typeof getServiceId;
|
|
19443
19656
|
declare const index$3_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
@@ -19456,8 +19669,8 @@ declare const index$3_tryAsMachineId: typeof tryAsMachineId;
|
|
|
19456
19669
|
declare const index$3_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
19457
19670
|
declare const index$3_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
19458
19671
|
declare namespace index$3 {
|
|
19459
|
-
export { index$3_AccumulationStateUpdate as AccumulationStateUpdate, index$3_ArgsDecoder as ArgsDecoder, index$3_ArgumentType as ArgumentType, index$3_BasicBlocks as BasicBlocks, index$3_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$3_EjectError as EjectError, index$3_ExtendedWitdthImmediateDecoder as ExtendedWitdthImmediateDecoder, index$3_ForgetPreimageError as ForgetPreimageError, index$3_HostCallMemory as HostCallMemory, index$3_HostCallRegisters as HostCallRegisters, index$3_HostCallResult as HostCallResult, index$3_ImmediateDecoder as ImmediateDecoder, index$3_MAX_U32 as MAX_U32, index$3_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$3_MachineInstance as MachineInstance, index$3_Mask as Mask, index$3_MemoryOperation as MemoryOperation, index$3_MemorySegment as MemorySegment, NO_OF_REGISTERS$1 as NO_OF_REGISTERS, index$3_NewServiceError as NewServiceError, index$3_NibblesDecoder as NibblesDecoder, index$3_PagesError as PagesError, index$3_PartiallyUpdatedState as PartiallyUpdatedState, index$3_PeekPokeError as PeekPokeError, index$3_PendingTransfer as PendingTransfer, index$3_PreimageStatusKind as PreimageStatusKind, index$3_Program as Program, index$3_ProgramDecoder as ProgramDecoder, index$3_ProvidePreimageError as ProvidePreimageError, DebuggerAdapter as Pvm, index$3_Registers as Registers, index$3_RequestPreimageError as RequestPreimageError, Result$2 as Result, index$3_RichTaggedError as RichTaggedError, index$3_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$3_SpiMemory as SpiMemory, index$3_SpiProgram as SpiProgram, index$3_TransferError as TransferError, index$3_UpdatePrivilegesError as UpdatePrivilegesError, index$3_WithDebug as WithDebug, index$3_ZeroVoidError as ZeroVoidError, index$3___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$3_asOpaqueType as asOpaqueType, index$3_assertEmpty as assertEmpty, index$3_assertNever as assertNever, index$l as block, index$s as bytes, index$3_check as check, index$3_clampU64ToU32 as clampU64ToU32, index$3_createResults as createResults, index$3_decodeStandardProgram as decodeStandardProgram, index$3_deepCloneMapWithArray as deepCloneMapWithArray, index$3_extractCodeAndMetadata as extractCodeAndMetadata, index$3_getServiceId as getServiceId, index$3_getServiceIdOrCurrent as getServiceIdOrCurrent, index$p as hash, index$3_inspect as inspect, index$3_instructionArgumentTypeMap as instructionArgumentTypeMap, index$
|
|
19460
|
-
export type { index$3_Args as Args, index$3_EnumMapping as EnumMapping, index$3_ErrorResult as ErrorResult, index$
|
|
19672
|
+
export { index$3_AccumulationStateUpdate as AccumulationStateUpdate, index$3_ArgsDecoder as ArgsDecoder, index$3_ArgumentType as ArgumentType, index$3_BasicBlocks as BasicBlocks, index$3_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$3_EjectError as EjectError, index$3_ExtendedWitdthImmediateDecoder as ExtendedWitdthImmediateDecoder, index$3_ForgetPreimageError as ForgetPreimageError, index$3_HostCallMemory as HostCallMemory, index$3_HostCallRegisters as HostCallRegisters, index$3_HostCallResult as HostCallResult, index$3_ImmediateDecoder as ImmediateDecoder, index$3_MAX_U32 as MAX_U32, index$3_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$3_MachineInstance as MachineInstance, index$3_Mask as Mask, index$3_MemoryOperation as MemoryOperation, index$3_MemorySegment as MemorySegment, NO_OF_REGISTERS$1 as NO_OF_REGISTERS, index$3_NewServiceError as NewServiceError, index$3_NibblesDecoder as NibblesDecoder, index$3_PagesError as PagesError, index$3_PartiallyUpdatedState as PartiallyUpdatedState, index$3_PeekPokeError as PeekPokeError, index$3_PendingTransfer as PendingTransfer, index$3_PreimageStatusKind as PreimageStatusKind, index$3_Program as Program, index$3_ProgramDecoder as ProgramDecoder, index$3_ProvidePreimageError as ProvidePreimageError, DebuggerAdapter as Pvm, index$3_Registers as Registers, index$3_RequestPreimageError as RequestPreimageError, Result$2 as Result, index$3_RichTaggedError as RichTaggedError, index$3_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$3_SpiMemory as SpiMemory, index$3_SpiProgram as SpiProgram, index$3_TransferError as TransferError, index$3_UpdatePrivilegesError as UpdatePrivilegesError, index$3_WithDebug as WithDebug, index$3_ZeroVoidError as ZeroVoidError, index$3___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$3_asOpaqueType as asOpaqueType, index$3_assertEmpty as assertEmpty, index$3_assertNever as assertNever, index$l as block, index$s as bytes, index$3_check as check, index$3_clampU64ToU32 as clampU64ToU32, index$3_createResults as createResults, index$3_decodeStandardProgram as decodeStandardProgram, index$3_deepCloneMapWithArray as deepCloneMapWithArray, index$3_emptyRegistersBuffer as emptyRegistersBuffer, index$3_extractCodeAndMetadata as extractCodeAndMetadata, index$3_getServiceId as getServiceId, index$3_getServiceIdOrCurrent as getServiceIdOrCurrent, index$p as hash, index$3_inspect as inspect, index$3_instructionArgumentTypeMap as instructionArgumentTypeMap, index$6 as interpreter, index$3_isBrowser as isBrowser, index$3_isTaggedError as isTaggedError, index$3_maybeTaggedErrorToString as maybeTaggedErrorToString, index$3_measure as measure, index$r as numbers, index$3_preimageLenAsU32 as preimageLenAsU32, index$3_resultToString as resultToString, index$3_seeThrough as seeThrough, index$3_slotsToPreimageStatus as slotsToPreimageStatus, index$3_toMemoryOperation as toMemoryOperation, index$3_tryAsMachineId as tryAsMachineId, index$3_tryAsProgramCounter as tryAsProgramCounter, index$3_writeServiceIdAsLeBytes as writeServiceIdAsLeBytes };
|
|
19673
|
+
export type { index$3_Args as Args, index$3_EnumMapping as EnumMapping, index$3_ErrorResult as ErrorResult, index$3_InsufficientFundsError as InsufficientFundsError, index$3_MachineId as MachineId, index$3_MachineResult as MachineResult, index$3_MachineStatus as MachineStatus, index$3_NoMachineError as NoMachineError, index$3_OK as OK, index$3_OkResult as OkResult, index$3_Opaque as Opaque, index$3_PartialState as PartialState, index$3_PreimageStatus as PreimageStatus, index$3_ProgramCounter as ProgramCounter, index$3_RefineExternalities as RefineExternalities, index$3_SegmentExportError as SegmentExportError, index$3_ServiceStateUpdate as ServiceStateUpdate, index$3_StateSlice as StateSlice, index$3_StringLiteral as StringLiteral, index$3_TRANSFER_MEMO_BYTES as TRANSFER_MEMO_BYTES, index$3_TaggedError as TaggedError, index$3_TokenOf as TokenOf, index$3_Uninstantiable as Uninstantiable, index$3_UnprivilegedError as UnprivilegedError, index$3_WithOpaque as WithOpaque };
|
|
19461
19674
|
}
|
|
19462
19675
|
|
|
19463
19676
|
declare const ENTROPY_BYTES = 32;
|
|
@@ -20349,4 +20562,4 @@ declare namespace index {
|
|
|
20349
20562
|
export type { index_PreimagesInput as PreimagesInput, index_PreimagesState as PreimagesState, index_PreimagesStateUpdate as PreimagesStateUpdate };
|
|
20350
20563
|
}
|
|
20351
20564
|
|
|
20352
|
-
export { index$l as block, index$j as block_json, index$s as bytes, index$q as codec, index$o as collections, index$m as config, index$h as config_node, index$n as crypto, index$c as database, index$b as erasure_coding, index$9 as fuzz_proto, index$p as hash, index$
|
|
20565
|
+
export { index$l as block, index$j as block_json, index$s as bytes, index$q as codec, index$o as collections, index$m as config, index$h as config_node, index$n as crypto, index$c as database, index$b as erasure_coding, index$9 as fuzz_proto, index$p as hash, index$4 as jam_host_calls, index$k as json_parser, index$i as logger, index$f as mmr, index$r as numbers, index$t as ordering, index$3 as pvm, index$5 as pvm_host_calls, index$6 as pvm_interpreter, index$7 as pvm_program, index$8 as pvm_spi_decoder, index$2 as shuffling, index$e as state, index$1 as state_json, index$d as state_merkleization, index as transition, index$g as trie, index$u as utils };
|