@typeberry/lib 0.2.0-0303f5b → 0.2.0-3f440a7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +2412 -1731
- package/index.d.ts +2101 -1909
- package/index.js +2410 -1729
- package/package.json +1 -1
package/index.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 {
|
|
@@ -242,6 +238,14 @@ declare abstract class WithDebug {
|
|
|
242
238
|
}
|
|
243
239
|
}
|
|
244
240
|
|
|
241
|
+
declare function lazyInspect<T>(obj: T) {
|
|
242
|
+
return {
|
|
243
|
+
toString() {
|
|
244
|
+
return inspect(obj);
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
245
249
|
/**
|
|
246
250
|
* The function will produce relative path resolver that is adjusted
|
|
247
251
|
* for package location within the workspace.
|
|
@@ -769,6 +773,7 @@ declare const index$u_inspect: typeof inspect;
|
|
|
769
773
|
declare const index$u_isBrowser: typeof isBrowser;
|
|
770
774
|
declare const index$u_isResult: typeof isResult;
|
|
771
775
|
declare const index$u_isTaggedError: typeof isTaggedError;
|
|
776
|
+
declare const index$u_lazyInspect: typeof lazyInspect;
|
|
772
777
|
declare const index$u_maybeTaggedErrorToString: typeof maybeTaggedErrorToString;
|
|
773
778
|
declare const index$u_measure: typeof measure;
|
|
774
779
|
declare const index$u_oomWarningPrinted: typeof oomWarningPrinted;
|
|
@@ -780,7 +785,7 @@ declare const index$u_seeThrough: typeof seeThrough;
|
|
|
780
785
|
declare const index$u_trimStack: typeof trimStack;
|
|
781
786
|
declare const index$u_workspacePathFix: typeof workspacePathFix;
|
|
782
787
|
declare namespace index$u {
|
|
783
|
-
export { index$u_ALL_VERSIONS_IN_ORDER as ALL_VERSIONS_IN_ORDER, index$u_CURRENT_SUITE as CURRENT_SUITE, index$u_CURRENT_VERSION as CURRENT_VERSION, index$u_Compatibility as Compatibility, index$u_DEFAULT_SUITE as DEFAULT_SUITE, index$u_DEFAULT_VERSION as DEFAULT_VERSION, index$u_ErrorsCollector as ErrorsCollector, index$u_GpVersion as GpVersion, MAX_LENGTH$1 as MAX_LENGTH, Result$2 as Result, index$u_RichTaggedError as RichTaggedError, index$u_TEST_COMPARE_USING as TEST_COMPARE_USING, index$u_TestSuite as TestSuite, index$u_WithDebug as WithDebug, index$u___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$u_asOpaqueType as asOpaqueType, index$u_assertEmpty as assertEmpty, index$u_assertNever as assertNever, index$u_callCompareFunction as callCompareFunction, index$u_check as check, index$u_deepEqual as deepEqual, index$u_getAllKeysSorted as getAllKeysSorted, index$u_inspect as inspect, index$u_isBrowser as isBrowser, index$u_isResult as isResult, index$u_isTaggedError as isTaggedError, index$u_maybeTaggedErrorToString as maybeTaggedErrorToString, index$u_measure as measure, index$u_oomWarningPrinted as oomWarningPrinted, index$u_parseCurrentSuite as parseCurrentSuite, index$u_parseCurrentVersion as parseCurrentVersion, index$u_resultToString as resultToString, index$u_safeAllocUint8Array as safeAllocUint8Array, index$u_seeThrough as seeThrough, index$u_trimStack as trimStack, index$u_workspacePathFix as workspacePathFix };
|
|
788
|
+
export { index$u_ALL_VERSIONS_IN_ORDER as ALL_VERSIONS_IN_ORDER, index$u_CURRENT_SUITE as CURRENT_SUITE, index$u_CURRENT_VERSION as CURRENT_VERSION, index$u_Compatibility as Compatibility, index$u_DEFAULT_SUITE as DEFAULT_SUITE, index$u_DEFAULT_VERSION as DEFAULT_VERSION, index$u_ErrorsCollector as ErrorsCollector, index$u_GpVersion as GpVersion, MAX_LENGTH$1 as MAX_LENGTH, Result$2 as Result, index$u_RichTaggedError as RichTaggedError, index$u_TEST_COMPARE_USING as TEST_COMPARE_USING, index$u_TestSuite as TestSuite, index$u_WithDebug as WithDebug, index$u___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$u_asOpaqueType as asOpaqueType, index$u_assertEmpty as assertEmpty, index$u_assertNever as assertNever, index$u_callCompareFunction as callCompareFunction, index$u_check as check, index$u_deepEqual as deepEqual, index$u_getAllKeysSorted as getAllKeysSorted, index$u_inspect as inspect, index$u_isBrowser as isBrowser, index$u_isResult as isResult, index$u_isTaggedError as isTaggedError, index$u_lazyInspect as lazyInspect, index$u_maybeTaggedErrorToString as maybeTaggedErrorToString, index$u_measure as measure, index$u_oomWarningPrinted as oomWarningPrinted, index$u_parseCurrentSuite as parseCurrentSuite, index$u_parseCurrentVersion as parseCurrentVersion, index$u_resultToString as resultToString, index$u_safeAllocUint8Array as safeAllocUint8Array, index$u_seeThrough as seeThrough, index$u_trimStack as trimStack, index$u_workspacePathFix as workspacePathFix };
|
|
784
789
|
export type { index$u_DeepEqualOptions as DeepEqualOptions, index$u_EnumMapping as EnumMapping, index$u_ErrorResult as ErrorResult, index$u_OK as OK, index$u_OkResult as OkResult, index$u_Opaque as Opaque, index$u_StringLiteral as StringLiteral, index$u_TaggedError as TaggedError, index$u_TokenOf as TokenOf, index$u_Uninstantiable as Uninstantiable, index$u_WithOpaque as WithOpaque };
|
|
785
790
|
}
|
|
786
791
|
|
|
@@ -5117,6 +5122,17 @@ declare class Bootnode implements PeerAddress {
|
|
|
5117
5122
|
}
|
|
5118
5123
|
}
|
|
5119
5124
|
|
|
5125
|
+
/** Implemented PVM Backends names in THE SAME ORDER as enum. */
|
|
5126
|
+
declare const PvmBackendNames = ["built-in", "ananas"];
|
|
5127
|
+
|
|
5128
|
+
/** Implemented PVM Backends to choose from. */
|
|
5129
|
+
declare enum PvmBackend {
|
|
5130
|
+
/** Built-in aka. Typeberry 🫐 interpreter. */
|
|
5131
|
+
BuiltIn = 0,
|
|
5132
|
+
/** Ananas 🍍 interpreter. */
|
|
5133
|
+
Ananas = 1,
|
|
5134
|
+
}
|
|
5135
|
+
|
|
5120
5136
|
type index$m_Bootnode = Bootnode;
|
|
5121
5137
|
declare const index$m_Bootnode: typeof Bootnode;
|
|
5122
5138
|
type index$m_ChainSpec = ChainSpec;
|
|
@@ -5128,10 +5144,13 @@ declare const index$m_EST_VALIDATORS: typeof EST_VALIDATORS;
|
|
|
5128
5144
|
declare const index$m_EST_VALIDATORS_SUPER_MAJORITY: typeof EST_VALIDATORS_SUPER_MAJORITY;
|
|
5129
5145
|
type index$m_PeerAddress = PeerAddress;
|
|
5130
5146
|
type index$m_PeerId = PeerId;
|
|
5147
|
+
type index$m_PvmBackend = PvmBackend;
|
|
5148
|
+
declare const index$m_PvmBackend: typeof PvmBackend;
|
|
5149
|
+
declare const index$m_PvmBackendNames: typeof PvmBackendNames;
|
|
5131
5150
|
declare const index$m_fullChainSpec: typeof fullChainSpec;
|
|
5132
5151
|
declare const index$m_tinyChainSpec: typeof tinyChainSpec;
|
|
5133
5152
|
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 };
|
|
5153
|
+
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
5154
|
export type { index$m_PeerAddress as PeerAddress, index$m_PeerId as PeerId };
|
|
5136
5155
|
}
|
|
5137
5156
|
|
|
@@ -8154,7 +8173,8 @@ declare const DEFAULT_CONFIG = "default";
|
|
|
8154
8173
|
|
|
8155
8174
|
declare const NODE_DEFAULTS = {
|
|
8156
8175
|
name: isBrowser() ? "browser" : os.hostname(),
|
|
8157
|
-
config: DEFAULT_CONFIG,
|
|
8176
|
+
config: [DEFAULT_CONFIG],
|
|
8177
|
+
pvm: PvmBackend.BuiltIn,
|
|
8158
8178
|
};
|
|
8159
8179
|
|
|
8160
8180
|
/** Chain spec chooser. */
|
|
@@ -8207,52 +8227,173 @@ declare class NodeConfiguration {
|
|
|
8207
8227
|
) {}
|
|
8208
8228
|
}
|
|
8209
8229
|
|
|
8210
|
-
declare function loadConfig(
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8230
|
+
declare function loadConfig(config: string[], withRelPath: (p: string) => string): NodeConfiguration {
|
|
8231
|
+
logger.log`🔧 Loading config`;
|
|
8232
|
+
let mergedJson: AnyJsonObject = {};
|
|
8233
|
+
|
|
8234
|
+
for (const entry of config) {
|
|
8235
|
+
logger.log`🔧 Applying '${entry}'`;
|
|
8236
|
+
|
|
8237
|
+
if (entry === DEV_CONFIG) {
|
|
8238
|
+
mergedJson = structuredClone(configs.dev); // clone to avoid mutating the original config. not doing a merge since dev and default should theoretically replace all properties.
|
|
8239
|
+
continue;
|
|
8240
|
+
}
|
|
8241
|
+
|
|
8242
|
+
if (entry === DEFAULT_CONFIG) {
|
|
8243
|
+
mergedJson = structuredClone(configs.default);
|
|
8244
|
+
continue;
|
|
8245
|
+
}
|
|
8246
|
+
|
|
8247
|
+
// try to parse as JSON
|
|
8248
|
+
try {
|
|
8249
|
+
const parsed = JSON.parse(entry);
|
|
8250
|
+
deepMerge(mergedJson, parsed);
|
|
8251
|
+
continue;
|
|
8252
|
+
} catch {}
|
|
8215
8253
|
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8254
|
+
// if not, try to load as file
|
|
8255
|
+
if (entry.indexOf("=") === -1 && entry.endsWith(".json")) {
|
|
8256
|
+
try {
|
|
8257
|
+
const configFile = fs.readFileSync(withRelPath(entry), "utf8");
|
|
8258
|
+
const parsed = JSON.parse(configFile);
|
|
8259
|
+
deepMerge(mergedJson, parsed);
|
|
8260
|
+
} catch (e) {
|
|
8261
|
+
throw new Error(`Unable to load config from ${entry}: ${e}`);
|
|
8262
|
+
}
|
|
8263
|
+
} else {
|
|
8264
|
+
// finally try to process as a pseudo-jq query
|
|
8265
|
+
try {
|
|
8266
|
+
processQuery(mergedJson, entry, withRelPath);
|
|
8267
|
+
} catch (e) {
|
|
8268
|
+
throw new Error(`Error while processing '${entry}': ${e}`);
|
|
8269
|
+
}
|
|
8270
|
+
}
|
|
8219
8271
|
}
|
|
8220
8272
|
|
|
8221
8273
|
try {
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
return parseFromJson(parsed, NodeConfiguration.fromJson);
|
|
8274
|
+
const parsed = parseFromJson(mergedJson, NodeConfiguration.fromJson);
|
|
8275
|
+
logger.log`🔧 Config ready`;
|
|
8276
|
+
return parsed;
|
|
8226
8277
|
} catch (e) {
|
|
8227
|
-
throw new Error(`Unable to
|
|
8278
|
+
throw new Error(`Unable to parse config: ${e}`);
|
|
8279
|
+
}
|
|
8280
|
+
}
|
|
8281
|
+
|
|
8282
|
+
declare function deepMerge(target: AnyJsonObject, source: JsonValue): void {
|
|
8283
|
+
if (!isJsonObject(source)) {
|
|
8284
|
+
throw new Error(`Expected object, got ${source}`);
|
|
8285
|
+
}
|
|
8286
|
+
for (const key in source) {
|
|
8287
|
+
if (isJsonObject(source[key])) {
|
|
8288
|
+
if (!isJsonObject(target[key])) {
|
|
8289
|
+
target[key] = {};
|
|
8290
|
+
}
|
|
8291
|
+
deepMerge(target[key], source[key]);
|
|
8292
|
+
} else {
|
|
8293
|
+
target[key] = source[key];
|
|
8294
|
+
}
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
|
|
8298
|
+
/**
|
|
8299
|
+
* Caution: updates input directly.
|
|
8300
|
+
* Processes a pseudo-jq query. Syntax:
|
|
8301
|
+
* .path.to.value = { ... } - updates value with the specified object by replacement
|
|
8302
|
+
* .path.to.value += { ... } - updates value with the specified object by merging
|
|
8303
|
+
* .path.to.value = file.json - updates value with the contents of file.json
|
|
8304
|
+
* .path.to.value += file.json - merges the contents of file.json onto value
|
|
8305
|
+
*/
|
|
8306
|
+
declare function processQuery(input: AnyJsonObject, query: string, withRelPath: (p: string) => string): void {
|
|
8307
|
+
const queryParts = query.split("=");
|
|
8308
|
+
|
|
8309
|
+
if (queryParts.length === 2) {
|
|
8310
|
+
let [path, value] = queryParts.map((part) => part.trim());
|
|
8311
|
+
let merge = false;
|
|
8312
|
+
|
|
8313
|
+
// detect += syntax
|
|
8314
|
+
if (path.endsWith("+")) {
|
|
8315
|
+
merge = true;
|
|
8316
|
+
path = path.slice(0, -1);
|
|
8317
|
+
}
|
|
8318
|
+
|
|
8319
|
+
let parsedValue: JsonValue;
|
|
8320
|
+
if (value.endsWith(".json")) {
|
|
8321
|
+
try {
|
|
8322
|
+
const configFile = fs.readFileSync(withRelPath(value), "utf8");
|
|
8323
|
+
const parsed = JSON.parse(configFile);
|
|
8324
|
+
parsedValue = parsed;
|
|
8325
|
+
} catch (e) {
|
|
8326
|
+
throw new Error(`Unable to load config from ${value}: ${e}`);
|
|
8327
|
+
}
|
|
8328
|
+
} else {
|
|
8329
|
+
try {
|
|
8330
|
+
parsedValue = JSON.parse(value);
|
|
8331
|
+
} catch (e) {
|
|
8332
|
+
throw new Error(`Unrecognized syntax '${value}': ${e}`);
|
|
8333
|
+
}
|
|
8334
|
+
}
|
|
8335
|
+
|
|
8336
|
+
let pathParts = path.split(".");
|
|
8337
|
+
|
|
8338
|
+
// allow leading dot in path
|
|
8339
|
+
if (pathParts[0] === "") {
|
|
8340
|
+
pathParts = pathParts.slice(1);
|
|
8341
|
+
}
|
|
8342
|
+
|
|
8343
|
+
let target = input;
|
|
8344
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
8345
|
+
const part = pathParts[i];
|
|
8346
|
+
if (!isJsonObject(target[part])) {
|
|
8347
|
+
target[part] = {};
|
|
8348
|
+
}
|
|
8349
|
+
if (i === pathParts.length - 1) {
|
|
8350
|
+
if (merge) {
|
|
8351
|
+
deepMerge(target[part], parsedValue);
|
|
8352
|
+
} else {
|
|
8353
|
+
target[part] = parsedValue;
|
|
8354
|
+
}
|
|
8355
|
+
return;
|
|
8356
|
+
}
|
|
8357
|
+
target = target[part];
|
|
8358
|
+
}
|
|
8228
8359
|
}
|
|
8360
|
+
|
|
8361
|
+
throw new Error("Unrecognized syntax.");
|
|
8362
|
+
}
|
|
8363
|
+
|
|
8364
|
+
type JsonValue = string | number | boolean | null | AnyJsonObject | JsonArray;
|
|
8365
|
+
|
|
8366
|
+
interface AnyJsonObject {
|
|
8367
|
+
[key: string]: JsonValue;
|
|
8368
|
+
}
|
|
8369
|
+
|
|
8370
|
+
interface JsonArray extends Array<JsonValue> {}
|
|
8371
|
+
|
|
8372
|
+
declare function isJsonObject(value: JsonValue): value is AnyJsonObject {
|
|
8373
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8229
8374
|
}
|
|
8230
8375
|
|
|
8376
|
+
type index$h_AnyJsonObject = AnyJsonObject;
|
|
8231
8377
|
declare const index$h_DEFAULT_CONFIG: typeof DEFAULT_CONFIG;
|
|
8232
8378
|
declare const index$h_DEV_CONFIG: typeof DEV_CONFIG;
|
|
8233
8379
|
type index$h_JipChainSpec = JipChainSpec;
|
|
8234
8380
|
declare const index$h_JipChainSpec: typeof JipChainSpec;
|
|
8381
|
+
type index$h_JsonArray = JsonArray;
|
|
8382
|
+
type index$h_JsonValue = JsonValue;
|
|
8235
8383
|
type index$h_KnownChainSpec = KnownChainSpec;
|
|
8236
8384
|
declare const index$h_KnownChainSpec: typeof KnownChainSpec;
|
|
8237
8385
|
declare const index$h_NODE_DEFAULTS: typeof NODE_DEFAULTS;
|
|
8238
8386
|
type index$h_NodeConfiguration = NodeConfiguration;
|
|
8239
8387
|
declare const index$h_NodeConfiguration: typeof NodeConfiguration;
|
|
8388
|
+
declare const index$h_deepMerge: typeof deepMerge;
|
|
8389
|
+
declare const index$h_isJsonObject: typeof isJsonObject;
|
|
8240
8390
|
declare const index$h_knownChainSpecFromJson: typeof knownChainSpecFromJson;
|
|
8241
8391
|
declare const index$h_loadConfig: typeof loadConfig;
|
|
8242
8392
|
declare const index$h_parseBootnode: typeof parseBootnode;
|
|
8393
|
+
declare const index$h_processQuery: typeof processQuery;
|
|
8243
8394
|
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
|
-
};
|
|
8395
|
+
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 };
|
|
8396
|
+
export type { index$h_AnyJsonObject as AnyJsonObject, index$h_JsonArray as JsonArray, index$h_JsonValue as JsonValue };
|
|
8256
8397
|
}
|
|
8257
8398
|
|
|
8258
8399
|
/**
|
|
@@ -9977,25 +10118,6 @@ declare class LookupHistoryItem {
|
|
|
9977
10118
|
}
|
|
9978
10119
|
}
|
|
9979
10120
|
|
|
9980
|
-
/** Dictionary entry of services that auto-accumulate every block. */
|
|
9981
|
-
declare class AutoAccumulate {
|
|
9982
|
-
static Codec = codec.Class(AutoAccumulate, {
|
|
9983
|
-
service: codec.u32.asOpaque<ServiceId>(),
|
|
9984
|
-
gasLimit: codec.u64.asOpaque<ServiceGas>(),
|
|
9985
|
-
});
|
|
9986
|
-
|
|
9987
|
-
static create({ service, gasLimit }: CodecRecord<AutoAccumulate>) {
|
|
9988
|
-
return new AutoAccumulate(service, gasLimit);
|
|
9989
|
-
}
|
|
9990
|
-
|
|
9991
|
-
private constructor(
|
|
9992
|
-
/** Service id that auto-accumulates. */
|
|
9993
|
-
readonly service: ServiceId,
|
|
9994
|
-
/** Gas limit for auto-accumulation. */
|
|
9995
|
-
readonly gasLimit: ServiceGas,
|
|
9996
|
-
) {}
|
|
9997
|
-
}
|
|
9998
|
-
|
|
9999
10121
|
/**
|
|
10000
10122
|
* https://graypaper.fluffylabs.dev/#/ab2cdbd/114402114402?v=0.7.2
|
|
10001
10123
|
*/
|
|
@@ -10008,7 +10130,9 @@ declare class PrivilegedServices {
|
|
|
10008
10130
|
registrar: Compatibility.isGreaterOrEqual(GpVersion.V0_7_1)
|
|
10009
10131
|
? codec.u32.asOpaque<ServiceId>()
|
|
10010
10132
|
: ignoreValueWithDefault(tryAsServiceId(2 ** 32 - 1)),
|
|
10011
|
-
autoAccumulateServices:
|
|
10133
|
+
autoAccumulateServices: codec.dictionary(codec.u32.asOpaque<ServiceId>(), codec.u64.asOpaque<ServiceGas>(), {
|
|
10134
|
+
sortKeys: (a, b) => a - b,
|
|
10135
|
+
}),
|
|
10012
10136
|
});
|
|
10013
10137
|
|
|
10014
10138
|
static create(a: CodecRecord<PrivilegedServices>) {
|
|
@@ -10033,7 +10157,7 @@ declare class PrivilegedServices {
|
|
|
10033
10157
|
/** `χ_A`: Manages authorization queue one for each core. */
|
|
10034
10158
|
readonly assigners: PerCore<ServiceId>,
|
|
10035
10159
|
/** `χ_Z`: Dictionary of services that auto-accumulate every block with their gas limit. */
|
|
10036
|
-
readonly autoAccumulateServices:
|
|
10160
|
+
readonly autoAccumulateServices: Map<ServiceId, ServiceGas>,
|
|
10037
10161
|
) {}
|
|
10038
10162
|
}
|
|
10039
10163
|
|
|
@@ -11350,7 +11474,7 @@ declare class InMemoryState extends WithDebug implements State, WithStateView, E
|
|
|
11350
11474
|
assigners: tryAsPerCore(new Array(spec.coresCount).fill(tryAsServiceId(0)), spec),
|
|
11351
11475
|
delegator: tryAsServiceId(0),
|
|
11352
11476
|
registrar: tryAsServiceId(MAX_VALUE),
|
|
11353
|
-
autoAccumulateServices:
|
|
11477
|
+
autoAccumulateServices: new Map(),
|
|
11354
11478
|
}),
|
|
11355
11479
|
accumulationOutputLog: SortedArray.fromArray(accumulationOutputComparator, []),
|
|
11356
11480
|
services: new Map(),
|
|
@@ -11406,8 +11530,6 @@ type index$e_AccumulationQueue = AccumulationQueue;
|
|
|
11406
11530
|
type index$e_AccumulationQueueView = AccumulationQueueView;
|
|
11407
11531
|
type index$e_AuthorizationPool = AuthorizationPool;
|
|
11408
11532
|
type index$e_AuthorizationQueue = AuthorizationQueue;
|
|
11409
|
-
type index$e_AutoAccumulate = AutoAccumulate;
|
|
11410
|
-
declare const index$e_AutoAccumulate: typeof AutoAccumulate;
|
|
11411
11533
|
type index$e_AvailabilityAssignment = AvailabilityAssignment;
|
|
11412
11534
|
declare const index$e_AvailabilityAssignment: typeof AvailabilityAssignment;
|
|
11413
11535
|
type index$e_AvailabilityAssignmentsView = AvailabilityAssignmentsView;
|
|
@@ -11516,7 +11638,7 @@ declare const index$e_validatorsDataCodec: typeof validatorsDataCodec;
|
|
|
11516
11638
|
declare const index$e_workReportsSortedSetCodec: typeof workReportsSortedSetCodec;
|
|
11517
11639
|
declare const index$e_zeroSizeHint: typeof zeroSizeHint;
|
|
11518
11640
|
declare namespace index$e {
|
|
11519
|
-
export { index$e_AccumulationOutput as AccumulationOutput, index$
|
|
11641
|
+
export { index$e_AccumulationOutput as AccumulationOutput, index$e_AvailabilityAssignment as AvailabilityAssignment, index$e_BASE_SERVICE_BALANCE as BASE_SERVICE_BALANCE, index$e_BlockState as BlockState, index$e_CoreStatistics as CoreStatistics, index$e_DisputesRecords as DisputesRecords, index$e_ELECTIVE_BYTE_BALANCE as ELECTIVE_BYTE_BALANCE, index$e_ELECTIVE_ITEM_BALANCE as ELECTIVE_ITEM_BALANCE, index$e_InMemoryService as InMemoryService, index$e_InMemoryState as InMemoryState, index$e_LookupHistoryItem as LookupHistoryItem, index$e_MAX_LOOKUP_HISTORY_SLOTS as MAX_LOOKUP_HISTORY_SLOTS, index$e_NotYetAccumulatedReport as NotYetAccumulatedReport, index$e_PreimageItem as PreimageItem, index$e_PrivilegedServices as PrivilegedServices, index$e_RecentBlocks as RecentBlocks, index$e_SafroleData as SafroleData, index$e_SafroleSealingKeysData as SafroleSealingKeysData, index$e_SafroleSealingKeysKind as SafroleSealingKeysKind, index$e_ServiceAccountInfo as ServiceAccountInfo, index$e_ServiceStatistics as ServiceStatistics, index$e_StatisticsData as StatisticsData, index$e_StorageItem as StorageItem, index$e_UpdateError as UpdateError, index$e_UpdatePreimage as UpdatePreimage, index$e_UpdatePreimageKind as UpdatePreimageKind, index$e_UpdateService as UpdateService, index$e_UpdateServiceKind as UpdateServiceKind, index$e_UpdateStorage as UpdateStorage, index$e_UpdateStorageKind as UpdateStorageKind, index$e_ValidatorData as ValidatorData, index$e_ValidatorStatistics as ValidatorStatistics, index$e_accumulationOutputComparator as accumulationOutputComparator, index$e_accumulationQueueCodec as accumulationQueueCodec, index$e_authPoolsCodec as authPoolsCodec, index$e_authQueuesCodec as authQueuesCodec, index$e_availabilityAssignmentsCodec as availabilityAssignmentsCodec, index$e_codecBandersnatchKey as codecBandersnatchKey, index$e_codecPerCore as codecPerCore, index$e_codecServiceId as codecServiceId, index$e_codecVarGas as codecVarGas, index$e_codecVarU16 as codecVarU16, index$e_codecWithVersion as codecWithVersion, index$e_hashComparator as hashComparator, index$e_ignoreValueWithDefault as ignoreValueWithDefault, index$e_recentlyAccumulatedCodec as recentlyAccumulatedCodec, index$e_serviceDataCodec as serviceDataCodec, index$e_serviceEntriesCodec as serviceEntriesCodec, index$e_sortedSetCodec as sortedSetCodec, index$e_tryAsLookupHistorySlots as tryAsLookupHistorySlots, index$e_tryAsPerCore as tryAsPerCore, index$e_validatorsDataCodec as validatorsDataCodec, index$e_workReportsSortedSetCodec as workReportsSortedSetCodec, index$e_zeroSizeHint as zeroSizeHint };
|
|
11520
11642
|
export type { index$e_AUTHORIZATION_QUEUE_SIZE as AUTHORIZATION_QUEUE_SIZE, index$e_AccumulationQueue as AccumulationQueue, index$e_AccumulationQueueView as AccumulationQueueView, index$e_AuthorizationPool as AuthorizationPool, index$e_AuthorizationQueue as AuthorizationQueue, index$e_AvailabilityAssignmentsView as AvailabilityAssignmentsView, index$e_BlocksState as BlocksState, index$e_ENTROPY_ENTRIES as ENTROPY_ENTRIES, index$e_EnumerableState as EnumerableState, index$e_FieldNames as FieldNames, index$e_InMemoryStateFields as InMemoryStateFields, index$e_LookupHistorySlots as LookupHistorySlots, index$e_MAX_AUTH_POOL_SIZE as MAX_AUTH_POOL_SIZE, index$e_MAX_RECENT_HISTORY as MAX_RECENT_HISTORY, index$e_PerCore as PerCore, index$e_RecentBlocksView as RecentBlocksView, index$e_RecentlyAccumulated as RecentlyAccumulated, index$e_RecentlyAccumulatedView as RecentlyAccumulatedView, index$e_SafroleDataView as SafroleDataView, index$e_SafroleSealingKeys as SafroleSealingKeys, index$e_Service as Service, index$e_ServiceAccountInfoView as ServiceAccountInfoView, index$e_ServiceData as ServiceData, index$e_ServiceEntries as ServiceEntries, index$e_ServicesUpdate as ServicesUpdate, index$e_State as State, index$e_StateView as StateView, index$e_StatisticsDataView as StatisticsDataView, index$e_StorageKey as StorageKey, index$e_VALIDATOR_META_BYTES as VALIDATOR_META_BYTES, index$e_ValidatorDataView as ValidatorDataView, index$e_WithStateView as WithStateView };
|
|
11521
11643
|
}
|
|
11522
11644
|
|
|
@@ -14292,7 +14414,7 @@ interface PartialState {
|
|
|
14292
14414
|
a: PerCore<ServiceId>,
|
|
14293
14415
|
v: ServiceId | null,
|
|
14294
14416
|
r: ServiceId | null,
|
|
14295
|
-
z:
|
|
14417
|
+
z: Map<ServiceId, ServiceGas>,
|
|
14296
14418
|
): Result$2<OK, UpdatePrivilegesError>;
|
|
14297
14419
|
|
|
14298
14420
|
/** Yield accumulation trie result hash. */
|
|
@@ -14334,48 +14456,133 @@ declare class PendingTransfer {
|
|
|
14334
14456
|
}
|
|
14335
14457
|
}
|
|
14336
14458
|
|
|
14337
|
-
/** Gas measuring type. Can be either U64 or U32 for performance reasons. */
|
|
14338
|
-
type Gas = BigGas | SmallGas;
|
|
14339
14459
|
/** A U64 version of `Gas`. */
|
|
14340
14460
|
type BigGas = Opaque<U64, "BigGas[U64]">;
|
|
14341
14461
|
/** A U32 version of `Gas`. */
|
|
14342
14462
|
type SmallGas = Opaque<U32, "SmallGas[U32]">;
|
|
14343
|
-
|
|
14344
|
-
|
|
14345
|
-
declare const tryAsSmallGas = (v: number): SmallGas => asOpaqueType(tryAsU32(v));
|
|
14346
|
-
|
|
14347
|
-
/** Attempt to convert given number into U64 gas representation. */
|
|
14348
|
-
declare const tryAsBigGas = (v: number | bigint): BigGas => asOpaqueType(tryAsU64(v));
|
|
14349
|
-
|
|
14350
|
-
/** Attempt to convert given number into gas. */
|
|
14351
|
-
declare const tryAsGas = (v: number | bigint): Gas =>
|
|
14352
|
-
typeof v === "number" && v < 2 ** 32 ? tryAsSmallGas(v) : tryAsBigGas(v);
|
|
14353
|
-
|
|
14354
|
-
/** Create a new gas counter instance depending on the gas value. */
|
|
14355
|
-
declare function gasCounter(gas: Gas): GasCounter {
|
|
14356
|
-
return new GasCounterU64(tryAsU64(gas));
|
|
14357
|
-
}
|
|
14463
|
+
/** Gas measuring type. Can be either U64 or U32 for performance reasons. */
|
|
14464
|
+
type Gas = BigGas | SmallGas;
|
|
14358
14465
|
|
|
14359
14466
|
/** An abstraction over gas counter.
|
|
14360
14467
|
*
|
|
14361
14468
|
* It can be optimized to use numbers instead of bigint in case of small gas.
|
|
14362
14469
|
*/
|
|
14363
|
-
interface
|
|
14470
|
+
interface IGasCounter {
|
|
14471
|
+
/**
|
|
14472
|
+
* Set during initialization of GasCounter.
|
|
14473
|
+
*
|
|
14474
|
+
* NOTE: Needed to calculate `used()` gas.
|
|
14475
|
+
*/
|
|
14476
|
+
initialGas: Gas;
|
|
14477
|
+
|
|
14364
14478
|
/** Return remaining gas. */
|
|
14365
14479
|
get(): Gas;
|
|
14366
14480
|
|
|
14367
|
-
/**
|
|
14481
|
+
/**
|
|
14482
|
+
* Overwrite remaining gas.
|
|
14483
|
+
*
|
|
14484
|
+
* NOTE: Could cause `used()` gas calculation to be incorrect.
|
|
14485
|
+
*
|
|
14486
|
+
* @see
|
|
14487
|
+
* Prefer sub method instead.
|
|
14488
|
+
*/
|
|
14368
14489
|
set(g: Gas): void;
|
|
14369
14490
|
|
|
14370
14491
|
/** Returns true if there was an underflow. */
|
|
14371
14492
|
sub(g: Gas): boolean;
|
|
14493
|
+
|
|
14494
|
+
/**
|
|
14495
|
+
* Calculates used gas since creation of GasCounter.
|
|
14496
|
+
*
|
|
14497
|
+
* The interface does not handle negative or more than `initialGas` values.
|
|
14498
|
+
*
|
|
14499
|
+
* NOTE: We can use at most `initialGas` and as little as `0`.
|
|
14500
|
+
*/
|
|
14501
|
+
used(): Gas;
|
|
14502
|
+
}
|
|
14503
|
+
|
|
14504
|
+
type PageFault$1 = {
|
|
14505
|
+
address: U32;
|
|
14506
|
+
};
|
|
14507
|
+
|
|
14508
|
+
/** Allows store and read segments of memory. */
|
|
14509
|
+
interface IMemory {
|
|
14510
|
+
/** Store bytes into memory at given address. */
|
|
14511
|
+
store(address: U32, bytes: Uint8Array): Result$2<OK, PageFault$1>;
|
|
14512
|
+
|
|
14513
|
+
/** Load bytes from memory from given address into given buffer. */
|
|
14514
|
+
read(address: U32, result: Uint8Array): Result$2<OK, PageFault$1>;
|
|
14372
14515
|
}
|
|
14373
14516
|
|
|
14374
14517
|
declare const NO_OF_REGISTERS$1 = 13;
|
|
14375
14518
|
|
|
14519
|
+
/** Allow to set and get all registers encoded into little-endian bytes. */
|
|
14520
|
+
interface IRegisters {
|
|
14521
|
+
/**
|
|
14522
|
+
* Get all registers encoded into little-endian bytes.
|
|
14523
|
+
*
|
|
14524
|
+
* NOTE: Total length of bytes must be NO_OF_REGISTERS * REGISTER_BYTE_SIZE.
|
|
14525
|
+
*/
|
|
14526
|
+
getAllEncoded(): Uint8Array;
|
|
14527
|
+
/**
|
|
14528
|
+
* Set all registers from little-endian encoded bytes.
|
|
14529
|
+
*
|
|
14530
|
+
* NOTE: Total length of bytes must be NO_OF_REGISTERS * REGISTER_BYTE_SIZE.
|
|
14531
|
+
*/
|
|
14532
|
+
setAllEncoded(bytes: Uint8Array): void;
|
|
14533
|
+
}
|
|
14534
|
+
|
|
14535
|
+
/**
|
|
14536
|
+
* Result codes for the PVM execution.
|
|
14537
|
+
*
|
|
14538
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/2e43002e4300?v=0.7.2
|
|
14539
|
+
*/
|
|
14540
|
+
declare enum Status {
|
|
14541
|
+
/** Continue */
|
|
14542
|
+
OK = 255,
|
|
14543
|
+
/** Finished */
|
|
14544
|
+
HALT = 0,
|
|
14545
|
+
/** Panic */
|
|
14546
|
+
PANIC = 1,
|
|
14547
|
+
/** Page-fault */
|
|
14548
|
+
FAULT = 2,
|
|
14549
|
+
/** Host-call */
|
|
14550
|
+
HOST = 3,
|
|
14551
|
+
/** Out of gas */
|
|
14552
|
+
OOG = 4,
|
|
14553
|
+
}
|
|
14554
|
+
|
|
14555
|
+
interface IPvmInterpreter {
|
|
14556
|
+
/** Manipulate gas. */
|
|
14557
|
+
readonly gas: IGasCounter;
|
|
14558
|
+
|
|
14559
|
+
/** Manipulate registers. */
|
|
14560
|
+
readonly registers: IRegisters;
|
|
14561
|
+
|
|
14562
|
+
/** Manipulate memory. */
|
|
14563
|
+
readonly memory: IMemory;
|
|
14564
|
+
|
|
14565
|
+
/** Prepare SPI program to be executed. */
|
|
14566
|
+
resetJam(program: Uint8Array, args: Uint8Array, pc: number, gas: Gas): void;
|
|
14567
|
+
|
|
14568
|
+
/** Execute loaded program. */
|
|
14569
|
+
runProgram(): void;
|
|
14570
|
+
|
|
14571
|
+
/** Get current Status. */
|
|
14572
|
+
getStatus(): Status;
|
|
14573
|
+
|
|
14574
|
+
/** Get current Program Counter. */
|
|
14575
|
+
getPC(): number;
|
|
14576
|
+
|
|
14577
|
+
/** Get exit args. Needed in case of HOST or FAULT. */
|
|
14578
|
+
getExitParam(): U32 | null;
|
|
14579
|
+
}
|
|
14580
|
+
|
|
14581
|
+
// x << 3 === x * 8
|
|
14582
|
+
|
|
14376
14583
|
type RegisterIndex = Opaque<number, "register index">;
|
|
14377
14584
|
|
|
14378
|
-
declare class Registers {
|
|
14585
|
+
declare class Registers implements IRegisters {
|
|
14379
14586
|
private asSigned: BigInt64Array;
|
|
14380
14587
|
private asUnsigned: BigUint64Array;
|
|
14381
14588
|
|
|
@@ -14385,6 +14592,15 @@ declare class Registers {
|
|
|
14385
14592
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14386
14593
|
}
|
|
14387
14594
|
|
|
14595
|
+
getAllEncoded(): Uint8Array {
|
|
14596
|
+
return this.bytes;
|
|
14597
|
+
}
|
|
14598
|
+
|
|
14599
|
+
setAllEncoded(bytes: Uint8Array): void {
|
|
14600
|
+
check`${bytes.length === this.bytes.length} Incorrect size of input registers. Got: ${bytes.length}, need: ${this.bytes.length}`;
|
|
14601
|
+
this.bytes.set(bytes, 0);
|
|
14602
|
+
}
|
|
14603
|
+
|
|
14388
14604
|
static fromBytes(bytes: Uint8Array) {
|
|
14389
14605
|
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14390
14606
|
return new Registers(bytes);
|
|
@@ -14395,10 +14611,6 @@ declare class Registers {
|
|
|
14395
14611
|
return this.bytes.subarray(offset, offset + len);
|
|
14396
14612
|
}
|
|
14397
14613
|
|
|
14398
|
-
getAllBytesAsLittleEndian() {
|
|
14399
|
-
return this.bytes;
|
|
14400
|
-
}
|
|
14401
|
-
|
|
14402
14614
|
copyFrom(regs: Registers | BigUint64Array) {
|
|
14403
14615
|
const array = regs instanceof BigUint64Array ? regs : regs.asUnsigned;
|
|
14404
14616
|
this.asUnsigned.set(array);
|
|
@@ -14447,1493 +14659,1856 @@ declare class Registers {
|
|
|
14447
14659
|
}
|
|
14448
14660
|
}
|
|
14449
14661
|
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/237201239801
|
|
14454
|
-
*/
|
|
14455
|
-
declare class Mask {
|
|
14662
|
+
declare class HostCallMemory {
|
|
14663
|
+
constructor(private readonly memory: IMemory) {}
|
|
14664
|
+
|
|
14456
14665
|
/**
|
|
14457
|
-
*
|
|
14458
|
-
* In case the value is non-zero it signifies the offset to the index with next instruction.
|
|
14666
|
+
* Save some bytes into memory under given address.
|
|
14459
14667
|
*
|
|
14460
|
-
*
|
|
14461
|
-
*
|
|
14462
|
-
* 0..1..2..3..4..5..6..7..8..9 # Indices
|
|
14463
|
-
* 0..2..1..0..1..0..3..2..1..0 # lookupTable forward values
|
|
14464
|
-
* ```
|
|
14465
|
-
* There are instructions at indices `0, 3, 5, 9`.
|
|
14668
|
+
* NOTE: Given address is U64 (pure register value),
|
|
14669
|
+
* but we use only lower 32-bits.
|
|
14466
14670
|
*/
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
}
|
|
14472
|
-
|
|
14473
|
-
isInstruction(index: number) {
|
|
14474
|
-
return this.lookupTableForward[index] === 0;
|
|
14475
|
-
}
|
|
14671
|
+
storeFrom(regAddress: U64, bytes: Uint8Array): Result$2<OK, PageFault$1> {
|
|
14672
|
+
if (bytes.length === 0) {
|
|
14673
|
+
return Result.ok(OK);
|
|
14674
|
+
}
|
|
14476
14675
|
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14676
|
+
// NOTE: We always take lower 32 bits from register value.
|
|
14677
|
+
//
|
|
14678
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
14679
|
+
const address = tryAsU32(Number(regAddress & 0xffff_ffffn));
|
|
14680
|
+
return this.memory.store(address, bytes);
|
|
14480
14681
|
}
|
|
14481
14682
|
|
|
14482
|
-
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
|
|
14490
|
-
|
|
14491
|
-
table[i] = lastInstructionOffset;
|
|
14683
|
+
/**
|
|
14684
|
+
* Read some bytes from memory under given address.
|
|
14685
|
+
*
|
|
14686
|
+
* NOTE: Given address is U64 (pure register value),
|
|
14687
|
+
* but we use only lower 32-bits.
|
|
14688
|
+
*/
|
|
14689
|
+
loadInto(output: Uint8Array, regAddress: U64): Result$2<OK, PageFault$1> {
|
|
14690
|
+
if (output.length === 0) {
|
|
14691
|
+
return Result.ok(OK);
|
|
14492
14692
|
}
|
|
14493
|
-
return table;
|
|
14494
|
-
}
|
|
14495
14693
|
|
|
14496
|
-
|
|
14497
|
-
|
|
14694
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
14695
|
+
//
|
|
14696
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
14697
|
+
const address = tryAsU32(Number(regAddress & 0xffff_ffffn));
|
|
14698
|
+
return this.memory.read(address, output);
|
|
14498
14699
|
}
|
|
14499
14700
|
}
|
|
14500
14701
|
|
|
14501
|
-
declare
|
|
14502
|
-
|
|
14503
|
-
ONE_IMMEDIATE = 1,
|
|
14504
|
-
TWO_IMMEDIATES = 2,
|
|
14505
|
-
ONE_OFFSET = 3,
|
|
14506
|
-
ONE_REGISTER_ONE_IMMEDIATE = 4,
|
|
14507
|
-
ONE_REGISTER_TWO_IMMEDIATES = 5,
|
|
14508
|
-
ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET = 6,
|
|
14509
|
-
TWO_REGISTERS = 7,
|
|
14510
|
-
TWO_REGISTERS_ONE_IMMEDIATE = 8,
|
|
14511
|
-
TWO_REGISTERS_ONE_OFFSET = 9,
|
|
14512
|
-
TWO_REGISTERS_TWO_IMMEDIATES = 10,
|
|
14513
|
-
THREE_REGISTERS = 11,
|
|
14514
|
-
ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE = 12,
|
|
14515
|
-
}
|
|
14516
|
-
|
|
14517
|
-
declare class ExtendedWitdthImmediateDecoder {
|
|
14518
|
-
private unsignedImmediate: BigUint64Array;
|
|
14519
|
-
private bytes: Uint8Array;
|
|
14702
|
+
declare class HostCallRegisters {
|
|
14703
|
+
private readonly registers: DataView;
|
|
14520
14704
|
|
|
14521
|
-
constructor() {
|
|
14522
|
-
|
|
14523
|
-
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
14524
|
-
this.bytes = new Uint8Array(buffer);
|
|
14705
|
+
constructor(private readonly bytes: Uint8Array) {
|
|
14706
|
+
this.registers = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
14525
14707
|
}
|
|
14526
14708
|
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
|
|
14530
|
-
this.bytes[i] = bytes[i];
|
|
14531
|
-
}
|
|
14532
|
-
|
|
14533
|
-
for (; i < IMMEDIATE_SIZE; i++) {
|
|
14534
|
-
this.bytes[i] = 0;
|
|
14535
|
-
}
|
|
14709
|
+
/** Get U64 register value. */
|
|
14710
|
+
get(registerIndex: number): U64 {
|
|
14711
|
+
return tryAsU64(this.registers.getBigUint64(registerIndex * REGISTER_BYTE_SIZE, true));
|
|
14536
14712
|
}
|
|
14537
14713
|
|
|
14538
|
-
|
|
14539
|
-
|
|
14714
|
+
/** Set U64 register value. */
|
|
14715
|
+
set(registerIndex: number, value: U64) {
|
|
14716
|
+
this.registers.setBigUint64(registerIndex * REGISTER_BYTE_SIZE, value, true);
|
|
14540
14717
|
}
|
|
14541
14718
|
|
|
14542
|
-
|
|
14543
|
-
|
|
14719
|
+
/** Get all registers encoded into little-endian bytes. */
|
|
14720
|
+
getEncoded(): Uint8Array {
|
|
14721
|
+
return this.bytes;
|
|
14544
14722
|
}
|
|
14545
14723
|
}
|
|
14546
14724
|
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
private i64: BigInt64Array;
|
|
14552
|
-
private view: DataView;
|
|
14553
|
-
private bytes: Uint8Array;
|
|
14554
|
-
|
|
14555
|
-
constructor() {
|
|
14556
|
-
const buffer = new ArrayBuffer(BUFFER_SIZE);
|
|
14557
|
-
this.u32 = new Uint32Array(buffer);
|
|
14558
|
-
this.i32 = new Int32Array(buffer);
|
|
14559
|
-
this.u64 = new BigUint64Array(buffer);
|
|
14560
|
-
this.i64 = new BigInt64Array(buffer);
|
|
14561
|
-
this.view = new DataView(buffer);
|
|
14562
|
-
this.bytes = new Uint8Array(buffer);
|
|
14563
|
-
}
|
|
14725
|
+
/** Strictly-typed host call index. */
|
|
14726
|
+
type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
14727
|
+
/** Attempt to convert a number into `HostCallIndex`. */
|
|
14728
|
+
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
14564
14729
|
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14730
|
+
/**
|
|
14731
|
+
* Host-call exit reason.
|
|
14732
|
+
*
|
|
14733
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
14734
|
+
*/
|
|
14735
|
+
declare enum PvmExecution {
|
|
14736
|
+
Halt = 0,
|
|
14737
|
+
Panic = 1,
|
|
14738
|
+
OOG = 2, // out-of-gas
|
|
14739
|
+
}
|
|
14570
14740
|
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14741
|
+
/** A utility function to easily trace a bunch of registers. */
|
|
14742
|
+
declare function traceRegisters(...regs: number[]) {
|
|
14743
|
+
return regs.map(tryAsRegisterIndex);
|
|
14744
|
+
}
|
|
14574
14745
|
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14746
|
+
/** An interface for a host call implementation */
|
|
14747
|
+
interface HostCallHandler {
|
|
14748
|
+
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
14749
|
+
readonly index: HostCallIndex;
|
|
14579
14750
|
|
|
14580
14751
|
/**
|
|
14581
|
-
*
|
|
14752
|
+
* The gas cost of invocation of that host call.
|
|
14753
|
+
*
|
|
14754
|
+
* NOTE: `((reg: HostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
14582
14755
|
*/
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14756
|
+
readonly basicGasCost: SmallGas | ((reg: HostCallRegisters) => Gas);
|
|
14757
|
+
|
|
14758
|
+
/** Currently executing service id. */
|
|
14759
|
+
readonly currentServiceId: U32;
|
|
14760
|
+
|
|
14761
|
+
/** Input&Output registers that we should add to tracing log. */
|
|
14762
|
+
readonly tracedRegisters: RegisterIndex[];
|
|
14586
14763
|
|
|
14587
14764
|
/**
|
|
14588
|
-
*
|
|
14765
|
+
* Actually execute the host call.
|
|
14766
|
+
*
|
|
14767
|
+
* NOTE the call is ALLOWED and expected to modify registers and memory.
|
|
14589
14768
|
*/
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
}
|
|
14769
|
+
execute(gas: IGasCounter, regs: HostCallRegisters, memory: HostCallMemory): Promise<undefined | PvmExecution>;
|
|
14770
|
+
}
|
|
14593
14771
|
|
|
14594
|
-
|
|
14595
|
-
|
|
14596
|
-
|
|
14772
|
+
/** Container for all available host calls. */
|
|
14773
|
+
declare class HostCallsManager {
|
|
14774
|
+
private readonly hostCalls = new Map<HostCallIndex, HostCallHandler>();
|
|
14775
|
+
private readonly missing;
|
|
14597
14776
|
|
|
14598
|
-
|
|
14599
|
-
|
|
14777
|
+
constructor({
|
|
14778
|
+
missing,
|
|
14779
|
+
handlers = [],
|
|
14780
|
+
}: {
|
|
14781
|
+
missing: HostCallHandler;
|
|
14782
|
+
handlers?: HostCallHandler[];
|
|
14783
|
+
}) {
|
|
14784
|
+
this.missing = missing;
|
|
14785
|
+
|
|
14786
|
+
for (const handler of handlers) {
|
|
14787
|
+
check`${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
14788
|
+
this.hostCalls.set(handler.index, handler);
|
|
14789
|
+
}
|
|
14600
14790
|
}
|
|
14601
14791
|
|
|
14602
|
-
|
|
14603
|
-
|
|
14792
|
+
/** Get a host call by index. */
|
|
14793
|
+
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
14794
|
+
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
14604
14795
|
}
|
|
14605
14796
|
|
|
14606
|
-
|
|
14607
|
-
|
|
14797
|
+
traceHostCall(
|
|
14798
|
+
context: string,
|
|
14799
|
+
hostCallIndex: HostCallIndex,
|
|
14800
|
+
hostCallHandler: HostCallHandler,
|
|
14801
|
+
registers: HostCallRegisters,
|
|
14802
|
+
gas: Gas,
|
|
14803
|
+
) {
|
|
14804
|
+
const { currentServiceId } = hostCallHandler;
|
|
14805
|
+
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
14806
|
+
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
14807
|
+
const registerValues = hostCallHandler.tracedRegisters
|
|
14808
|
+
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
14809
|
+
.filter((v) => v[1] !== 0n)
|
|
14810
|
+
.map(([idx, value]) => {
|
|
14811
|
+
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
14812
|
+
})
|
|
14813
|
+
.join(", ");
|
|
14814
|
+
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
14608
14815
|
}
|
|
14816
|
+
}
|
|
14609
14817
|
|
|
14610
|
-
|
|
14611
|
-
|
|
14818
|
+
/** Create a new gas counter instance depending on the gas value. */
|
|
14819
|
+
declare function gasCounter(gas: Gas): IGasCounter {
|
|
14820
|
+
return new GasCounterU64(tryAsU64(gas));
|
|
14821
|
+
}
|
|
14822
|
+
|
|
14823
|
+
type MemoryIndex = Opaque<number, "memory index">;
|
|
14824
|
+
|
|
14825
|
+
declare const tryAsMemoryIndex = (index: number): MemoryIndex => {
|
|
14826
|
+
check`${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
14827
|
+
return asOpaqueType(index);
|
|
14828
|
+
};
|
|
14829
|
+
|
|
14830
|
+
type SbrkIndex = Opaque<number, "sbrk index">;
|
|
14831
|
+
|
|
14832
|
+
declare const tryAsSbrkIndex = (index: number): SbrkIndex => {
|
|
14833
|
+
check`${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
14834
|
+
return asOpaqueType(index);
|
|
14835
|
+
};
|
|
14836
|
+
|
|
14837
|
+
type PageIndex = Opaque<number, "memory page index">;
|
|
14838
|
+
type PageNumber = Opaque<number, "memory page number">;
|
|
14839
|
+
|
|
14840
|
+
declare class PageFault implements PageFault$1 {
|
|
14841
|
+
private constructor(
|
|
14842
|
+
public address: U32,
|
|
14843
|
+
public isAccessFault = true,
|
|
14844
|
+
) {}
|
|
14845
|
+
|
|
14846
|
+
static fromPageNumber(maybePageNumber: number, isAccessFault = false) {
|
|
14847
|
+
const pageNumber = tryAsPageNumber(maybePageNumber);
|
|
14848
|
+
const startPageIndex = getStartPageIndexFromPageNumber(pageNumber);
|
|
14849
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
14612
14850
|
}
|
|
14613
14851
|
|
|
14614
|
-
|
|
14615
|
-
|
|
14852
|
+
static fromMemoryIndex(maybeMemoryIndex: number, isAccessFault = false) {
|
|
14853
|
+
const memoryIndex = tryAsMemoryIndex(maybeMemoryIndex % MEMORY_SIZE);
|
|
14854
|
+
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
14855
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
14616
14856
|
}
|
|
14617
14857
|
}
|
|
14618
14858
|
|
|
14619
|
-
|
|
14620
|
-
|
|
14859
|
+
/**
|
|
14860
|
+
* A representation of open-ended range of consecutive indices in memory,
|
|
14861
|
+
* possibly empty or wrapping around.
|
|
14862
|
+
*
|
|
14863
|
+
* `[start, start + length)`
|
|
14864
|
+
*/
|
|
14865
|
+
declare class MemoryRange {
|
|
14866
|
+
/**
|
|
14867
|
+
* Exclusive end index of the range.
|
|
14868
|
+
*
|
|
14869
|
+
* NOTE: The index may be wrapped around and smaller than `start`!
|
|
14870
|
+
*/
|
|
14871
|
+
public readonly end: MemoryIndex;
|
|
14872
|
+
/**
|
|
14873
|
+
* Inclusive last index of the range (present unless the range is empty).
|
|
14874
|
+
*
|
|
14875
|
+
* NOTE: the index may be wrapped around and smaller than `start`!
|
|
14876
|
+
*/
|
|
14877
|
+
public readonly lastIndex: MemoryIndex | null = null;
|
|
14621
14878
|
|
|
14622
|
-
|
|
14623
|
-
|
|
14624
|
-
|
|
14879
|
+
private constructor(
|
|
14880
|
+
public readonly start: MemoryIndex,
|
|
14881
|
+
public readonly length: number,
|
|
14882
|
+
) {
|
|
14883
|
+
this.end = tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
14625
14884
|
|
|
14626
|
-
|
|
14627
|
-
|
|
14885
|
+
if (length > 0) {
|
|
14886
|
+
this.lastIndex = tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
14887
|
+
}
|
|
14628
14888
|
}
|
|
14629
14889
|
|
|
14630
|
-
|
|
14631
|
-
|
|
14890
|
+
/** Creates a memory range from given starting point and length */
|
|
14891
|
+
static fromStartAndLength(start: MemoryIndex, length: number) {
|
|
14892
|
+
if (!Number.isInteger(length) || length < 0 || length > MEMORY_SIZE) {
|
|
14893
|
+
throw new TypeError(`length must be a non-negative integer and less than ${MEMORY_SIZE}, got ${length}`);
|
|
14894
|
+
}
|
|
14895
|
+
|
|
14896
|
+
return new MemoryRange(start, length);
|
|
14632
14897
|
}
|
|
14633
14898
|
|
|
14634
|
-
|
|
14635
|
-
|
|
14899
|
+
/** Checks if a range is empty (`length === 0`) */
|
|
14900
|
+
isEmpty() {
|
|
14901
|
+
return this.length === 0;
|
|
14636
14902
|
}
|
|
14637
14903
|
|
|
14638
|
-
|
|
14639
|
-
|
|
14904
|
+
/** Returns true if the range is wrapped (`start` >= `end`) and is not empty */
|
|
14905
|
+
isWrapped() {
|
|
14906
|
+
return this.start >= this.end && !this.isEmpty();
|
|
14640
14907
|
}
|
|
14641
14908
|
|
|
14642
|
-
|
|
14643
|
-
|
|
14909
|
+
/** Checks if given memory address is within the range */
|
|
14910
|
+
isInRange(address: MemoryIndex) {
|
|
14911
|
+
if (this.isWrapped()) {
|
|
14912
|
+
return address >= this.start || address < this.end;
|
|
14913
|
+
}
|
|
14914
|
+
|
|
14915
|
+
return address >= this.start && address < this.end;
|
|
14644
14916
|
}
|
|
14645
14917
|
|
|
14646
|
-
|
|
14647
|
-
|
|
14918
|
+
/** Checks if this range overlaps with another range */
|
|
14919
|
+
overlapsWith(other: MemoryRange) {
|
|
14920
|
+
if (this.lastIndex === null || other.lastIndex === null) {
|
|
14921
|
+
return false;
|
|
14922
|
+
}
|
|
14923
|
+
|
|
14924
|
+
return (
|
|
14925
|
+
this.isInRange(other.start) ||
|
|
14926
|
+
this.isInRange(other.lastIndex) ||
|
|
14927
|
+
other.isInRange(this.start) ||
|
|
14928
|
+
other.isInRange(this.lastIndex)
|
|
14929
|
+
);
|
|
14648
14930
|
}
|
|
14649
14931
|
}
|
|
14650
14932
|
|
|
14651
|
-
|
|
14652
|
-
|
|
14653
|
-
noOfBytesToSkip: number;
|
|
14654
|
-
};
|
|
14655
|
-
|
|
14656
|
-
type OneImmediateArgs = {
|
|
14657
|
-
type: ArgumentType.ONE_IMMEDIATE;
|
|
14658
|
-
noOfBytesToSkip: number;
|
|
14659
|
-
/** V_X */
|
|
14660
|
-
immediateDecoder: ImmediateDecoder;
|
|
14661
|
-
};
|
|
14933
|
+
declare abstract class MemoryPage {
|
|
14934
|
+
public start: MemoryIndex;
|
|
14662
14935
|
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
/** W_A */
|
|
14667
|
-
firstRegisterIndex: number;
|
|
14668
|
-
/** W_B */
|
|
14669
|
-
secondRegisterIndex: number;
|
|
14670
|
-
/** W_D */
|
|
14671
|
-
thirdRegisterIndex: number;
|
|
14672
|
-
};
|
|
14936
|
+
constructor(pageNumber: PageNumber) {
|
|
14937
|
+
this.start = getStartPageIndexFromPageNumber(pageNumber);
|
|
14938
|
+
}
|
|
14673
14939
|
|
|
14674
|
-
|
|
14675
|
-
|
|
14676
|
-
noOfBytesToSkip: number;
|
|
14677
|
-
/** W_A */
|
|
14678
|
-
firstRegisterIndex: number;
|
|
14679
|
-
/** W_D */
|
|
14680
|
-
secondRegisterIndex: number;
|
|
14681
|
-
};
|
|
14940
|
+
/** Returns `true` if the page is writeable. */
|
|
14941
|
+
abstract isWriteable(): boolean;
|
|
14682
14942
|
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
|
|
14690
|
-
|
|
14691
|
-
|
|
14692
|
-
|
|
14943
|
+
/**
|
|
14944
|
+
* Load exactly `length` bytes from memory page, starting at index `address`
|
|
14945
|
+
* into the `res` array.
|
|
14946
|
+
*
|
|
14947
|
+
* Note that the `res` might be bigger than the number of bytes length, but cannot be smaller.
|
|
14948
|
+
*
|
|
14949
|
+
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
14950
|
+
* NOTE That the `result` might be partially modified in case `PageFault` occurs!
|
|
14951
|
+
*/
|
|
14952
|
+
abstract loadInto(res: Uint8Array, address: PageIndex, length: number): Result$2<OK, PageFault>;
|
|
14693
14953
|
|
|
14694
|
-
|
|
14695
|
-
|
|
14696
|
-
|
|
14697
|
-
|
|
14698
|
-
|
|
14699
|
-
|
|
14700
|
-
|
|
14701
|
-
|
|
14954
|
+
/**
|
|
14955
|
+
* Copy all bytes from the `data` into the page at index `address`.
|
|
14956
|
+
*
|
|
14957
|
+
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
14958
|
+
*/
|
|
14959
|
+
abstract storeFrom(address: PageIndex, data: Uint8Array): Result$2<OK, PageFault>;
|
|
14960
|
+
/**
|
|
14961
|
+
* Get dump of the entire page. Should only be used for the debugger-adapter because it
|
|
14962
|
+
* might be inefficient.
|
|
14963
|
+
*/
|
|
14964
|
+
abstract getPageDump(): Uint8Array;
|
|
14702
14965
|
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
noOfBytesToSkip: number;
|
|
14706
|
-
/** W_A */
|
|
14707
|
-
registerIndex: number;
|
|
14708
|
-
/** V_X */
|
|
14709
|
-
immediateDecoder: ExtendedWitdthImmediateDecoder;
|
|
14710
|
-
};
|
|
14966
|
+
abstract setData(pageIndex: PageIndex, data: Uint8Array): void;
|
|
14967
|
+
}
|
|
14711
14968
|
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
|
|
14715
|
-
|
|
14716
|
-
|
|
14717
|
-
|
|
14718
|
-
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14969
|
+
/**
|
|
14970
|
+
* I had to extend ArrayBuffer type to use resizable ArrayBuffer.
|
|
14971
|
+
* We will be able to remove it when this is merged: https://github.com/microsoft/TypeScript/pull/58573
|
|
14972
|
+
* And then a new version of TypeScript is released.
|
|
14973
|
+
*/
|
|
14974
|
+
declare global {
|
|
14975
|
+
interface ArrayBufferConstructor {
|
|
14976
|
+
new (length: number, options?: {
|
|
14977
|
+
maxByteLength: number;
|
|
14978
|
+
}): ArrayBuffer;
|
|
14979
|
+
}
|
|
14980
|
+
interface ArrayBuffer {
|
|
14981
|
+
resize(length: number): void;
|
|
14982
|
+
}
|
|
14983
|
+
}
|
|
14724
14984
|
|
|
14725
|
-
type
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
firstImmediateDecoder: ImmediateDecoder;
|
|
14730
|
-
/** V_Y */
|
|
14731
|
-
secondImmediateDecoder: ImmediateDecoder;
|
|
14985
|
+
type InitialMemoryState = {
|
|
14986
|
+
memory: Map<PageNumber, MemoryPage>;
|
|
14987
|
+
sbrkIndex: SbrkIndex;
|
|
14988
|
+
endHeapIndex: SbrkIndex;
|
|
14732
14989
|
};
|
|
14733
14990
|
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
firstRegisterIndex: number;
|
|
14739
|
-
/** W_B */
|
|
14740
|
-
secondRegisterIndex: number;
|
|
14741
|
-
nextPc: number;
|
|
14742
|
-
};
|
|
14991
|
+
declare enum AccessType {
|
|
14992
|
+
READ = 0,
|
|
14993
|
+
WRITE = 1,
|
|
14994
|
+
}
|
|
14743
14995
|
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
};
|
|
14996
|
+
declare class Memory implements IMemory {
|
|
14997
|
+
static fromInitialMemory(initialMemoryState: InitialMemoryState) {
|
|
14998
|
+
return new Memory(
|
|
14999
|
+
initialMemoryState?.sbrkIndex,
|
|
15000
|
+
initialMemoryState?.sbrkIndex,
|
|
15001
|
+
initialMemoryState?.endHeapIndex,
|
|
15002
|
+
initialMemoryState?.memory,
|
|
15003
|
+
);
|
|
15004
|
+
}
|
|
14754
15005
|
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
firstImmediateDecoder: ImmediateDecoder;
|
|
14762
|
-
/** V_Y */
|
|
14763
|
-
secondImmediateDecoder: ImmediateDecoder;
|
|
14764
|
-
};
|
|
15006
|
+
constructor(
|
|
15007
|
+
private sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
15008
|
+
private virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
15009
|
+
private endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX),
|
|
15010
|
+
private memory = new Map<PageNumber, MemoryPage>(),
|
|
15011
|
+
) {}
|
|
14765
15012
|
|
|
14766
|
-
|
|
14767
|
-
|
|
14768
|
-
|
|
14769
|
-
/** V_X */
|
|
14770
|
-
nextPc: number;
|
|
14771
|
-
};
|
|
15013
|
+
store(address: U32, bytes: Uint8Array): Result$2<OK, PageFault$1> {
|
|
15014
|
+
return this.storeFrom(tryAsMemoryIndex(address), bytes);
|
|
15015
|
+
}
|
|
14772
15016
|
|
|
14773
|
-
|
|
14774
|
-
|
|
14775
|
-
|
|
14776
|
-
| TwoRegistersArgs
|
|
14777
|
-
| ThreeRegistersArgs
|
|
14778
|
-
| TwoRegistersOneImmediateArgs
|
|
14779
|
-
| TwoRegistersTwoImmediatesArgs
|
|
14780
|
-
| OneRegisterOneImmediateOneOffsetArgs
|
|
14781
|
-
| TwoRegistersOneOffsetArgs
|
|
14782
|
-
| OneRegisterOneImmediateArgs
|
|
14783
|
-
| OneOffsetArgs
|
|
14784
|
-
| TwoImmediatesArgs
|
|
14785
|
-
| OneRegisterTwoImmediatesArgs
|
|
14786
|
-
| OneRegisterOneExtendedWidthImmediateArgs;
|
|
15017
|
+
read(address: U32, output: Uint8Array): Result$2<OK, PageFault$1> {
|
|
15018
|
+
return this.loadInto(output, tryAsMemoryIndex(address));
|
|
15019
|
+
}
|
|
14787
15020
|
|
|
14788
|
-
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
15021
|
+
reset() {
|
|
15022
|
+
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15023
|
+
this.virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15024
|
+
this.endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX);
|
|
15025
|
+
this.memory = new Map<PageNumber, MemoryPage>(); // TODO [MaSi]: We should keep allocated pages somewhere and reuse it when it is possible
|
|
15026
|
+
}
|
|
14793
15027
|
|
|
14794
|
-
|
|
14795
|
-
this.
|
|
14796
|
-
this.
|
|
15028
|
+
copyFrom(memory: Memory) {
|
|
15029
|
+
this.sbrkIndex = memory.sbrkIndex;
|
|
15030
|
+
this.virtualSbrkIndex = memory.virtualSbrkIndex;
|
|
15031
|
+
this.endHeapIndex = memory.endHeapIndex;
|
|
15032
|
+
this.memory = memory.memory;
|
|
14797
15033
|
}
|
|
14798
15034
|
|
|
14799
|
-
|
|
14800
|
-
|
|
14801
|
-
|
|
15035
|
+
storeFrom(address: MemoryIndex, bytes: Uint8Array): Result$2<OK, PageFault> {
|
|
15036
|
+
if (bytes.length === 0) {
|
|
15037
|
+
return Result.ok(OK);
|
|
15038
|
+
}
|
|
14802
15039
|
|
|
14803
|
-
|
|
14804
|
-
|
|
14805
|
-
break;
|
|
15040
|
+
logger.insane`MEM[${address}] <- ${BytesBlob.blobFrom(bytes)}`;
|
|
15041
|
+
const pagesResult = this.getPages(address, bytes.length, AccessType.WRITE);
|
|
14806
15042
|
|
|
14807
|
-
|
|
14808
|
-
|
|
14809
|
-
|
|
14810
|
-
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
14811
|
-
break;
|
|
14812
|
-
}
|
|
15043
|
+
if (pagesResult.isError) {
|
|
15044
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
15045
|
+
}
|
|
14813
15046
|
|
|
14814
|
-
|
|
14815
|
-
|
|
14816
|
-
|
|
14817
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14818
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14819
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14820
|
-
this.nibblesDecoder.setByte(secondByte);
|
|
14821
|
-
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14822
|
-
break;
|
|
14823
|
-
}
|
|
15047
|
+
const pages = pagesResult.ok;
|
|
15048
|
+
let currentPosition: number = address;
|
|
15049
|
+
let bytesLeft = bytes.length;
|
|
14824
15050
|
|
|
14825
|
-
|
|
14826
|
-
|
|
14827
|
-
|
|
14828
|
-
|
|
14829
|
-
|
|
15051
|
+
for (const page of pages) {
|
|
15052
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE);
|
|
15053
|
+
const bytesToWrite = Math.min(PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15054
|
+
const sourceStartIndex = currentPosition - address;
|
|
15055
|
+
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
14830
15056
|
|
|
14831
|
-
|
|
14832
|
-
const immediateStartIndex = pc + 2;
|
|
14833
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14834
|
-
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
14835
|
-
break;
|
|
14836
|
-
}
|
|
15057
|
+
page.storeFrom(pageStartIndex, source);
|
|
14837
15058
|
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
15059
|
+
currentPosition += bytesToWrite;
|
|
15060
|
+
bytesLeft -= bytesToWrite;
|
|
15061
|
+
}
|
|
15062
|
+
return Result.ok(OK);
|
|
15063
|
+
}
|
|
14842
15064
|
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
14846
|
-
|
|
15065
|
+
private getPages(startAddress: MemoryIndex, length: number, accessType: AccessType): Result$2<MemoryPage[], PageFault> {
|
|
15066
|
+
if (length === 0) {
|
|
15067
|
+
return Result.ok([]);
|
|
15068
|
+
}
|
|
14847
15069
|
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
Math.max(0, nextInstructionDistance - 2 - immediateLength),
|
|
14851
|
-
);
|
|
14852
|
-
const offsetStartIndex = pc + 2 + immediateLength;
|
|
14853
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14854
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15070
|
+
const memoryRange = MemoryRange.fromStartAndLength(startAddress, length);
|
|
15071
|
+
const pageRange = PageRange.fromMemoryRange(memoryRange);
|
|
14855
15072
|
|
|
14856
|
-
|
|
14857
|
-
break;
|
|
14858
|
-
}
|
|
15073
|
+
const pages: MemoryPage[] = [];
|
|
14859
15074
|
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
|
|
14864
|
-
|
|
14865
|
-
|
|
14866
|
-
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
14867
|
-
const offsetStartIndex = pc + 2;
|
|
14868
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14869
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
14870
|
-
|
|
14871
|
-
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
14872
|
-
break;
|
|
14873
|
-
}
|
|
14874
|
-
|
|
14875
|
-
case ArgumentType.TWO_REGISTERS: {
|
|
14876
|
-
const firstByte = this.code[pc + 1];
|
|
14877
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14878
|
-
result.firstRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14879
|
-
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14880
|
-
break;
|
|
14881
|
-
}
|
|
14882
|
-
|
|
14883
|
-
case ArgumentType.ONE_OFFSET: {
|
|
14884
|
-
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
14885
|
-
const offsetStartIndex = pc + 1;
|
|
14886
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14887
|
-
const offsetBytes = this.code.subarray(offsetStartIndex, offsetEndIndex);
|
|
14888
|
-
this.offsetDecoder.setBytes(offsetBytes);
|
|
14889
|
-
const offsetValue = this.offsetDecoder.getSigned();
|
|
14890
|
-
result.nextPc = pc + offsetValue;
|
|
14891
|
-
break;
|
|
15075
|
+
for (const pageNumber of pageRange) {
|
|
15076
|
+
if (pageNumber < RESERVED_NUMBER_OF_PAGES) {
|
|
15077
|
+
return Result.error(
|
|
15078
|
+
PageFault.fromPageNumber(pageNumber, true),
|
|
15079
|
+
() => `Page fault: attempted to access reserved page ${pageNumber}`,
|
|
15080
|
+
);
|
|
14892
15081
|
}
|
|
14893
15082
|
|
|
14894
|
-
|
|
14895
|
-
const firstByte = this.code[pc + 1];
|
|
14896
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14897
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15083
|
+
const page = this.memory.get(pageNumber);
|
|
14898
15084
|
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14902
|
-
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
14903
|
-
result.immediateDecoder.setBytes(immediateBytes);
|
|
14904
|
-
break;
|
|
15085
|
+
if (page === undefined) {
|
|
15086
|
+
return Result.error(PageFault.fromPageNumber(pageNumber), () => `Page fault: page ${pageNumber} not allocated`);
|
|
14905
15087
|
}
|
|
14906
15088
|
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
const firstImmediateStartIndex = pc + 2;
|
|
14912
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14913
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14914
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
14915
|
-
|
|
14916
|
-
const secondImmediateLength = Math.min(
|
|
14917
|
-
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
14918
|
-
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
15089
|
+
if (accessType === AccessType.WRITE && !page.isWriteable()) {
|
|
15090
|
+
return Result.error(
|
|
15091
|
+
PageFault.fromPageNumber(pageNumber, true),
|
|
15092
|
+
() => `Page fault: attempted to write to read-only page ${pageNumber}`,
|
|
14919
15093
|
);
|
|
14920
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14921
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14922
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14923
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14924
|
-
break;
|
|
14925
15094
|
}
|
|
14926
15095
|
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14930
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15096
|
+
pages.push(page);
|
|
15097
|
+
}
|
|
14931
15098
|
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
15099
|
+
return Result.ok(pages);
|
|
15100
|
+
}
|
|
15101
|
+
/**
|
|
15102
|
+
* Read content of the memory at `[address, address + result.length)` and
|
|
15103
|
+
* write the result into the `result` buffer.
|
|
15104
|
+
*
|
|
15105
|
+
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
15106
|
+
*/
|
|
15107
|
+
loadInto(result: Uint8Array, startAddress: MemoryIndex): Result$2<OK, PageFault> {
|
|
15108
|
+
if (result.length === 0) {
|
|
15109
|
+
return Result.ok(OK);
|
|
15110
|
+
}
|
|
14937
15111
|
|
|
14938
|
-
|
|
14939
|
-
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
14940
|
-
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
14941
|
-
);
|
|
14942
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14943
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14944
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14945
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14946
|
-
break;
|
|
14947
|
-
}
|
|
15112
|
+
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
14948
15113
|
|
|
14949
|
-
|
|
14950
|
-
|
|
14951
|
-
|
|
14952
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14953
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15114
|
+
if (pagesResult.isError) {
|
|
15115
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
15116
|
+
}
|
|
14954
15117
|
|
|
14955
|
-
|
|
14956
|
-
this.nibblesDecoder.setByte(secondByte);
|
|
14957
|
-
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
14958
|
-
const firstImmediateStartIndex = pc + 3;
|
|
14959
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14960
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14961
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15118
|
+
const pages = pagesResult.ok;
|
|
14962
15119
|
|
|
14963
|
-
|
|
14964
|
-
|
|
14965
|
-
Math.max(0, nextInstructionDistance - 3 - firstImmediateLength),
|
|
14966
|
-
);
|
|
14967
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14968
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14969
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14970
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14971
|
-
break;
|
|
14972
|
-
}
|
|
15120
|
+
let currentPosition: number = startAddress;
|
|
15121
|
+
let bytesLeft = result.length;
|
|
14973
15122
|
|
|
14974
|
-
|
|
14975
|
-
|
|
14976
|
-
|
|
14977
|
-
|
|
15123
|
+
for (const page of pages) {
|
|
15124
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE);
|
|
15125
|
+
const bytesToRead = Math.min(PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15126
|
+
const destinationStartIndex = currentPosition - startAddress;
|
|
15127
|
+
const destination = result.subarray(destinationStartIndex);
|
|
14978
15128
|
|
|
14979
|
-
|
|
14980
|
-
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
break;
|
|
14984
|
-
}
|
|
15129
|
+
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
15130
|
+
|
|
15131
|
+
currentPosition += bytesToRead;
|
|
15132
|
+
bytesLeft -= bytesToRead;
|
|
14985
15133
|
}
|
|
15134
|
+
|
|
15135
|
+
logger.insane`MEM[${startAddress}] => ${BytesBlob.blobFrom(result)}`;
|
|
15136
|
+
return Result.ok(OK);
|
|
14986
15137
|
}
|
|
14987
|
-
}
|
|
14988
15138
|
|
|
14989
|
-
|
|
14990
|
-
|
|
15139
|
+
sbrk(length: number): SbrkIndex {
|
|
15140
|
+
const currentSbrkIndex = this.sbrkIndex;
|
|
15141
|
+
const currentVirtualSbrkIndex = this.virtualSbrkIndex;
|
|
14991
15142
|
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
|
|
15143
|
+
// new sbrk index is bigger than 2 ** 32 or endHeapIndex
|
|
15144
|
+
if (MAX_MEMORY_INDEX < currentVirtualSbrkIndex + length || currentVirtualSbrkIndex + length > this.endHeapIndex) {
|
|
15145
|
+
throw new OutOfMemory();
|
|
15146
|
+
}
|
|
14996
15147
|
|
|
14997
|
-
|
|
14998
|
-
type: ArgumentType.ONE_IMMEDIATE,
|
|
14999
|
-
noOfBytesToSkip: 1,
|
|
15000
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
15001
|
-
};
|
|
15148
|
+
const newVirtualSbrkIndex = tryAsSbrkIndex(this.virtualSbrkIndex + length);
|
|
15002
15149
|
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
};
|
|
15150
|
+
// no alllocation needed
|
|
15151
|
+
if (newVirtualSbrkIndex <= currentSbrkIndex) {
|
|
15152
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
15153
|
+
return currentVirtualSbrkIndex;
|
|
15154
|
+
}
|
|
15009
15155
|
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
};
|
|
15156
|
+
// standard allocation using "Writeable" pages
|
|
15157
|
+
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize(newVirtualSbrkIndex));
|
|
15158
|
+
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
15159
|
+
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15160
|
+
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE;
|
|
15161
|
+
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
15017
15162
|
|
|
15018
|
-
|
|
15019
|
-
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
15023
|
-
nextPc: 0,
|
|
15024
|
-
};
|
|
15163
|
+
for (const pageNumber of rangeToAllocate) {
|
|
15164
|
+
const page = new WriteablePage(pageNumber);
|
|
15165
|
+
this.memory.set(pageNumber, page);
|
|
15166
|
+
}
|
|
15025
15167
|
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
|
|
15029
|
-
|
|
15030
|
-
secondRegisterIndex: 0,
|
|
15031
|
-
nextPc: 0,
|
|
15032
|
-
};
|
|
15168
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
15169
|
+
this.sbrkIndex = newSbrkIndex;
|
|
15170
|
+
return currentVirtualSbrkIndex;
|
|
15171
|
+
}
|
|
15033
15172
|
|
|
15034
|
-
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
|
|
15038
|
-
secondRegisterIndex: 0,
|
|
15039
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
15040
|
-
};
|
|
15173
|
+
getPageDump(pageNumber: PageNumber) {
|
|
15174
|
+
const page = this.memory.get(pageNumber);
|
|
15175
|
+
return page?.getPageDump() ?? null;
|
|
15176
|
+
}
|
|
15041
15177
|
|
|
15042
|
-
|
|
15043
|
-
|
|
15044
|
-
|
|
15045
|
-
|
|
15046
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
15047
|
-
};
|
|
15178
|
+
getDirtyPages() {
|
|
15179
|
+
return this.memory.keys();
|
|
15180
|
+
}
|
|
15181
|
+
}
|
|
15048
15182
|
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
registerIndex: 0,
|
|
15053
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
15054
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
15055
|
-
};
|
|
15183
|
+
declare class MemoryBuilder {
|
|
15184
|
+
private readonly initialMemory: Map<PageNumber, MemoryPage> = new Map();
|
|
15185
|
+
private isFinalized = false;
|
|
15056
15186
|
|
|
15057
|
-
|
|
15058
|
-
|
|
15059
|
-
|
|
15060
|
-
|
|
15061
|
-
}
|
|
15187
|
+
private ensureNotFinalized() {
|
|
15188
|
+
if (this.isFinalized) {
|
|
15189
|
+
throw new FinalizedBuilderModification();
|
|
15190
|
+
}
|
|
15191
|
+
}
|
|
15062
15192
|
|
|
15063
|
-
|
|
15064
|
-
|
|
15065
|
-
|
|
15066
|
-
|
|
15067
|
-
|
|
15068
|
-
};
|
|
15193
|
+
private ensureNoReservedMemoryUsage(range: MemoryRange) {
|
|
15194
|
+
if (range.overlapsWith(RESERVED_MEMORY_RANGE)) {
|
|
15195
|
+
throw new ReservedMemoryFault();
|
|
15196
|
+
}
|
|
15197
|
+
}
|
|
15069
15198
|
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
15073
|
-
|
|
15074
|
-
|
|
15075
|
-
|
|
15076
|
-
|
|
15077
|
-
|
|
15199
|
+
/**
|
|
15200
|
+
* Create entire readable pages to handle the `[start, end)` range.
|
|
15201
|
+
*
|
|
15202
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
15203
|
+
* they need to be the start indices of the pages.
|
|
15204
|
+
*
|
|
15205
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
15206
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
15207
|
+
*/
|
|
15208
|
+
setReadablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15209
|
+
this.ensureNotFinalized();
|
|
15210
|
+
check`${start < end} end has to be bigger than start`;
|
|
15211
|
+
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15212
|
+
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15213
|
+
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15078
15214
|
|
|
15079
|
-
|
|
15080
|
-
|
|
15081
|
-
noOfBytesToSkip: 9,
|
|
15082
|
-
registerIndex: 0,
|
|
15083
|
-
immediateDecoder: new ExtendedWitdthImmediateDecoder(),
|
|
15084
|
-
};
|
|
15215
|
+
const length = end - start;
|
|
15216
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15085
15217
|
|
|
15086
|
-
|
|
15087
|
-
};
|
|
15218
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15088
15219
|
|
|
15089
|
-
|
|
15090
|
-
|
|
15091
|
-
FALLTHROUGH = 1,
|
|
15092
|
-
ECALLI = 10,
|
|
15093
|
-
LOAD_IMM_64 = 20,
|
|
15094
|
-
STORE_IMM_U8 = 30,
|
|
15095
|
-
STORE_IMM_U16 = 31,
|
|
15096
|
-
STORE_IMM_U32 = 32,
|
|
15097
|
-
STORE_IMM_U64 = 33,
|
|
15098
|
-
JUMP = 40,
|
|
15099
|
-
JUMP_IND = 50,
|
|
15100
|
-
LOAD_IMM = 51,
|
|
15101
|
-
LOAD_U8 = 52,
|
|
15102
|
-
LOAD_I8 = 53,
|
|
15103
|
-
LOAD_U16 = 54,
|
|
15104
|
-
LOAD_I16 = 55,
|
|
15105
|
-
LOAD_U32 = 56,
|
|
15106
|
-
LOAD_I32 = 57,
|
|
15107
|
-
LOAD_U64 = 58,
|
|
15108
|
-
STORE_U8 = 59,
|
|
15109
|
-
STORE_U16 = 60,
|
|
15110
|
-
STORE_U32 = 61,
|
|
15111
|
-
STORE_U64 = 62,
|
|
15112
|
-
STORE_IMM_IND_U8 = 70,
|
|
15113
|
-
STORE_IMM_IND_U16 = 71,
|
|
15114
|
-
STORE_IMM_IND_U32 = 72,
|
|
15115
|
-
STORE_IMM_IND_U64 = 73,
|
|
15116
|
-
LOAD_IMM_JUMP = 80,
|
|
15117
|
-
BRANCH_EQ_IMM = 81,
|
|
15118
|
-
BRANCH_NE_IMM = 82,
|
|
15119
|
-
BRANCH_LT_U_IMM = 83,
|
|
15120
|
-
BRANCH_LE_U_IMM = 84,
|
|
15121
|
-
BRANCH_GE_U_IMM = 85,
|
|
15122
|
-
BRANCH_GT_U_IMM = 86,
|
|
15123
|
-
BRANCH_LT_S_IMM = 87,
|
|
15124
|
-
BRANCH_LE_S_IMM = 88,
|
|
15125
|
-
BRANCH_GE_S_IMM = 89,
|
|
15126
|
-
BRANCH_GT_S_IMM = 90,
|
|
15127
|
-
MOVE_REG = 100,
|
|
15128
|
-
SBRK = 101,
|
|
15129
|
-
COUNT_SET_BITS_64 = 102,
|
|
15130
|
-
COUNT_SET_BITS_32 = 103,
|
|
15131
|
-
LEADING_ZERO_BITS_64 = 104,
|
|
15132
|
-
LEADING_ZERO_BITS_32 = 105,
|
|
15133
|
-
TRAILING_ZERO_BITS_64 = 106,
|
|
15134
|
-
TRAILING_ZERO_BITS_32 = 107,
|
|
15135
|
-
SIGN_EXTEND_8 = 108,
|
|
15136
|
-
SIGN_EXTEND_16 = 109,
|
|
15137
|
-
ZERO_EXTEND_16 = 110,
|
|
15138
|
-
REVERSE_BYTES = 111,
|
|
15139
|
-
STORE_IND_U8 = 120,
|
|
15140
|
-
STORE_IND_U16 = 121,
|
|
15141
|
-
STORE_IND_U32 = 122,
|
|
15142
|
-
STORE_IND_U64 = 123,
|
|
15143
|
-
LOAD_IND_U8 = 124,
|
|
15144
|
-
LOAD_IND_I8 = 125,
|
|
15145
|
-
LOAD_IND_U16 = 126,
|
|
15146
|
-
LOAD_IND_I16 = 127,
|
|
15147
|
-
LOAD_IND_U32 = 128,
|
|
15148
|
-
LOAD_IND_I32 = 129,
|
|
15149
|
-
LOAD_IND_U64 = 130,
|
|
15150
|
-
ADD_IMM_32 = 131,
|
|
15151
|
-
AND_IMM = 132,
|
|
15152
|
-
XOR_IMM = 133,
|
|
15153
|
-
OR_IMM = 134,
|
|
15154
|
-
MUL_IMM_32 = 135,
|
|
15155
|
-
SET_LT_U_IMM = 136,
|
|
15156
|
-
SET_LT_S_IMM = 137,
|
|
15157
|
-
SHLO_L_IMM_32 = 138,
|
|
15158
|
-
SHLO_R_IMM_32 = 139,
|
|
15159
|
-
SHAR_R_IMM_32 = 140,
|
|
15160
|
-
NEG_ADD_IMM_32 = 141,
|
|
15161
|
-
SET_GT_U_IMM = 142,
|
|
15162
|
-
SET_GT_S_IMM = 143,
|
|
15163
|
-
SHLO_L_IMM_ALT_32 = 144,
|
|
15164
|
-
SHLO_R_IMM_ALT_32 = 145,
|
|
15165
|
-
SHAR_R_IMM_ALT_32 = 146,
|
|
15166
|
-
CMOV_IZ_IMM = 147,
|
|
15167
|
-
CMOV_NZ_IMM = 148,
|
|
15168
|
-
ADD_IMM_64 = 149,
|
|
15169
|
-
MUL_IMM_64 = 150,
|
|
15170
|
-
SHLO_L_IMM_64 = 151,
|
|
15171
|
-
SHLO_R_IMM_64 = 152,
|
|
15172
|
-
SHAR_R_IMM_64 = 153,
|
|
15173
|
-
NEG_ADD_IMM_64 = 154,
|
|
15174
|
-
SHLO_L_IMM_ALT_64 = 155,
|
|
15175
|
-
SHLO_R_IMM_ALT_64 = 156,
|
|
15176
|
-
SHAR_R_IMM_ALT_64 = 157,
|
|
15177
|
-
ROT_R_64_IMM = 158,
|
|
15178
|
-
ROT_R_64_IMM_ALT = 159,
|
|
15179
|
-
ROT_R_32_IMM = 160,
|
|
15180
|
-
ROT_R_32_IMM_ALT = 161,
|
|
15181
|
-
BRANCH_EQ = 170,
|
|
15182
|
-
BRANCH_NE = 171,
|
|
15183
|
-
BRANCH_LT_U = 172,
|
|
15184
|
-
BRANCH_LT_S = 173,
|
|
15185
|
-
BRANCH_GE_U = 174,
|
|
15186
|
-
BRANCH_GE_S = 175,
|
|
15187
|
-
LOAD_IMM_JUMP_IND = 180,
|
|
15188
|
-
ADD_32 = 190,
|
|
15189
|
-
SUB_32 = 191,
|
|
15190
|
-
MUL_32 = 192,
|
|
15191
|
-
DIV_U_32 = 193,
|
|
15192
|
-
DIV_S_32 = 194,
|
|
15193
|
-
REM_U_32 = 195,
|
|
15194
|
-
REM_S_32 = 196,
|
|
15195
|
-
SHLO_L_32 = 197,
|
|
15196
|
-
SHLO_R_32 = 198,
|
|
15197
|
-
SHAR_R_32 = 199,
|
|
15198
|
-
ADD_64 = 200,
|
|
15199
|
-
SUB_64 = 201,
|
|
15200
|
-
MUL_64 = 202,
|
|
15201
|
-
DIV_U_64 = 203,
|
|
15202
|
-
DIV_S_64 = 204,
|
|
15203
|
-
REM_U_64 = 205,
|
|
15204
|
-
REM_S_64 = 206,
|
|
15205
|
-
SHLO_L_64 = 207,
|
|
15206
|
-
SHLO_R_64 = 208,
|
|
15207
|
-
SHAR_R_64 = 209,
|
|
15208
|
-
AND = 210,
|
|
15209
|
-
XOR = 211,
|
|
15210
|
-
OR = 212,
|
|
15211
|
-
MUL_UPPER_S_S = 213,
|
|
15212
|
-
MUL_UPPER_U_U = 214,
|
|
15213
|
-
MUL_UPPER_S_U = 215,
|
|
15214
|
-
SET_LT_U = 216,
|
|
15215
|
-
SET_LT_S = 217,
|
|
15216
|
-
CMOV_IZ = 218,
|
|
15217
|
-
CMOV_NZ = 219,
|
|
15218
|
-
ROT_L_64 = 220,
|
|
15219
|
-
ROT_L_32 = 221,
|
|
15220
|
-
ROT_R_64 = 222,
|
|
15221
|
-
ROT_R_32 = 223,
|
|
15222
|
-
AND_INV = 224,
|
|
15223
|
-
OR_INV = 225,
|
|
15224
|
-
XNOR = 226,
|
|
15225
|
-
MAX = 227,
|
|
15226
|
-
MAX_U = 228,
|
|
15227
|
-
MIN = 229,
|
|
15228
|
-
MIN_U = 230,
|
|
15229
|
-
}
|
|
15220
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
15221
|
+
const noOfPages = pages.length;
|
|
15230
15222
|
|
|
15231
|
-
|
|
15232
|
-
|
|
15223
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
15224
|
+
const pageNumber = pages[i];
|
|
15225
|
+
const dataChunk = data.subarray(i * PAGE_SIZE, (i + 1) * PAGE_SIZE);
|
|
15226
|
+
const page = new ReadablePage(pageNumber, dataChunk);
|
|
15227
|
+
this.initialMemory.set(pageNumber, page);
|
|
15228
|
+
}
|
|
15233
15229
|
|
|
15234
|
-
|
|
15235
|
-
|
|
15230
|
+
return this;
|
|
15231
|
+
}
|
|
15236
15232
|
|
|
15237
|
-
|
|
15233
|
+
/**
|
|
15234
|
+
* Create entire writeable pages to handle the `[start, end)` range.
|
|
15235
|
+
*
|
|
15236
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
15237
|
+
* they need to be the start indices of the pages.
|
|
15238
|
+
*
|
|
15239
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
15240
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
15241
|
+
*/
|
|
15242
|
+
setWriteablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15243
|
+
this.ensureNotFinalized();
|
|
15244
|
+
check`${start < end} end has to be bigger than start`;
|
|
15245
|
+
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15246
|
+
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15247
|
+
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15238
15248
|
|
|
15239
|
-
|
|
15249
|
+
const length = end - start;
|
|
15250
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15240
15251
|
|
|
15241
|
-
|
|
15242
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U16] = ArgumentType.TWO_IMMEDIATES;
|
|
15243
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U32] = ArgumentType.TWO_IMMEDIATES;
|
|
15244
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_U64] = ArgumentType.TWO_IMMEDIATES;
|
|
15252
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15245
15253
|
|
|
15246
|
-
|
|
15254
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
15255
|
+
const noOfPages = pages.length;
|
|
15247
15256
|
|
|
15248
|
-
|
|
15249
|
-
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15253
|
-
|
|
15254
|
-
instructionArgumentTypeMap[Instruction.LOAD_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15255
|
-
instructionArgumentTypeMap[Instruction.LOAD_I32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15256
|
-
instructionArgumentTypeMap[Instruction.LOAD_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15257
|
-
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15258
|
-
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15259
|
-
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15260
|
-
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15257
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
15258
|
+
const pageNumber = pages[i];
|
|
15259
|
+
const dataChunk = data.subarray(i * PAGE_SIZE, (i + 1) * PAGE_SIZE);
|
|
15260
|
+
const page = new WriteablePage(pageNumber, dataChunk);
|
|
15261
|
+
this.initialMemory.set(pageNumber, page);
|
|
15262
|
+
}
|
|
15261
15263
|
|
|
15262
|
-
|
|
15263
|
-
|
|
15264
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15265
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15266
|
-
|
|
15267
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15268
|
-
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15269
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15270
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15271
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15272
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15273
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15274
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15275
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15276
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15277
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15264
|
+
return this;
|
|
15265
|
+
}
|
|
15278
15266
|
|
|
15279
|
-
|
|
15280
|
-
|
|
15281
|
-
|
|
15282
|
-
|
|
15283
|
-
|
|
15284
|
-
|
|
15285
|
-
|
|
15286
|
-
|
|
15287
|
-
|
|
15288
|
-
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
15289
|
-
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
15290
|
-
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
15267
|
+
/**
|
|
15268
|
+
* This function can be useful when page map and initial memory data are provided separatelly.
|
|
15269
|
+
* You can use setWriteablePages/setReadablePages to create empty pages and then setData to fill them
|
|
15270
|
+
*/
|
|
15271
|
+
setData(start: MemoryIndex, data: Uint8Array) {
|
|
15272
|
+
this.ensureNotFinalized();
|
|
15273
|
+
const pageOffset = start % PAGE_SIZE;
|
|
15274
|
+
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15275
|
+
check`${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15291
15276
|
|
|
15292
|
-
|
|
15293
|
-
|
|
15294
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15295
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15296
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15297
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15298
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15299
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15300
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15301
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15302
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15303
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15304
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15305
|
-
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15306
|
-
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15307
|
-
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15308
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15309
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15310
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15311
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15312
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15313
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15314
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15315
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15316
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15317
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15318
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15319
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15320
|
-
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15321
|
-
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15322
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15323
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15324
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15325
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15326
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15327
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15328
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15329
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15330
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15331
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15332
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15333
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15277
|
+
const length = data.length;
|
|
15278
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15334
15279
|
|
|
15335
|
-
|
|
15336
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15337
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15338
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15339
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15340
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15280
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15341
15281
|
|
|
15342
|
-
|
|
15282
|
+
const pageNumber = getPageNumber(start);
|
|
15283
|
+
const page = this.initialMemory.get(pageNumber);
|
|
15343
15284
|
|
|
15344
|
-
|
|
15345
|
-
|
|
15346
|
-
|
|
15347
|
-
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
15348
|
-
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
15349
|
-
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
15350
|
-
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
15351
|
-
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
15352
|
-
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
15353
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
15354
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
15355
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
15356
|
-
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
15357
|
-
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
15358
|
-
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
15359
|
-
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
15360
|
-
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
15361
|
-
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
15362
|
-
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
15363
|
-
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
15364
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
15365
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
15366
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
15367
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15368
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15369
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
15370
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15371
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15372
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
15373
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
15374
|
-
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
15375
|
-
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
15376
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15377
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15378
|
-
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
15379
|
-
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
15380
|
-
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
15381
|
-
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
15382
|
-
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
15383
|
-
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
15384
|
-
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
15285
|
+
if (page === undefined) {
|
|
15286
|
+
throw new PageNotExist();
|
|
15287
|
+
}
|
|
15385
15288
|
|
|
15386
|
-
|
|
15387
|
-
|
|
15289
|
+
const startPageIndex = tryAsPageIndex(start - page.start);
|
|
15290
|
+
page.setData(startPageIndex, data);
|
|
15388
15291
|
|
|
15389
|
-
|
|
15390
|
-
|
|
15292
|
+
return this;
|
|
15293
|
+
}
|
|
15391
15294
|
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15295
|
+
finalize(startHeapIndex: MemoryIndex, endHeapIndex: SbrkIndex): Memory {
|
|
15296
|
+
check`
|
|
15297
|
+
${startHeapIndex <= endHeapIndex}
|
|
15298
|
+
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
15299
|
+
`;
|
|
15300
|
+
this.ensureNotFinalized();
|
|
15396
15301
|
|
|
15397
|
-
const
|
|
15398
|
-
|
|
15302
|
+
const heapRange = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
15303
|
+
const heapPagesRange = PageRange.fromMemoryRange(heapRange);
|
|
15304
|
+
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
15399
15305
|
|
|
15400
|
-
for (
|
|
15401
|
-
if (
|
|
15402
|
-
|
|
15306
|
+
for (const pageNumber of initializedPageNumbers) {
|
|
15307
|
+
if (heapPagesRange.isInRange(pageNumber)) {
|
|
15308
|
+
throw new IncorrectSbrkIndex();
|
|
15403
15309
|
}
|
|
15404
15310
|
}
|
|
15405
|
-
}
|
|
15406
|
-
|
|
15407
|
-
isBeginningOfBasicBlock(index: number) {
|
|
15408
|
-
return this.basicBlocks.has(index);
|
|
15409
|
-
}
|
|
15410
|
-
}
|
|
15411
|
-
|
|
15412
|
-
declare enum Result {
|
|
15413
|
-
HALT = 0,
|
|
15414
|
-
PANIC = 1,
|
|
15415
|
-
FAULT_ACCESS = 2,
|
|
15416
|
-
FAULT = 3,
|
|
15417
|
-
HOST = 4,
|
|
15418
|
-
}
|
|
15419
15311
|
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
*
|
|
15426
|
-
* In case of a `status === Result.FAULT` this will be the memory address
|
|
15427
|
-
* that triggered the fault.
|
|
15428
|
-
* In case of a `status === Result.HOST` this will be the host call index
|
|
15429
|
-
* that should be invoked.
|
|
15430
|
-
*
|
|
15431
|
-
* In any other circumstance the value should be `null`.
|
|
15432
|
-
*/
|
|
15433
|
-
public exitParam: number | null = null;
|
|
15312
|
+
const memory = Memory.fromInitialMemory({
|
|
15313
|
+
memory: this.initialMemory,
|
|
15314
|
+
sbrkIndex: tryAsSbrkIndex(startHeapIndex),
|
|
15315
|
+
endHeapIndex,
|
|
15316
|
+
});
|
|
15434
15317
|
|
|
15435
|
-
|
|
15436
|
-
|
|
15437
|
-
this.status = null;
|
|
15438
|
-
this.exitParam = null;
|
|
15318
|
+
this.isFinalized = true;
|
|
15319
|
+
return memory;
|
|
15439
15320
|
}
|
|
15440
15321
|
}
|
|
15441
15322
|
|
|
15442
|
-
|
|
15443
|
-
|
|
15444
|
-
declare const tryAsMemoryIndex = (index: number): MemoryIndex => {
|
|
15445
|
-
check`${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15446
|
-
return asOpaqueType(index);
|
|
15447
|
-
};
|
|
15448
|
-
|
|
15449
|
-
type SbrkIndex = Opaque<number, "sbrk index">;
|
|
15450
|
-
|
|
15451
|
-
declare const tryAsSbrkIndex = (index: number): SbrkIndex => {
|
|
15452
|
-
check`${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
15453
|
-
return asOpaqueType(index);
|
|
15454
|
-
};
|
|
15455
|
-
|
|
15456
|
-
type PageIndex = Opaque<number, "memory page index">;
|
|
15457
|
-
type PageNumber = Opaque<number, "memory page number">;
|
|
15458
|
-
|
|
15459
|
-
declare class PageFault {
|
|
15460
|
-
private constructor(
|
|
15461
|
-
public address: MemoryIndex,
|
|
15462
|
-
public isAccessFault = true,
|
|
15463
|
-
) {}
|
|
15323
|
+
declare const NO_OF_REGISTERS = 13;
|
|
15464
15324
|
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
return new PageFault(startPageIndex, isAccessFault);
|
|
15325
|
+
declare class MemorySegment extends WithDebug {
|
|
15326
|
+
static from({ start, end, data }: Omit<MemorySegment, never>) {
|
|
15327
|
+
return new MemorySegment(start, end, data);
|
|
15469
15328
|
}
|
|
15470
15329
|
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15330
|
+
constructor(
|
|
15331
|
+
public readonly start: number,
|
|
15332
|
+
public readonly end: number,
|
|
15333
|
+
public readonly data: Uint8Array | null,
|
|
15334
|
+
) {
|
|
15335
|
+
super();
|
|
15336
|
+
}
|
|
15337
|
+
}
|
|
15338
|
+
declare class SpiMemory extends WithDebug {
|
|
15339
|
+
constructor(
|
|
15340
|
+
public readonly readable: MemorySegment[],
|
|
15341
|
+
public readonly writeable: MemorySegment[],
|
|
15342
|
+
public readonly sbrkIndex: number,
|
|
15343
|
+
public readonly heapEnd: number,
|
|
15344
|
+
) {
|
|
15345
|
+
super();
|
|
15475
15346
|
}
|
|
15476
15347
|
}
|
|
15477
15348
|
|
|
15478
|
-
declare class
|
|
15479
|
-
constructor(
|
|
15480
|
-
|
|
15349
|
+
declare class SpiProgram extends WithDebug {
|
|
15350
|
+
constructor(
|
|
15351
|
+
public readonly code: Uint8Array,
|
|
15352
|
+
public readonly memory: SpiMemory,
|
|
15353
|
+
public readonly registers: BigUint64Array,
|
|
15354
|
+
) {
|
|
15355
|
+
super();
|
|
15481
15356
|
}
|
|
15482
15357
|
}
|
|
15483
15358
|
|
|
15484
15359
|
/**
|
|
15485
|
-
*
|
|
15486
|
-
* possibly empty or wrapping around.
|
|
15360
|
+
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
15487
15361
|
*
|
|
15488
|
-
*
|
|
15362
|
+
* E_n - little endian encoding, n - length
|
|
15363
|
+
* o - initial read only data
|
|
15364
|
+
* w - initial heap
|
|
15365
|
+
* z - heap pages filled with zeros
|
|
15366
|
+
* s - stack size
|
|
15367
|
+
* c - program code
|
|
15368
|
+
*
|
|
15369
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
15489
15370
|
*/
|
|
15490
|
-
declare
|
|
15491
|
-
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
15495
|
-
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
|
|
15502
|
-
|
|
15371
|
+
declare function decodeStandardProgram(program: Uint8Array, args: Uint8Array) {
|
|
15372
|
+
const decoder = Decoder.fromBlob(program);
|
|
15373
|
+
const oLength = decoder.u24();
|
|
15374
|
+
const wLength = decoder.u24();
|
|
15375
|
+
check`${args.length <= DATA_LENGTH} Incorrect arguments length`;
|
|
15376
|
+
check`${oLength <= DATA_LENGTH} Incorrect readonly segment length`;
|
|
15377
|
+
const readOnlyLength = oLength;
|
|
15378
|
+
check`${wLength <= DATA_LENGTH} Incorrect heap segment length`;
|
|
15379
|
+
const heapLength = wLength;
|
|
15380
|
+
const noOfHeapZerosPages = decoder.u16();
|
|
15381
|
+
const stackSize = decoder.u24();
|
|
15382
|
+
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
15383
|
+
const initialHeap = decoder.bytes(heapLength).raw;
|
|
15384
|
+
const codeLength = decoder.u32();
|
|
15385
|
+
const code = decoder.bytes(codeLength).raw;
|
|
15386
|
+
decoder.finish();
|
|
15503
15387
|
|
|
15504
|
-
|
|
15505
|
-
|
|
15506
|
-
|
|
15507
|
-
)
|
|
15508
|
-
|
|
15388
|
+
const readonlyDataStart = SEGMENT_SIZE;
|
|
15389
|
+
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
15390
|
+
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
15391
|
+
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
15392
|
+
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
15393
|
+
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
15394
|
+
const stackEnd = STACK_SEGMENT;
|
|
15395
|
+
const argsStart = ARGS_SEGMENT;
|
|
15396
|
+
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
15397
|
+
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
15509
15398
|
|
|
15510
|
-
|
|
15511
|
-
|
|
15512
|
-
}
|
|
15399
|
+
function nonEmpty(s: MemorySegment | false): s is MemorySegment {
|
|
15400
|
+
return s !== false;
|
|
15513
15401
|
}
|
|
15514
15402
|
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
|
|
15521
|
-
|
|
15522
|
-
|
|
15403
|
+
const readableMemory = [
|
|
15404
|
+
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
15405
|
+
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
15406
|
+
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
15407
|
+
].filter(nonEmpty);
|
|
15408
|
+
const writeableMemory = [
|
|
15409
|
+
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
15410
|
+
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
15411
|
+
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
15412
|
+
].filter(nonEmpty);
|
|
15523
15413
|
|
|
15524
|
-
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15414
|
+
return new SpiProgram(
|
|
15415
|
+
code,
|
|
15416
|
+
new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart),
|
|
15417
|
+
getRegisters(args.length),
|
|
15418
|
+
);
|
|
15419
|
+
}
|
|
15528
15420
|
|
|
15529
|
-
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
}
|
|
15421
|
+
declare function getMemorySegment(start: number, end: number, data: Uint8Array | null = null) {
|
|
15422
|
+
return new MemorySegment(start, end, data);
|
|
15423
|
+
}
|
|
15533
15424
|
|
|
15534
|
-
|
|
15535
|
-
|
|
15536
|
-
if (this.isWrapped()) {
|
|
15537
|
-
return address >= this.start || address < this.end;
|
|
15538
|
-
}
|
|
15425
|
+
declare function getRegisters(argsLength: number) {
|
|
15426
|
+
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
15539
15427
|
|
|
15540
|
-
|
|
15541
|
-
|
|
15428
|
+
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
15429
|
+
regs[0] = BigInt(LAST_PAGE);
|
|
15430
|
+
regs[1] = BigInt(STACK_SEGMENT);
|
|
15431
|
+
regs[7] = BigInt(ARGS_SEGMENT);
|
|
15432
|
+
regs[8] = BigInt(argsLength);
|
|
15542
15433
|
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
if (this.lastIndex === null || other.lastIndex === null) {
|
|
15546
|
-
return false;
|
|
15547
|
-
}
|
|
15434
|
+
return regs;
|
|
15435
|
+
}
|
|
15548
15436
|
|
|
15549
|
-
|
|
15550
|
-
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15555
|
-
|
|
15437
|
+
type index$8_MemorySegment = MemorySegment;
|
|
15438
|
+
declare const index$8_MemorySegment: typeof MemorySegment;
|
|
15439
|
+
declare const index$8_NO_OF_REGISTERS: typeof NO_OF_REGISTERS;
|
|
15440
|
+
type index$8_SpiMemory = SpiMemory;
|
|
15441
|
+
declare const index$8_SpiMemory: typeof SpiMemory;
|
|
15442
|
+
type index$8_SpiProgram = SpiProgram;
|
|
15443
|
+
declare const index$8_SpiProgram: typeof SpiProgram;
|
|
15444
|
+
declare const index$8_decodeStandardProgram: typeof decodeStandardProgram;
|
|
15445
|
+
declare const index$8_getMemorySegment: typeof getMemorySegment;
|
|
15446
|
+
declare const index$8_getRegisters: typeof getRegisters;
|
|
15447
|
+
declare namespace index$8 {
|
|
15448
|
+
export {
|
|
15449
|
+
index$8_MemorySegment as MemorySegment,
|
|
15450
|
+
index$8_NO_OF_REGISTERS as NO_OF_REGISTERS,
|
|
15451
|
+
index$8_SpiMemory as SpiMemory,
|
|
15452
|
+
index$8_SpiProgram as SpiProgram,
|
|
15453
|
+
index$8_decodeStandardProgram as decodeStandardProgram,
|
|
15454
|
+
index$8_getMemorySegment as getMemorySegment,
|
|
15455
|
+
index$8_getRegisters as getRegisters,
|
|
15456
|
+
};
|
|
15556
15457
|
}
|
|
15557
15458
|
|
|
15558
|
-
declare
|
|
15559
|
-
|
|
15459
|
+
declare class Program {
|
|
15460
|
+
static fromSpi(blob: Uint8Array, args: Uint8Array, hasMetadata: boolean) {
|
|
15461
|
+
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15462
|
+
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
15463
|
+
const regs = new Registers();
|
|
15464
|
+
regs.copyFrom(registers);
|
|
15465
|
+
const memoryBuilder = new MemoryBuilder();
|
|
15560
15466
|
|
|
15561
|
-
|
|
15562
|
-
|
|
15563
|
-
|
|
15467
|
+
for (const { start, end, data } of rawMemory.readable) {
|
|
15468
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
15469
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
15470
|
+
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15471
|
+
}
|
|
15564
15472
|
|
|
15565
|
-
|
|
15566
|
-
|
|
15473
|
+
for (const { start, end, data } of rawMemory.writeable) {
|
|
15474
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
15475
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
15476
|
+
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15477
|
+
}
|
|
15567
15478
|
|
|
15568
|
-
|
|
15569
|
-
|
|
15570
|
-
|
|
15571
|
-
*
|
|
15572
|
-
* Note that the `res` might be bigger than the number of bytes length, but cannot be smaller.
|
|
15573
|
-
*
|
|
15574
|
-
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
15575
|
-
* NOTE That the `result` might be partially modified in case `PageFault` occurs!
|
|
15576
|
-
*/
|
|
15577
|
-
abstract loadInto(res: Uint8Array, address: PageIndex, length: number): Result$2<OK, PageFault>;
|
|
15479
|
+
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
15480
|
+
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
15481
|
+
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
15578
15482
|
|
|
15579
|
-
|
|
15580
|
-
|
|
15581
|
-
*
|
|
15582
|
-
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
15583
|
-
*/
|
|
15584
|
-
abstract storeFrom(address: PageIndex, data: Uint8Array): Result$2<OK, PageFault>;
|
|
15585
|
-
/**
|
|
15586
|
-
* Get dump of the entire page. Should only be used for the debugger-adapter because it
|
|
15587
|
-
* might be inefficient.
|
|
15588
|
-
*/
|
|
15589
|
-
abstract getPageDump(): Uint8Array;
|
|
15483
|
+
return new Program(code, regs, memory, metadata);
|
|
15484
|
+
}
|
|
15590
15485
|
|
|
15591
|
-
|
|
15486
|
+
static fromGeneric(blob: Uint8Array, hasMetadata: boolean) {
|
|
15487
|
+
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15488
|
+
const regs = new Registers();
|
|
15489
|
+
const memory = new Memory();
|
|
15490
|
+
return new Program(code, regs, memory, metadata);
|
|
15491
|
+
}
|
|
15492
|
+
|
|
15493
|
+
private constructor(
|
|
15494
|
+
public readonly code: Uint8Array,
|
|
15495
|
+
public readonly registers: Registers,
|
|
15496
|
+
public readonly memory: Memory,
|
|
15497
|
+
public metadata: Uint8Array = new Uint8Array(),
|
|
15498
|
+
) {}
|
|
15592
15499
|
}
|
|
15593
15500
|
|
|
15594
15501
|
/**
|
|
15595
|
-
*
|
|
15596
|
-
*
|
|
15597
|
-
*
|
|
15502
|
+
* A function that splits preimage into metadata and code.
|
|
15503
|
+
*
|
|
15504
|
+
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
15598
15505
|
*/
|
|
15599
|
-
declare
|
|
15600
|
-
|
|
15601
|
-
|
|
15602
|
-
|
|
15603
|
-
|
|
15604
|
-
}
|
|
15605
|
-
interface ArrayBuffer {
|
|
15606
|
-
resize(length: number): void;
|
|
15607
|
-
}
|
|
15506
|
+
declare function extractCodeAndMetadata(blobWithMetadata: Uint8Array) {
|
|
15507
|
+
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
15508
|
+
const metadata = decoder.bytesBlob().raw;
|
|
15509
|
+
const code = decoder.remainingBytes().raw;
|
|
15510
|
+
return { metadata, code };
|
|
15608
15511
|
}
|
|
15609
15512
|
|
|
15610
|
-
type
|
|
15611
|
-
|
|
15612
|
-
|
|
15613
|
-
|
|
15614
|
-
|
|
15615
|
-
|
|
15616
|
-
|
|
15617
|
-
|
|
15618
|
-
WRITE = 1,
|
|
15513
|
+
type index$7_Program = Program;
|
|
15514
|
+
declare const index$7_Program: typeof Program;
|
|
15515
|
+
declare const index$7_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
15516
|
+
declare namespace index$7 {
|
|
15517
|
+
export {
|
|
15518
|
+
index$7_Program as Program,
|
|
15519
|
+
index$7_extractCodeAndMetadata as extractCodeAndMetadata,
|
|
15520
|
+
};
|
|
15619
15521
|
}
|
|
15620
15522
|
|
|
15621
|
-
|
|
15622
|
-
|
|
15623
|
-
|
|
15624
|
-
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
|
|
15523
|
+
/**
|
|
15524
|
+
* Mask class is an implementation of skip function defined in GP.
|
|
15525
|
+
*
|
|
15526
|
+
* https://graypaper.fluffylabs.dev/#/5f542d7/237201239801
|
|
15527
|
+
*/
|
|
15528
|
+
declare class Mask {
|
|
15529
|
+
/**
|
|
15530
|
+
* The lookup table will have `0` at the index which corresponds to an instruction on the same index in the bytecode.
|
|
15531
|
+
* In case the value is non-zero it signifies the offset to the index with next instruction.
|
|
15532
|
+
*
|
|
15533
|
+
* Example:
|
|
15534
|
+
* ```
|
|
15535
|
+
* 0..1..2..3..4..5..6..7..8..9 # Indices
|
|
15536
|
+
* 0..2..1..0..1..0..3..2..1..0 # lookupTable forward values
|
|
15537
|
+
* ```
|
|
15538
|
+
* There are instructions at indices `0, 3, 5, 9`.
|
|
15539
|
+
*/
|
|
15540
|
+
private lookupTableForward: Uint8Array;
|
|
15541
|
+
|
|
15542
|
+
constructor(mask: BitVec) {
|
|
15543
|
+
this.lookupTableForward = this.buildLookupTableForward(mask);
|
|
15629
15544
|
}
|
|
15630
15545
|
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
private virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
15634
|
-
private endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX),
|
|
15635
|
-
private memory = new Map<PageNumber, MemoryPage>(),
|
|
15636
|
-
) {}
|
|
15637
|
-
|
|
15638
|
-
reset() {
|
|
15639
|
-
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15640
|
-
this.virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
15641
|
-
this.endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX);
|
|
15642
|
-
this.memory = new Map<PageNumber, MemoryPage>(); // TODO [MaSi]: We should keep allocated pages somewhere and reuse it when it is possible
|
|
15546
|
+
isInstruction(index: number) {
|
|
15547
|
+
return this.lookupTableForward[index] === 0;
|
|
15643
15548
|
}
|
|
15644
15549
|
|
|
15645
|
-
|
|
15646
|
-
|
|
15647
|
-
this.
|
|
15648
|
-
this.endHeapIndex = memory.endHeapIndex;
|
|
15649
|
-
this.memory = memory.memory;
|
|
15550
|
+
getNoOfBytesToNextInstruction(index: number) {
|
|
15551
|
+
check`${index >= 0} index (${index}) cannot be a negative number`;
|
|
15552
|
+
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
15650
15553
|
}
|
|
15651
15554
|
|
|
15652
|
-
|
|
15653
|
-
|
|
15654
|
-
|
|
15655
|
-
|
|
15656
|
-
|
|
15657
|
-
|
|
15658
|
-
|
|
15659
|
-
|
|
15660
|
-
|
|
15661
|
-
|
|
15555
|
+
private buildLookupTableForward(mask: BitVec) {
|
|
15556
|
+
const table = safeAllocUint8Array(mask.bitLength);
|
|
15557
|
+
let lastInstructionOffset = 0;
|
|
15558
|
+
for (let i = mask.bitLength - 1; i >= 0; i--) {
|
|
15559
|
+
if (mask.isSet(i)) {
|
|
15560
|
+
lastInstructionOffset = 0;
|
|
15561
|
+
} else {
|
|
15562
|
+
lastInstructionOffset++;
|
|
15563
|
+
}
|
|
15564
|
+
table[i] = lastInstructionOffset;
|
|
15662
15565
|
}
|
|
15566
|
+
return table;
|
|
15567
|
+
}
|
|
15663
15568
|
|
|
15664
|
-
|
|
15665
|
-
|
|
15666
|
-
|
|
15569
|
+
static empty() {
|
|
15570
|
+
return new Mask(BitVec.empty(0));
|
|
15571
|
+
}
|
|
15572
|
+
}
|
|
15667
15573
|
|
|
15668
|
-
|
|
15669
|
-
|
|
15670
|
-
|
|
15671
|
-
|
|
15672
|
-
|
|
15574
|
+
declare enum ArgumentType {
|
|
15575
|
+
NO_ARGUMENTS = 0,
|
|
15576
|
+
ONE_IMMEDIATE = 1,
|
|
15577
|
+
TWO_IMMEDIATES = 2,
|
|
15578
|
+
ONE_OFFSET = 3,
|
|
15579
|
+
ONE_REGISTER_ONE_IMMEDIATE = 4,
|
|
15580
|
+
ONE_REGISTER_TWO_IMMEDIATES = 5,
|
|
15581
|
+
ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET = 6,
|
|
15582
|
+
TWO_REGISTERS = 7,
|
|
15583
|
+
TWO_REGISTERS_ONE_IMMEDIATE = 8,
|
|
15584
|
+
TWO_REGISTERS_ONE_OFFSET = 9,
|
|
15585
|
+
TWO_REGISTERS_TWO_IMMEDIATES = 10,
|
|
15586
|
+
THREE_REGISTERS = 11,
|
|
15587
|
+
ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE = 12,
|
|
15588
|
+
}
|
|
15673
15589
|
|
|
15674
|
-
|
|
15590
|
+
declare class ExtendedWitdthImmediateDecoder {
|
|
15591
|
+
private unsignedImmediate: BigUint64Array;
|
|
15592
|
+
private bytes: Uint8Array;
|
|
15675
15593
|
|
|
15676
|
-
|
|
15677
|
-
|
|
15678
|
-
|
|
15679
|
-
|
|
15594
|
+
constructor() {
|
|
15595
|
+
const buffer = new ArrayBuffer(IMMEDIATE_SIZE);
|
|
15596
|
+
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
15597
|
+
this.bytes = new Uint8Array(buffer);
|
|
15680
15598
|
}
|
|
15681
15599
|
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
|
|
15600
|
+
setBytes(bytes: Uint8Array) {
|
|
15601
|
+
let i = 0;
|
|
15602
|
+
for (; i < bytes.length; i++) {
|
|
15603
|
+
this.bytes[i] = bytes[i];
|
|
15685
15604
|
}
|
|
15686
15605
|
|
|
15687
|
-
|
|
15688
|
-
|
|
15606
|
+
for (; i < IMMEDIATE_SIZE; i++) {
|
|
15607
|
+
this.bytes[i] = 0;
|
|
15608
|
+
}
|
|
15609
|
+
}
|
|
15689
15610
|
|
|
15690
|
-
|
|
15611
|
+
getValue() {
|
|
15612
|
+
return this.unsignedImmediate[0];
|
|
15613
|
+
}
|
|
15691
15614
|
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
() => `Page fault: attempted to access reserved page ${pageNumber}`,
|
|
15697
|
-
);
|
|
15698
|
-
}
|
|
15615
|
+
getBytesAsLittleEndian() {
|
|
15616
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE);
|
|
15617
|
+
}
|
|
15618
|
+
}
|
|
15699
15619
|
|
|
15700
|
-
|
|
15620
|
+
declare class ImmediateDecoder {
|
|
15621
|
+
private u32: Uint32Array;
|
|
15622
|
+
private i32: Int32Array;
|
|
15623
|
+
private u64: BigUint64Array;
|
|
15624
|
+
private i64: BigInt64Array;
|
|
15625
|
+
private view: DataView;
|
|
15626
|
+
private bytes: Uint8Array;
|
|
15701
15627
|
|
|
15702
|
-
|
|
15703
|
-
|
|
15704
|
-
|
|
15628
|
+
constructor() {
|
|
15629
|
+
const buffer = new ArrayBuffer(BUFFER_SIZE);
|
|
15630
|
+
this.u32 = new Uint32Array(buffer);
|
|
15631
|
+
this.i32 = new Int32Array(buffer);
|
|
15632
|
+
this.u64 = new BigUint64Array(buffer);
|
|
15633
|
+
this.i64 = new BigInt64Array(buffer);
|
|
15634
|
+
this.view = new DataView(buffer);
|
|
15635
|
+
this.bytes = new Uint8Array(buffer);
|
|
15636
|
+
}
|
|
15705
15637
|
|
|
15706
|
-
|
|
15707
|
-
|
|
15708
|
-
|
|
15709
|
-
|
|
15710
|
-
|
|
15711
|
-
}
|
|
15638
|
+
setBytes(bytes: Uint8Array) {
|
|
15639
|
+
const n = bytes.length;
|
|
15640
|
+
const msb = n > 0 ? bytes[n - 1] & 0x80 : 0;
|
|
15641
|
+
const noOfBytes = Math.min(n, BUFFER_SIZE);
|
|
15642
|
+
const prefix = msb !== 0 ? 0xff : 0x00;
|
|
15712
15643
|
|
|
15713
|
-
|
|
15644
|
+
for (let i = 0; i < noOfBytes; i++) {
|
|
15645
|
+
this.view.setUint8(i, bytes[i]);
|
|
15714
15646
|
}
|
|
15715
15647
|
|
|
15716
|
-
|
|
15648
|
+
for (let i = n; i < BUFFER_SIZE; i++) {
|
|
15649
|
+
this.view.setUint8(i, prefix);
|
|
15650
|
+
}
|
|
15717
15651
|
}
|
|
15652
|
+
|
|
15718
15653
|
/**
|
|
15719
|
-
*
|
|
15720
|
-
* write the result into the `result` buffer.
|
|
15721
|
-
*
|
|
15722
|
-
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
15654
|
+
* @deprecated Use getU32 instead
|
|
15723
15655
|
*/
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
-
|
|
15727
|
-
}
|
|
15728
|
-
|
|
15729
|
-
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
15730
|
-
|
|
15731
|
-
if (pagesResult.isError) {
|
|
15732
|
-
return Result.error(pagesResult.error, pagesResult.details);
|
|
15733
|
-
}
|
|
15656
|
+
getUnsigned() {
|
|
15657
|
+
return this.u32[U32_INDEX];
|
|
15658
|
+
}
|
|
15734
15659
|
|
|
15735
|
-
|
|
15660
|
+
/**
|
|
15661
|
+
* @deprecated Use getI32 instead
|
|
15662
|
+
*/
|
|
15663
|
+
getSigned() {
|
|
15664
|
+
return this.i32[U32_INDEX];
|
|
15665
|
+
}
|
|
15736
15666
|
|
|
15737
|
-
|
|
15738
|
-
|
|
15667
|
+
getU32(): number {
|
|
15668
|
+
return this.u32[U32_INDEX];
|
|
15669
|
+
}
|
|
15739
15670
|
|
|
15740
|
-
|
|
15741
|
-
|
|
15742
|
-
|
|
15743
|
-
const destinationStartIndex = currentPosition - startAddress;
|
|
15744
|
-
const destination = result.subarray(destinationStartIndex);
|
|
15671
|
+
getI32(): number {
|
|
15672
|
+
return this.i32[U32_INDEX];
|
|
15673
|
+
}
|
|
15745
15674
|
|
|
15746
|
-
|
|
15675
|
+
getU64(): bigint {
|
|
15676
|
+
return this.u64[U64_INDEX];
|
|
15677
|
+
}
|
|
15747
15678
|
|
|
15748
|
-
|
|
15749
|
-
|
|
15750
|
-
|
|
15679
|
+
getI64(): bigint {
|
|
15680
|
+
return this.i64[U64_INDEX];
|
|
15681
|
+
}
|
|
15751
15682
|
|
|
15752
|
-
|
|
15753
|
-
return
|
|
15683
|
+
getBytesAsLittleEndian() {
|
|
15684
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE);
|
|
15754
15685
|
}
|
|
15755
15686
|
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15687
|
+
getExtendedBytesAsLittleEndian() {
|
|
15688
|
+
return this.bytes;
|
|
15689
|
+
}
|
|
15690
|
+
}
|
|
15759
15691
|
|
|
15760
|
-
|
|
15761
|
-
|
|
15762
|
-
throw new OutOfMemory();
|
|
15763
|
-
}
|
|
15692
|
+
declare class NibblesDecoder {
|
|
15693
|
+
private byte = new Int8Array(1);
|
|
15764
15694
|
|
|
15765
|
-
|
|
15695
|
+
setByte(byte: number) {
|
|
15696
|
+
this.byte[0] = byte;
|
|
15697
|
+
}
|
|
15766
15698
|
|
|
15767
|
-
|
|
15768
|
-
|
|
15769
|
-
|
|
15770
|
-
return currentVirtualSbrkIndex;
|
|
15771
|
-
}
|
|
15699
|
+
getHighNibble() {
|
|
15700
|
+
return (this.byte[0] & 0xf0) >>> 4;
|
|
15701
|
+
}
|
|
15772
15702
|
|
|
15773
|
-
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15777
|
-
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE;
|
|
15778
|
-
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
15703
|
+
getLowNibble() {
|
|
15704
|
+
return this.byte[0] & 0x0f;
|
|
15705
|
+
}
|
|
15779
15706
|
|
|
15780
|
-
|
|
15781
|
-
|
|
15782
|
-
|
|
15783
|
-
}
|
|
15707
|
+
getHighNibbleAsRegisterIndex() {
|
|
15708
|
+
return Math.min(this.getHighNibble(), MAX_REGISTER_INDEX);
|
|
15709
|
+
}
|
|
15784
15710
|
|
|
15785
|
-
|
|
15786
|
-
this.
|
|
15787
|
-
return currentVirtualSbrkIndex;
|
|
15711
|
+
getLowNibbleAsRegisterIndex() {
|
|
15712
|
+
return Math.min(this.getLowNibble(), MAX_REGISTER_INDEX);
|
|
15788
15713
|
}
|
|
15789
15714
|
|
|
15790
|
-
|
|
15791
|
-
|
|
15792
|
-
return page?.getPageDump() ?? null;
|
|
15715
|
+
getHighNibbleAsLength() {
|
|
15716
|
+
return Math.min(this.getHighNibble(), MAX_LENGTH);
|
|
15793
15717
|
}
|
|
15794
15718
|
|
|
15795
|
-
|
|
15796
|
-
return this.
|
|
15719
|
+
getLowNibbleAsLength() {
|
|
15720
|
+
return Math.min(this.getLowNibble(), MAX_LENGTH);
|
|
15797
15721
|
}
|
|
15798
15722
|
}
|
|
15799
15723
|
|
|
15800
|
-
|
|
15801
|
-
|
|
15802
|
-
|
|
15803
|
-
|
|
15804
|
-
private ensureNotFinalized() {
|
|
15805
|
-
if (this.isFinalized) {
|
|
15806
|
-
throw new FinalizedBuilderModification();
|
|
15807
|
-
}
|
|
15808
|
-
}
|
|
15724
|
+
type EmptyArgs = {
|
|
15725
|
+
type: ArgumentType.NO_ARGUMENTS;
|
|
15726
|
+
noOfBytesToSkip: number;
|
|
15727
|
+
};
|
|
15809
15728
|
|
|
15810
|
-
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15729
|
+
type OneImmediateArgs = {
|
|
15730
|
+
type: ArgumentType.ONE_IMMEDIATE;
|
|
15731
|
+
noOfBytesToSkip: number;
|
|
15732
|
+
/** V_X */
|
|
15733
|
+
immediateDecoder: ImmediateDecoder;
|
|
15734
|
+
};
|
|
15815
15735
|
|
|
15816
|
-
|
|
15817
|
-
|
|
15818
|
-
|
|
15819
|
-
|
|
15820
|
-
|
|
15821
|
-
|
|
15822
|
-
|
|
15823
|
-
|
|
15824
|
-
|
|
15825
|
-
|
|
15826
|
-
this.ensureNotFinalized();
|
|
15827
|
-
check`${start < end} end has to be bigger than start`;
|
|
15828
|
-
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15829
|
-
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15830
|
-
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15736
|
+
type ThreeRegistersArgs = {
|
|
15737
|
+
type: ArgumentType.THREE_REGISTERS;
|
|
15738
|
+
noOfBytesToSkip: number;
|
|
15739
|
+
/** W_A */
|
|
15740
|
+
firstRegisterIndex: number;
|
|
15741
|
+
/** W_B */
|
|
15742
|
+
secondRegisterIndex: number;
|
|
15743
|
+
/** W_D */
|
|
15744
|
+
thirdRegisterIndex: number;
|
|
15745
|
+
};
|
|
15831
15746
|
|
|
15832
|
-
|
|
15833
|
-
|
|
15747
|
+
type TwoRegistersArgs = {
|
|
15748
|
+
type: ArgumentType.TWO_REGISTERS;
|
|
15749
|
+
noOfBytesToSkip: number;
|
|
15750
|
+
/** W_A */
|
|
15751
|
+
firstRegisterIndex: number;
|
|
15752
|
+
/** W_D */
|
|
15753
|
+
secondRegisterIndex: number;
|
|
15754
|
+
};
|
|
15834
15755
|
|
|
15835
|
-
|
|
15756
|
+
type TwoRegistersOneImmediateArgs = {
|
|
15757
|
+
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15758
|
+
noOfBytesToSkip: number;
|
|
15759
|
+
/** W_A */
|
|
15760
|
+
firstRegisterIndex: number;
|
|
15761
|
+
/** W_B */
|
|
15762
|
+
secondRegisterIndex: number;
|
|
15763
|
+
/** V_X */
|
|
15764
|
+
immediateDecoder: ImmediateDecoder;
|
|
15765
|
+
};
|
|
15836
15766
|
|
|
15837
|
-
|
|
15838
|
-
|
|
15767
|
+
type OneRegisterOneImmediateArgs = {
|
|
15768
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15769
|
+
noOfBytesToSkip: number;
|
|
15770
|
+
/** W_A */
|
|
15771
|
+
registerIndex: number;
|
|
15772
|
+
/** V_X */
|
|
15773
|
+
immediateDecoder: ImmediateDecoder;
|
|
15774
|
+
};
|
|
15839
15775
|
|
|
15840
|
-
|
|
15841
|
-
|
|
15842
|
-
|
|
15843
|
-
|
|
15844
|
-
|
|
15845
|
-
|
|
15776
|
+
type OneRegisterOneExtendedWidthImmediateArgs = {
|
|
15777
|
+
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
15778
|
+
noOfBytesToSkip: number;
|
|
15779
|
+
/** W_A */
|
|
15780
|
+
registerIndex: number;
|
|
15781
|
+
/** V_X */
|
|
15782
|
+
immediateDecoder: ExtendedWitdthImmediateDecoder;
|
|
15783
|
+
};
|
|
15846
15784
|
|
|
15847
|
-
|
|
15848
|
-
|
|
15785
|
+
type TwoRegistersTwoImmediatesArgs = {
|
|
15786
|
+
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
15787
|
+
noOfBytesToSkip: number;
|
|
15788
|
+
/** W_A */
|
|
15789
|
+
firstRegisterIndex: number;
|
|
15790
|
+
/** W_B */
|
|
15791
|
+
secondRegisterIndex: number;
|
|
15792
|
+
/** V_X */
|
|
15793
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15794
|
+
/** V_Y */
|
|
15795
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15796
|
+
};
|
|
15849
15797
|
|
|
15850
|
-
|
|
15851
|
-
|
|
15852
|
-
|
|
15853
|
-
|
|
15854
|
-
|
|
15855
|
-
|
|
15856
|
-
|
|
15857
|
-
|
|
15858
|
-
*/
|
|
15859
|
-
setWriteablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15860
|
-
this.ensureNotFinalized();
|
|
15861
|
-
check`${start < end} end has to be bigger than start`;
|
|
15862
|
-
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15863
|
-
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15864
|
-
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15798
|
+
type TwoImmediatesArgs = {
|
|
15799
|
+
type: ArgumentType.TWO_IMMEDIATES;
|
|
15800
|
+
noOfBytesToSkip: number;
|
|
15801
|
+
/** V_X */
|
|
15802
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15803
|
+
/** V_Y */
|
|
15804
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15805
|
+
};
|
|
15865
15806
|
|
|
15866
|
-
|
|
15867
|
-
|
|
15807
|
+
type TwoRegistersOneOffsetArgs = {
|
|
15808
|
+
type: ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15809
|
+
noOfBytesToSkip: number;
|
|
15810
|
+
/** W_A */
|
|
15811
|
+
firstRegisterIndex: number;
|
|
15812
|
+
/** W_B */
|
|
15813
|
+
secondRegisterIndex: number;
|
|
15814
|
+
nextPc: number;
|
|
15815
|
+
};
|
|
15868
15816
|
|
|
15869
|
-
|
|
15817
|
+
type OneRegisterOneImmediateOneOffsetArgs = {
|
|
15818
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15819
|
+
noOfBytesToSkip: number;
|
|
15820
|
+
/** W_A */
|
|
15821
|
+
registerIndex: number;
|
|
15822
|
+
/** V_X */
|
|
15823
|
+
immediateDecoder: ImmediateDecoder;
|
|
15824
|
+
/** V_Y */
|
|
15825
|
+
nextPc: number;
|
|
15826
|
+
};
|
|
15870
15827
|
|
|
15871
|
-
|
|
15872
|
-
|
|
15828
|
+
type OneRegisterTwoImmediatesArgs = {
|
|
15829
|
+
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15830
|
+
noOfBytesToSkip: number;
|
|
15831
|
+
/** W_A */
|
|
15832
|
+
registerIndex: number;
|
|
15833
|
+
/** V_X */
|
|
15834
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15835
|
+
/** V_Y */
|
|
15836
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15837
|
+
};
|
|
15873
15838
|
|
|
15874
|
-
|
|
15875
|
-
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
|
|
15879
|
-
|
|
15839
|
+
type OneOffsetArgs = {
|
|
15840
|
+
type: ArgumentType.ONE_OFFSET;
|
|
15841
|
+
noOfBytesToSkip: number;
|
|
15842
|
+
/** V_X */
|
|
15843
|
+
nextPc: number;
|
|
15844
|
+
};
|
|
15880
15845
|
|
|
15881
|
-
|
|
15846
|
+
type Args =
|
|
15847
|
+
| EmptyArgs
|
|
15848
|
+
| OneImmediateArgs
|
|
15849
|
+
| TwoRegistersArgs
|
|
15850
|
+
| ThreeRegistersArgs
|
|
15851
|
+
| TwoRegistersOneImmediateArgs
|
|
15852
|
+
| TwoRegistersTwoImmediatesArgs
|
|
15853
|
+
| OneRegisterOneImmediateOneOffsetArgs
|
|
15854
|
+
| TwoRegistersOneOffsetArgs
|
|
15855
|
+
| OneRegisterOneImmediateArgs
|
|
15856
|
+
| OneOffsetArgs
|
|
15857
|
+
| TwoImmediatesArgs
|
|
15858
|
+
| OneRegisterTwoImmediatesArgs
|
|
15859
|
+
| OneRegisterOneExtendedWidthImmediateArgs;
|
|
15860
|
+
|
|
15861
|
+
declare class ArgsDecoder {
|
|
15862
|
+
private nibblesDecoder = new NibblesDecoder();
|
|
15863
|
+
private offsetDecoder = new ImmediateDecoder();
|
|
15864
|
+
private code: Uint8Array = new Uint8Array();
|
|
15865
|
+
private mask: Mask = Mask.empty();
|
|
15866
|
+
|
|
15867
|
+
reset(code: Uint8Array, mask: Mask) {
|
|
15868
|
+
this.code = code;
|
|
15869
|
+
this.mask = mask;
|
|
15882
15870
|
}
|
|
15883
15871
|
|
|
15884
|
-
|
|
15885
|
-
|
|
15886
|
-
|
|
15887
|
-
*/
|
|
15888
|
-
setData(start: MemoryIndex, data: Uint8Array) {
|
|
15889
|
-
this.ensureNotFinalized();
|
|
15890
|
-
const pageOffset = start % PAGE_SIZE;
|
|
15891
|
-
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15892
|
-
check`${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15872
|
+
fillArgs<T extends Args>(pc: number, result: T): void {
|
|
15873
|
+
const nextInstructionDistance = 1 + this.mask.getNoOfBytesToNextInstruction(pc + 1);
|
|
15874
|
+
result.noOfBytesToSkip = nextInstructionDistance;
|
|
15893
15875
|
|
|
15894
|
-
|
|
15895
|
-
|
|
15876
|
+
switch (result.type) {
|
|
15877
|
+
case ArgumentType.NO_ARGUMENTS:
|
|
15878
|
+
break;
|
|
15879
|
+
|
|
15880
|
+
case ArgumentType.ONE_IMMEDIATE: {
|
|
15881
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
15882
|
+
const argsStartIndex = pc + 1;
|
|
15883
|
+
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
15884
|
+
break;
|
|
15885
|
+
}
|
|
15886
|
+
|
|
15887
|
+
case ArgumentType.THREE_REGISTERS: {
|
|
15888
|
+
const firstByte = this.code[pc + 1];
|
|
15889
|
+
const secondByte = this.code[pc + 2];
|
|
15890
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15891
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15892
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15893
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
15894
|
+
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15895
|
+
break;
|
|
15896
|
+
}
|
|
15897
|
+
|
|
15898
|
+
case ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE: {
|
|
15899
|
+
const firstByte = this.code[pc + 1];
|
|
15900
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15901
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15902
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15903
|
+
|
|
15904
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15905
|
+
const immediateStartIndex = pc + 2;
|
|
15906
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15907
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
15908
|
+
break;
|
|
15909
|
+
}
|
|
15910
|
+
|
|
15911
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET: {
|
|
15912
|
+
const firstByte = this.code[pc + 1];
|
|
15913
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15914
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15915
|
+
|
|
15916
|
+
const immediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
15917
|
+
const immediateStartIndex = pc + 2;
|
|
15918
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15919
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
15920
|
+
|
|
15921
|
+
const offsetLength = Math.min(
|
|
15922
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
15923
|
+
Math.max(0, nextInstructionDistance - 2 - immediateLength),
|
|
15924
|
+
);
|
|
15925
|
+
const offsetStartIndex = pc + 2 + immediateLength;
|
|
15926
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15927
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15928
|
+
|
|
15929
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
15930
|
+
break;
|
|
15931
|
+
}
|
|
15932
|
+
|
|
15933
|
+
case ArgumentType.TWO_REGISTERS_ONE_OFFSET: {
|
|
15934
|
+
const firstByte = this.code[pc + 1];
|
|
15935
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15936
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15937
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15938
|
+
|
|
15939
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15940
|
+
const offsetStartIndex = pc + 2;
|
|
15941
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15942
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15943
|
+
|
|
15944
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
15945
|
+
break;
|
|
15946
|
+
}
|
|
15947
|
+
|
|
15948
|
+
case ArgumentType.TWO_REGISTERS: {
|
|
15949
|
+
const firstByte = this.code[pc + 1];
|
|
15950
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15951
|
+
result.firstRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15952
|
+
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15953
|
+
break;
|
|
15954
|
+
}
|
|
15955
|
+
|
|
15956
|
+
case ArgumentType.ONE_OFFSET: {
|
|
15957
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
15958
|
+
const offsetStartIndex = pc + 1;
|
|
15959
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15960
|
+
const offsetBytes = this.code.subarray(offsetStartIndex, offsetEndIndex);
|
|
15961
|
+
this.offsetDecoder.setBytes(offsetBytes);
|
|
15962
|
+
const offsetValue = this.offsetDecoder.getSigned();
|
|
15963
|
+
result.nextPc = pc + offsetValue;
|
|
15964
|
+
break;
|
|
15965
|
+
}
|
|
15966
|
+
|
|
15967
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE: {
|
|
15968
|
+
const firstByte = this.code[pc + 1];
|
|
15969
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15970
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15971
|
+
|
|
15972
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15973
|
+
const immediateStartIndex = pc + 2;
|
|
15974
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15975
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
15976
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
15977
|
+
break;
|
|
15978
|
+
}
|
|
15979
|
+
|
|
15980
|
+
case ArgumentType.TWO_IMMEDIATES: {
|
|
15981
|
+
const firstByte = this.code[pc + 1];
|
|
15982
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15983
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
15984
|
+
const firstImmediateStartIndex = pc + 2;
|
|
15985
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
15986
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
15987
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15988
|
+
|
|
15989
|
+
const secondImmediateLength = Math.min(
|
|
15990
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
15991
|
+
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
15992
|
+
);
|
|
15993
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
15994
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
15995
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
15996
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
15997
|
+
break;
|
|
15998
|
+
}
|
|
15999
|
+
|
|
16000
|
+
case ArgumentType.ONE_REGISTER_TWO_IMMEDIATES: {
|
|
16001
|
+
const firstByte = this.code[pc + 1];
|
|
16002
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
16003
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
16004
|
+
|
|
16005
|
+
const firstImmediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
16006
|
+
const firstImmediateStartIndex = pc + 2;
|
|
16007
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
16008
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
16009
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
16010
|
+
|
|
16011
|
+
const secondImmediateLength = Math.min(
|
|
16012
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
16013
|
+
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
16014
|
+
);
|
|
16015
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
16016
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
16017
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
16018
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
16019
|
+
break;
|
|
16020
|
+
}
|
|
16021
|
+
|
|
16022
|
+
case ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES: {
|
|
16023
|
+
const firstByte = this.code[pc + 1];
|
|
16024
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
16025
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
16026
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
16027
|
+
|
|
16028
|
+
const secondByte = this.code[pc + 2];
|
|
16029
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
16030
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
16031
|
+
const firstImmediateStartIndex = pc + 3;
|
|
16032
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
16033
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
16034
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
16035
|
+
|
|
16036
|
+
const secondImmediateLength = Math.min(
|
|
16037
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
16038
|
+
Math.max(0, nextInstructionDistance - 3 - firstImmediateLength),
|
|
16039
|
+
);
|
|
16040
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
16041
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
16042
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
16043
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
16044
|
+
break;
|
|
16045
|
+
}
|
|
16046
|
+
|
|
16047
|
+
case ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE: {
|
|
16048
|
+
const firstByte = this.code[pc + 1];
|
|
16049
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
16050
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
16051
|
+
|
|
16052
|
+
const immediateStartIndex = pc + 2;
|
|
16053
|
+
const immediateEndIndex = immediateStartIndex + 8;
|
|
16054
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
16055
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
16056
|
+
break;
|
|
16057
|
+
}
|
|
16058
|
+
}
|
|
16059
|
+
}
|
|
16060
|
+
}
|
|
16061
|
+
|
|
16062
|
+
declare const createResults = () => {
|
|
16063
|
+
const results = new Array(ARGUMENT_TYPE_LENGTH) as Results;
|
|
16064
|
+
|
|
16065
|
+
results[ArgumentType.NO_ARGUMENTS] = {
|
|
16066
|
+
type: ArgumentType.NO_ARGUMENTS,
|
|
16067
|
+
noOfBytesToSkip: 1,
|
|
16068
|
+
};
|
|
16069
|
+
|
|
16070
|
+
results[ArgumentType.ONE_IMMEDIATE] = {
|
|
16071
|
+
type: ArgumentType.ONE_IMMEDIATE,
|
|
16072
|
+
noOfBytesToSkip: 1,
|
|
16073
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16074
|
+
};
|
|
16075
|
+
|
|
16076
|
+
results[ArgumentType.TWO_REGISTERS] = {
|
|
16077
|
+
type: ArgumentType.TWO_REGISTERS,
|
|
16078
|
+
noOfBytesToSkip: 1,
|
|
16079
|
+
firstRegisterIndex: 0,
|
|
16080
|
+
secondRegisterIndex: 0,
|
|
16081
|
+
};
|
|
16082
|
+
|
|
16083
|
+
results[ArgumentType.THREE_REGISTERS] = {
|
|
16084
|
+
type: ArgumentType.THREE_REGISTERS,
|
|
16085
|
+
noOfBytesToSkip: 1,
|
|
16086
|
+
firstRegisterIndex: 0,
|
|
16087
|
+
secondRegisterIndex: 0,
|
|
16088
|
+
thirdRegisterIndex: 0,
|
|
16089
|
+
};
|
|
16090
|
+
|
|
16091
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET] = {
|
|
16092
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET,
|
|
16093
|
+
noOfBytesToSkip: 1,
|
|
16094
|
+
registerIndex: 0,
|
|
16095
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16096
|
+
nextPc: 0,
|
|
16097
|
+
};
|
|
16098
|
+
|
|
16099
|
+
results[ArgumentType.TWO_REGISTERS_ONE_OFFSET] = {
|
|
16100
|
+
type: ArgumentType.TWO_REGISTERS_ONE_OFFSET,
|
|
16101
|
+
noOfBytesToSkip: 1,
|
|
16102
|
+
firstRegisterIndex: 0,
|
|
16103
|
+
secondRegisterIndex: 0,
|
|
16104
|
+
nextPc: 0,
|
|
16105
|
+
};
|
|
16106
|
+
|
|
16107
|
+
results[ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE] = {
|
|
16108
|
+
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE,
|
|
16109
|
+
noOfBytesToSkip: 1,
|
|
16110
|
+
firstRegisterIndex: 0,
|
|
16111
|
+
secondRegisterIndex: 0,
|
|
16112
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16113
|
+
};
|
|
16114
|
+
|
|
16115
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE] = {
|
|
16116
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE,
|
|
16117
|
+
noOfBytesToSkip: 1,
|
|
16118
|
+
registerIndex: 0,
|
|
16119
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16120
|
+
};
|
|
16121
|
+
|
|
16122
|
+
results[ArgumentType.ONE_REGISTER_TWO_IMMEDIATES] = {
|
|
16123
|
+
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES,
|
|
16124
|
+
noOfBytesToSkip: 1,
|
|
16125
|
+
registerIndex: 0,
|
|
16126
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16127
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16128
|
+
};
|
|
16129
|
+
|
|
16130
|
+
results[ArgumentType.ONE_OFFSET] = {
|
|
16131
|
+
type: ArgumentType.ONE_OFFSET,
|
|
16132
|
+
noOfBytesToSkip: 1,
|
|
16133
|
+
nextPc: 0,
|
|
16134
|
+
};
|
|
16135
|
+
|
|
16136
|
+
results[ArgumentType.TWO_IMMEDIATES] = {
|
|
16137
|
+
type: ArgumentType.TWO_IMMEDIATES,
|
|
16138
|
+
noOfBytesToSkip: 1,
|
|
16139
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16140
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16141
|
+
};
|
|
16142
|
+
|
|
16143
|
+
results[ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES] = {
|
|
16144
|
+
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES,
|
|
16145
|
+
noOfBytesToSkip: 1,
|
|
16146
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16147
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16148
|
+
firstRegisterIndex: 0,
|
|
16149
|
+
secondRegisterIndex: 0,
|
|
16150
|
+
};
|
|
16151
|
+
|
|
16152
|
+
results[ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE] = {
|
|
16153
|
+
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE,
|
|
16154
|
+
noOfBytesToSkip: 9,
|
|
16155
|
+
registerIndex: 0,
|
|
16156
|
+
immediateDecoder: new ExtendedWitdthImmediateDecoder(),
|
|
16157
|
+
};
|
|
16158
|
+
|
|
16159
|
+
return results;
|
|
16160
|
+
};
|
|
16161
|
+
|
|
16162
|
+
declare enum Instruction {
|
|
16163
|
+
TRAP = 0,
|
|
16164
|
+
FALLTHROUGH = 1,
|
|
16165
|
+
ECALLI = 10,
|
|
16166
|
+
LOAD_IMM_64 = 20,
|
|
16167
|
+
STORE_IMM_U8 = 30,
|
|
16168
|
+
STORE_IMM_U16 = 31,
|
|
16169
|
+
STORE_IMM_U32 = 32,
|
|
16170
|
+
STORE_IMM_U64 = 33,
|
|
16171
|
+
JUMP = 40,
|
|
16172
|
+
JUMP_IND = 50,
|
|
16173
|
+
LOAD_IMM = 51,
|
|
16174
|
+
LOAD_U8 = 52,
|
|
16175
|
+
LOAD_I8 = 53,
|
|
16176
|
+
LOAD_U16 = 54,
|
|
16177
|
+
LOAD_I16 = 55,
|
|
16178
|
+
LOAD_U32 = 56,
|
|
16179
|
+
LOAD_I32 = 57,
|
|
16180
|
+
LOAD_U64 = 58,
|
|
16181
|
+
STORE_U8 = 59,
|
|
16182
|
+
STORE_U16 = 60,
|
|
16183
|
+
STORE_U32 = 61,
|
|
16184
|
+
STORE_U64 = 62,
|
|
16185
|
+
STORE_IMM_IND_U8 = 70,
|
|
16186
|
+
STORE_IMM_IND_U16 = 71,
|
|
16187
|
+
STORE_IMM_IND_U32 = 72,
|
|
16188
|
+
STORE_IMM_IND_U64 = 73,
|
|
16189
|
+
LOAD_IMM_JUMP = 80,
|
|
16190
|
+
BRANCH_EQ_IMM = 81,
|
|
16191
|
+
BRANCH_NE_IMM = 82,
|
|
16192
|
+
BRANCH_LT_U_IMM = 83,
|
|
16193
|
+
BRANCH_LE_U_IMM = 84,
|
|
16194
|
+
BRANCH_GE_U_IMM = 85,
|
|
16195
|
+
BRANCH_GT_U_IMM = 86,
|
|
16196
|
+
BRANCH_LT_S_IMM = 87,
|
|
16197
|
+
BRANCH_LE_S_IMM = 88,
|
|
16198
|
+
BRANCH_GE_S_IMM = 89,
|
|
16199
|
+
BRANCH_GT_S_IMM = 90,
|
|
16200
|
+
MOVE_REG = 100,
|
|
16201
|
+
SBRK = 101,
|
|
16202
|
+
COUNT_SET_BITS_64 = 102,
|
|
16203
|
+
COUNT_SET_BITS_32 = 103,
|
|
16204
|
+
LEADING_ZERO_BITS_64 = 104,
|
|
16205
|
+
LEADING_ZERO_BITS_32 = 105,
|
|
16206
|
+
TRAILING_ZERO_BITS_64 = 106,
|
|
16207
|
+
TRAILING_ZERO_BITS_32 = 107,
|
|
16208
|
+
SIGN_EXTEND_8 = 108,
|
|
16209
|
+
SIGN_EXTEND_16 = 109,
|
|
16210
|
+
ZERO_EXTEND_16 = 110,
|
|
16211
|
+
REVERSE_BYTES = 111,
|
|
16212
|
+
STORE_IND_U8 = 120,
|
|
16213
|
+
STORE_IND_U16 = 121,
|
|
16214
|
+
STORE_IND_U32 = 122,
|
|
16215
|
+
STORE_IND_U64 = 123,
|
|
16216
|
+
LOAD_IND_U8 = 124,
|
|
16217
|
+
LOAD_IND_I8 = 125,
|
|
16218
|
+
LOAD_IND_U16 = 126,
|
|
16219
|
+
LOAD_IND_I16 = 127,
|
|
16220
|
+
LOAD_IND_U32 = 128,
|
|
16221
|
+
LOAD_IND_I32 = 129,
|
|
16222
|
+
LOAD_IND_U64 = 130,
|
|
16223
|
+
ADD_IMM_32 = 131,
|
|
16224
|
+
AND_IMM = 132,
|
|
16225
|
+
XOR_IMM = 133,
|
|
16226
|
+
OR_IMM = 134,
|
|
16227
|
+
MUL_IMM_32 = 135,
|
|
16228
|
+
SET_LT_U_IMM = 136,
|
|
16229
|
+
SET_LT_S_IMM = 137,
|
|
16230
|
+
SHLO_L_IMM_32 = 138,
|
|
16231
|
+
SHLO_R_IMM_32 = 139,
|
|
16232
|
+
SHAR_R_IMM_32 = 140,
|
|
16233
|
+
NEG_ADD_IMM_32 = 141,
|
|
16234
|
+
SET_GT_U_IMM = 142,
|
|
16235
|
+
SET_GT_S_IMM = 143,
|
|
16236
|
+
SHLO_L_IMM_ALT_32 = 144,
|
|
16237
|
+
SHLO_R_IMM_ALT_32 = 145,
|
|
16238
|
+
SHAR_R_IMM_ALT_32 = 146,
|
|
16239
|
+
CMOV_IZ_IMM = 147,
|
|
16240
|
+
CMOV_NZ_IMM = 148,
|
|
16241
|
+
ADD_IMM_64 = 149,
|
|
16242
|
+
MUL_IMM_64 = 150,
|
|
16243
|
+
SHLO_L_IMM_64 = 151,
|
|
16244
|
+
SHLO_R_IMM_64 = 152,
|
|
16245
|
+
SHAR_R_IMM_64 = 153,
|
|
16246
|
+
NEG_ADD_IMM_64 = 154,
|
|
16247
|
+
SHLO_L_IMM_ALT_64 = 155,
|
|
16248
|
+
SHLO_R_IMM_ALT_64 = 156,
|
|
16249
|
+
SHAR_R_IMM_ALT_64 = 157,
|
|
16250
|
+
ROT_R_64_IMM = 158,
|
|
16251
|
+
ROT_R_64_IMM_ALT = 159,
|
|
16252
|
+
ROT_R_32_IMM = 160,
|
|
16253
|
+
ROT_R_32_IMM_ALT = 161,
|
|
16254
|
+
BRANCH_EQ = 170,
|
|
16255
|
+
BRANCH_NE = 171,
|
|
16256
|
+
BRANCH_LT_U = 172,
|
|
16257
|
+
BRANCH_LT_S = 173,
|
|
16258
|
+
BRANCH_GE_U = 174,
|
|
16259
|
+
BRANCH_GE_S = 175,
|
|
16260
|
+
LOAD_IMM_JUMP_IND = 180,
|
|
16261
|
+
ADD_32 = 190,
|
|
16262
|
+
SUB_32 = 191,
|
|
16263
|
+
MUL_32 = 192,
|
|
16264
|
+
DIV_U_32 = 193,
|
|
16265
|
+
DIV_S_32 = 194,
|
|
16266
|
+
REM_U_32 = 195,
|
|
16267
|
+
REM_S_32 = 196,
|
|
16268
|
+
SHLO_L_32 = 197,
|
|
16269
|
+
SHLO_R_32 = 198,
|
|
16270
|
+
SHAR_R_32 = 199,
|
|
16271
|
+
ADD_64 = 200,
|
|
16272
|
+
SUB_64 = 201,
|
|
16273
|
+
MUL_64 = 202,
|
|
16274
|
+
DIV_U_64 = 203,
|
|
16275
|
+
DIV_S_64 = 204,
|
|
16276
|
+
REM_U_64 = 205,
|
|
16277
|
+
REM_S_64 = 206,
|
|
16278
|
+
SHLO_L_64 = 207,
|
|
16279
|
+
SHLO_R_64 = 208,
|
|
16280
|
+
SHAR_R_64 = 209,
|
|
16281
|
+
AND = 210,
|
|
16282
|
+
XOR = 211,
|
|
16283
|
+
OR = 212,
|
|
16284
|
+
MUL_UPPER_S_S = 213,
|
|
16285
|
+
MUL_UPPER_U_U = 214,
|
|
16286
|
+
MUL_UPPER_S_U = 215,
|
|
16287
|
+
SET_LT_U = 216,
|
|
16288
|
+
SET_LT_S = 217,
|
|
16289
|
+
CMOV_IZ = 218,
|
|
16290
|
+
CMOV_NZ = 219,
|
|
16291
|
+
ROT_L_64 = 220,
|
|
16292
|
+
ROT_L_32 = 221,
|
|
16293
|
+
ROT_R_64 = 222,
|
|
16294
|
+
ROT_R_32 = 223,
|
|
16295
|
+
AND_INV = 224,
|
|
16296
|
+
OR_INV = 225,
|
|
16297
|
+
XNOR = 226,
|
|
16298
|
+
MAX = 227,
|
|
16299
|
+
MAX_U = 228,
|
|
16300
|
+
MIN = 229,
|
|
16301
|
+
MIN_U = 230,
|
|
16302
|
+
}
|
|
16303
|
+
|
|
16304
|
+
declare const instructionArgumentTypeMap = (() => {
|
|
16305
|
+
const instructionArgumentTypeMap = new Array<ArgumentType>(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
16306
|
+
|
|
16307
|
+
instructionArgumentTypeMap[Instruction.TRAP] = ArgumentType.NO_ARGUMENTS;
|
|
16308
|
+
instructionArgumentTypeMap[Instruction.FALLTHROUGH] = ArgumentType.NO_ARGUMENTS;
|
|
16309
|
+
|
|
16310
|
+
instructionArgumentTypeMap[Instruction.ECALLI] = ArgumentType.ONE_IMMEDIATE;
|
|
16311
|
+
|
|
16312
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_64] = ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
16313
|
+
|
|
16314
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U8] = ArgumentType.TWO_IMMEDIATES;
|
|
16315
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U16] = ArgumentType.TWO_IMMEDIATES;
|
|
16316
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U32] = ArgumentType.TWO_IMMEDIATES;
|
|
16317
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U64] = ArgumentType.TWO_IMMEDIATES;
|
|
16318
|
+
|
|
16319
|
+
instructionArgumentTypeMap[Instruction.JUMP] = ArgumentType.ONE_OFFSET;
|
|
16320
|
+
|
|
16321
|
+
instructionArgumentTypeMap[Instruction.JUMP_IND] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16322
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16323
|
+
instructionArgumentTypeMap[Instruction.LOAD_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16324
|
+
instructionArgumentTypeMap[Instruction.LOAD_I8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16325
|
+
instructionArgumentTypeMap[Instruction.LOAD_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16326
|
+
instructionArgumentTypeMap[Instruction.LOAD_I16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16327
|
+
instructionArgumentTypeMap[Instruction.LOAD_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16328
|
+
instructionArgumentTypeMap[Instruction.LOAD_I32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16329
|
+
instructionArgumentTypeMap[Instruction.LOAD_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16330
|
+
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16331
|
+
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16332
|
+
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16333
|
+
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16334
|
+
|
|
16335
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U8] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16336
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U16] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16337
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16338
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16339
|
+
|
|
16340
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16341
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16342
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16343
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16344
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16345
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16346
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16347
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16348
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16349
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16350
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16351
|
+
|
|
16352
|
+
instructionArgumentTypeMap[Instruction.MOVE_REG] = ArgumentType.TWO_REGISTERS;
|
|
16353
|
+
instructionArgumentTypeMap[Instruction.SBRK] = ArgumentType.TWO_REGISTERS;
|
|
16354
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16355
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16356
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16357
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16358
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16359
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16360
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_8] = ArgumentType.TWO_REGISTERS;
|
|
16361
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
16362
|
+
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
16363
|
+
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
16364
|
+
|
|
16365
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16366
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16367
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16368
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16369
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16370
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16371
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16372
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16373
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16374
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16375
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16376
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16377
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16378
|
+
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16379
|
+
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16380
|
+
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16381
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16382
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16383
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16384
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16385
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16386
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16387
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16388
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16389
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16390
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16391
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16392
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16393
|
+
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16394
|
+
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16395
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16396
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16397
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16398
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16399
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16400
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16401
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16402
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16403
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16404
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16405
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16406
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15896
16407
|
|
|
15897
|
-
|
|
16408
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16409
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16410
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16411
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16412
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16413
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15898
16414
|
|
|
15899
|
-
|
|
15900
|
-
const page = this.initialMemory.get(pageNumber);
|
|
16415
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP_IND] = ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
15901
16416
|
|
|
15902
|
-
|
|
15903
|
-
|
|
15904
|
-
|
|
16417
|
+
instructionArgumentTypeMap[Instruction.ADD_32] = ArgumentType.THREE_REGISTERS;
|
|
16418
|
+
instructionArgumentTypeMap[Instruction.ADD_64] = ArgumentType.THREE_REGISTERS;
|
|
16419
|
+
instructionArgumentTypeMap[Instruction.SUB_32] = ArgumentType.THREE_REGISTERS;
|
|
16420
|
+
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
16421
|
+
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
16422
|
+
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
16423
|
+
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
16424
|
+
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
16425
|
+
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
16426
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
16427
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
16428
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
16429
|
+
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
16430
|
+
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
16431
|
+
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
16432
|
+
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
16433
|
+
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
16434
|
+
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
16435
|
+
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
16436
|
+
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
16437
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
16438
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
16439
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
16440
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16441
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16442
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
16443
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16444
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16445
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
16446
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
16447
|
+
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
16448
|
+
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
16449
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16450
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16451
|
+
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
16452
|
+
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
16453
|
+
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
16454
|
+
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
16455
|
+
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
16456
|
+
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
16457
|
+
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
15905
16458
|
|
|
15906
|
-
|
|
15907
|
-
|
|
16459
|
+
return instructionArgumentTypeMap;
|
|
16460
|
+
})();
|
|
15908
16461
|
|
|
15909
|
-
|
|
15910
|
-
|
|
16462
|
+
declare class BasicBlocks {
|
|
16463
|
+
private basicBlocks: Set<number> = new Set();
|
|
15911
16464
|
|
|
15912
|
-
|
|
15913
|
-
|
|
15914
|
-
|
|
15915
|
-
|
|
15916
|
-
`;
|
|
15917
|
-
this.ensureNotFinalized();
|
|
16465
|
+
reset(code: Uint8Array, mask: Mask) {
|
|
16466
|
+
this.basicBlocks.clear();
|
|
16467
|
+
this.basicBlocks.add(0);
|
|
16468
|
+
const codeLength = code.length;
|
|
15918
16469
|
|
|
15919
|
-
const
|
|
15920
|
-
|
|
15921
|
-
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
16470
|
+
const isBasicBlockTermination = (index: number) =>
|
|
16471
|
+
mask.isInstruction(index) && terminationInstructions[code[index]];
|
|
15922
16472
|
|
|
15923
|
-
for (
|
|
15924
|
-
if (
|
|
15925
|
-
|
|
16473
|
+
for (let i = 0; i < codeLength; i++) {
|
|
16474
|
+
if (mask.isInstruction(i) && isBasicBlockTermination(i)) {
|
|
16475
|
+
this.basicBlocks.add(i + 1 + mask.getNoOfBytesToNextInstruction(i + 1));
|
|
15926
16476
|
}
|
|
15927
16477
|
}
|
|
16478
|
+
}
|
|
15928
16479
|
|
|
15929
|
-
|
|
15930
|
-
|
|
15931
|
-
|
|
15932
|
-
|
|
15933
|
-
});
|
|
16480
|
+
isBeginningOfBasicBlock(index: number) {
|
|
16481
|
+
return this.basicBlocks.has(index);
|
|
16482
|
+
}
|
|
16483
|
+
}
|
|
15934
16484
|
|
|
15935
|
-
|
|
15936
|
-
|
|
16485
|
+
declare enum Result {
|
|
16486
|
+
HALT = 0,
|
|
16487
|
+
PANIC = 1,
|
|
16488
|
+
FAULT_ACCESS = 2,
|
|
16489
|
+
FAULT = 3,
|
|
16490
|
+
HOST = 4,
|
|
16491
|
+
}
|
|
16492
|
+
|
|
16493
|
+
declare class InstructionResult {
|
|
16494
|
+
public nextPc = 0;
|
|
16495
|
+
public status: Result | null = null;
|
|
16496
|
+
/**
|
|
16497
|
+
* A numeric exit parameter of the PVM.
|
|
16498
|
+
*
|
|
16499
|
+
* In case of a `status === Result.FAULT` this will be the memory address
|
|
16500
|
+
* that triggered the fault.
|
|
16501
|
+
* In case of a `status === Result.HOST` this will be the host call index
|
|
16502
|
+
* that should be invoked.
|
|
16503
|
+
*
|
|
16504
|
+
* In any other circumstance the value should be `null`.
|
|
16505
|
+
*/
|
|
16506
|
+
public exitParam: number | null = null;
|
|
16507
|
+
|
|
16508
|
+
reset() {
|
|
16509
|
+
this.nextPc = 0;
|
|
16510
|
+
this.status = null;
|
|
16511
|
+
this.exitParam = null;
|
|
15937
16512
|
}
|
|
15938
16513
|
}
|
|
15939
16514
|
|
|
@@ -16918,7 +17493,7 @@ declare class StoreOps {
|
|
|
16918
17493
|
this.instructionResult.status = Result.FAULT_ACCESS;
|
|
16919
17494
|
} else {
|
|
16920
17495
|
this.instructionResult.status = Result.FAULT;
|
|
16921
|
-
this.instructionResult.exitParam = getStartPageIndex(storeResult.error.address);
|
|
17496
|
+
this.instructionResult.exitParam = getStartPageIndex(tryAsMemoryIndex(storeResult.error.address));
|
|
16922
17497
|
}
|
|
16923
17498
|
}
|
|
16924
17499
|
}
|
|
@@ -17719,34 +18294,20 @@ declare class ProgramDecoder {
|
|
|
17719
18294
|
}
|
|
17720
18295
|
}
|
|
17721
18296
|
|
|
17722
|
-
/**
|
|
17723
|
-
* Inner status codes for the PVM
|
|
17724
|
-
*
|
|
17725
|
-
* https://graypaper.fluffylabs.dev/#/85129da/2cae022cae02?v=0.6.3
|
|
17726
|
-
*/
|
|
17727
|
-
declare enum Status {
|
|
17728
|
-
OK = 255,
|
|
17729
|
-
HALT = 0,
|
|
17730
|
-
PANIC = 1,
|
|
17731
|
-
FAULT = 2,
|
|
17732
|
-
HOST = 3,
|
|
17733
|
-
OOG = 4,
|
|
17734
|
-
}
|
|
17735
|
-
|
|
17736
18297
|
type InterpreterOptions = {
|
|
17737
18298
|
useSbrkGas?: boolean;
|
|
17738
18299
|
};
|
|
17739
18300
|
|
|
17740
18301
|
declare const logger = Logger.new(import.meta.filename, "pvm");
|
|
17741
18302
|
|
|
17742
|
-
declare class Interpreter {
|
|
18303
|
+
declare class Interpreter implements IPvmInterpreter {
|
|
17743
18304
|
private readonly useSbrkGas: boolean;
|
|
17744
|
-
|
|
18305
|
+
readonly registers = new Registers();
|
|
18306
|
+
readonly memory = new Memory();
|
|
18307
|
+
gas = gasCounter(tryAsGas(0));
|
|
17745
18308
|
private code: Uint8Array = new Uint8Array();
|
|
17746
18309
|
private mask = Mask.empty();
|
|
17747
18310
|
private pc = 0;
|
|
17748
|
-
private gas = gasCounter(tryAsGas(0));
|
|
17749
|
-
private initialGas = gasCounter(tryAsGas(0));
|
|
17750
18311
|
private argsDecoder: ArgsDecoder;
|
|
17751
18312
|
private threeRegsDispatcher: ThreeRegsDispatcher;
|
|
17752
18313
|
private twoRegsOneImmDispatcher: TwoRegsOneImmDispatcher;
|
|
@@ -17756,7 +18317,6 @@ declare class Interpreter {
|
|
|
17756
18317
|
private oneOffsetDispatcher: OneOffsetDispatcher;
|
|
17757
18318
|
private oneRegOneImmDispatcher: OneRegOneImmDispatcher;
|
|
17758
18319
|
private instructionResult = new InstructionResult();
|
|
17759
|
-
private memory = new Memory();
|
|
17760
18320
|
private twoImmsDispatcher: TwoImmsDispatcher;
|
|
17761
18321
|
private oneRegTwoImmsDispatcher: OneRegTwoImmsDispatcher;
|
|
17762
18322
|
private noArgsDispatcher: NoArgsDispatcher;
|
|
@@ -17810,7 +18370,12 @@ declare class Interpreter {
|
|
|
17810
18370
|
this.oneRegOneExtImmDispatcher = new OneRegOneExtImmDispatcher(loadOps);
|
|
17811
18371
|
}
|
|
17812
18372
|
|
|
17813
|
-
|
|
18373
|
+
resetJam(program: Uint8Array, args: Uint8Array, pc: number, gas: Gas) {
|
|
18374
|
+
const p = Program.fromSpi(program, args, true);
|
|
18375
|
+
this.resetGeneric(p.code, pc, gas, p.registers, p.memory);
|
|
18376
|
+
}
|
|
18377
|
+
|
|
18378
|
+
resetGeneric(rawProgram: Uint8Array, pc: number, gas: Gas, maybeRegisters?: Registers, maybeMemory?: Memory) {
|
|
17814
18379
|
const programDecoder = new ProgramDecoder(rawProgram);
|
|
17815
18380
|
this.code = programDecoder.getCode();
|
|
17816
18381
|
this.mask = programDecoder.getMask();
|
|
@@ -17818,7 +18383,6 @@ declare class Interpreter {
|
|
|
17818
18383
|
|
|
17819
18384
|
this.pc = pc;
|
|
17820
18385
|
this.gas = gasCounter(gas);
|
|
17821
|
-
this.initialGas = gasCounter(gas);
|
|
17822
18386
|
this.status = Status.OK;
|
|
17823
18387
|
this.argsDecoder.reset(this.code, this.mask);
|
|
17824
18388
|
this.basicBlocks.reset(this.code, this.mask);
|
|
@@ -17960,10 +18524,6 @@ declare class Interpreter {
|
|
|
17960
18524
|
return this.status;
|
|
17961
18525
|
}
|
|
17962
18526
|
|
|
17963
|
-
getRegisters() {
|
|
17964
|
-
return this.registers;
|
|
17965
|
-
}
|
|
17966
|
-
|
|
17967
18527
|
getPC() {
|
|
17968
18528
|
return this.pc;
|
|
17969
18529
|
}
|
|
@@ -17972,24 +18532,6 @@ declare class Interpreter {
|
|
|
17972
18532
|
this.pc = nextPc;
|
|
17973
18533
|
}
|
|
17974
18534
|
|
|
17975
|
-
getGas(): Gas {
|
|
17976
|
-
return this.gas.get();
|
|
17977
|
-
}
|
|
17978
|
-
|
|
17979
|
-
getGasConsumed(): Gas {
|
|
17980
|
-
const gasConsumed = tryAsBigGas(this.initialGas.get()) - tryAsBigGas(this.gas.get());
|
|
17981
|
-
|
|
17982
|
-
if (gasConsumed < 0) {
|
|
17983
|
-
return this.initialGas.get();
|
|
17984
|
-
}
|
|
17985
|
-
|
|
17986
|
-
return tryAsBigGas(gasConsumed);
|
|
17987
|
-
}
|
|
17988
|
-
|
|
17989
|
-
getGasCounter(): GasCounter {
|
|
17990
|
-
return this.gas;
|
|
17991
|
-
}
|
|
17992
|
-
|
|
17993
18535
|
getStatus() {
|
|
17994
18536
|
return this.status;
|
|
17995
18537
|
}
|
|
@@ -17997,233 +18539,84 @@ declare class Interpreter {
|
|
|
17997
18539
|
getExitParam(): null | U32 {
|
|
17998
18540
|
const p = this.instructionResult.exitParam;
|
|
17999
18541
|
return p !== null ? tryAsU32(p) : p;
|
|
18000
|
-
}
|
|
18001
|
-
|
|
18002
|
-
getMemory() {
|
|
18003
|
-
return this.memory;
|
|
18004
|
-
}
|
|
18005
|
-
|
|
18006
|
-
getMemoryPage(pageNumber: number): null | Uint8Array {
|
|
18007
|
-
return this.memory.getPageDump(tryAsPageNumber(pageNumber));
|
|
18008
|
-
}
|
|
18009
|
-
|
|
18010
|
-
calculateBlockGasCost(): Map<string, number> {
|
|
18011
|
-
const codeLength = this.code.length;
|
|
18012
|
-
const blocks: Map<string, number> = new Map();
|
|
18013
|
-
let currentBlock = "0";
|
|
18014
|
-
let gasCost = 0;
|
|
18015
|
-
const getNextIstructionIndex = (index: number) => index + 1 + this.mask.getNoOfBytesToNextInstruction(index + 1);
|
|
18016
|
-
|
|
18017
|
-
for (let index = 0; index < codeLength; index = getNextIstructionIndex(index)) {
|
|
18018
|
-
const instruction = this.code[index];
|
|
18019
|
-
if (this.basicBlocks.isBeginningOfBasicBlock(index)) {
|
|
18020
|
-
blocks.set(currentBlock, gasCost);
|
|
18021
|
-
currentBlock = index.toString();
|
|
18022
|
-
gasCost = 0;
|
|
18023
|
-
}
|
|
18024
|
-
|
|
18025
|
-
gasCost += instructionGasMap[instruction];
|
|
18026
|
-
}
|
|
18027
|
-
|
|
18028
|
-
blocks.set(currentBlock, gasCost);
|
|
18029
|
-
|
|
18030
|
-
return blocks;
|
|
18031
|
-
}
|
|
18032
|
-
}
|
|
18033
|
-
|
|
18034
|
-
type index$8_BigGas = BigGas;
|
|
18035
|
-
type index$8_Gas = Gas;
|
|
18036
|
-
type index$8_GasCounter = GasCounter;
|
|
18037
|
-
type index$8_Interpreter = Interpreter;
|
|
18038
|
-
declare const index$8_Interpreter: typeof Interpreter;
|
|
18039
|
-
type index$8_InterpreterOptions = InterpreterOptions;
|
|
18040
|
-
type index$8_Memory = Memory;
|
|
18041
|
-
declare const index$8_Memory: typeof Memory;
|
|
18042
|
-
type index$8_MemoryBuilder = MemoryBuilder;
|
|
18043
|
-
declare const index$8_MemoryBuilder: typeof MemoryBuilder;
|
|
18044
|
-
type index$8_MemoryIndex = MemoryIndex;
|
|
18045
|
-
type index$8_Registers = Registers;
|
|
18046
|
-
declare const index$8_Registers: typeof Registers;
|
|
18047
|
-
type index$8_SbrkIndex = SbrkIndex;
|
|
18048
|
-
type index$8_SmallGas = SmallGas;
|
|
18049
|
-
declare const index$8_gasCounter: typeof gasCounter;
|
|
18050
|
-
declare const index$8_logger: typeof logger;
|
|
18051
|
-
declare const index$8_tryAsBigGas: typeof tryAsBigGas;
|
|
18052
|
-
declare const index$8_tryAsGas: typeof tryAsGas;
|
|
18053
|
-
declare const index$8_tryAsMemoryIndex: typeof tryAsMemoryIndex;
|
|
18054
|
-
declare const index$8_tryAsSbrkIndex: typeof tryAsSbrkIndex;
|
|
18055
|
-
declare const index$8_tryAsSmallGas: typeof tryAsSmallGas;
|
|
18056
|
-
declare namespace index$8 {
|
|
18057
|
-
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 };
|
|
18058
|
-
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 };
|
|
18059
|
-
}
|
|
18060
|
-
|
|
18061
|
-
interface IHostCallMemory {
|
|
18062
|
-
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds>;
|
|
18063
|
-
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds>;
|
|
18064
|
-
}
|
|
18065
|
-
|
|
18066
|
-
declare class HostCallMemory implements IHostCallMemory {
|
|
18067
|
-
constructor(private readonly memory: Memory) {}
|
|
18068
|
-
|
|
18069
|
-
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds> {
|
|
18070
|
-
if (bytes.length === 0) {
|
|
18071
|
-
return Result.ok(OK);
|
|
18072
|
-
}
|
|
18073
|
-
|
|
18074
|
-
if (address + tryAsU64(bytes.length) > MEMORY_SIZE) {
|
|
18075
|
-
return Result.error(
|
|
18076
|
-
new OutOfBounds(),
|
|
18077
|
-
() => `Memory access out of bounds: address ${address} + length ${bytes.length} exceeds memory size`,
|
|
18078
|
-
);
|
|
18079
|
-
}
|
|
18080
|
-
|
|
18081
|
-
return this.memory.storeFrom(tryAsMemoryIndex(Number(address)), bytes);
|
|
18082
|
-
}
|
|
18083
|
-
|
|
18084
|
-
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds> {
|
|
18085
|
-
if (result.length === 0) {
|
|
18086
|
-
return Result.ok(OK);
|
|
18087
|
-
}
|
|
18088
|
-
|
|
18089
|
-
if (startAddress + tryAsU64(result.length) > MEMORY_SIZE) {
|
|
18090
|
-
return Result.error(
|
|
18091
|
-
new OutOfBounds(),
|
|
18092
|
-
() => `Memory access out of bounds: address ${startAddress} + length ${result.length} exceeds memory size`,
|
|
18093
|
-
);
|
|
18094
|
-
}
|
|
18095
|
-
|
|
18096
|
-
return this.memory.loadInto(result, tryAsMemoryIndex(Number(startAddress)));
|
|
18097
|
-
}
|
|
18098
|
-
}
|
|
18099
|
-
|
|
18100
|
-
interface IHostCallRegisters {
|
|
18101
|
-
get(registerIndex: number): U64;
|
|
18102
|
-
set(registerIndex: number, value: U64): void;
|
|
18103
|
-
}
|
|
18104
|
-
|
|
18105
|
-
declare class HostCallRegisters implements IHostCallRegisters {
|
|
18106
|
-
constructor(private readonly registers: Registers) {}
|
|
18107
|
-
|
|
18108
|
-
get(registerIndex: number): U64 {
|
|
18109
|
-
return tryAsU64(this.registers.getU64(registerIndex));
|
|
18110
|
-
}
|
|
18111
|
-
|
|
18112
|
-
set(registerIndex: number, value: U64) {
|
|
18113
|
-
this.registers.setU64(registerIndex, value);
|
|
18114
|
-
}
|
|
18115
|
-
}
|
|
18116
|
-
|
|
18117
|
-
/** Strictly-typed host call index. */
|
|
18118
|
-
type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
18119
|
-
/** Attempt to convert a number into `HostCallIndex`. */
|
|
18120
|
-
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
18121
|
-
|
|
18122
|
-
/**
|
|
18123
|
-
* Host-call exit reason.
|
|
18124
|
-
*
|
|
18125
|
-
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
18126
|
-
*/
|
|
18127
|
-
declare enum PvmExecution {
|
|
18128
|
-
Halt = 0,
|
|
18129
|
-
Panic = 1,
|
|
18130
|
-
OOG = 2, // out-of-gas
|
|
18131
|
-
}
|
|
18132
|
-
|
|
18133
|
-
/** A utility function to easily trace a bunch of registers. */
|
|
18134
|
-
declare function traceRegisters(...regs: number[]) {
|
|
18135
|
-
return regs.map(tryAsRegisterIndex);
|
|
18136
|
-
}
|
|
18137
|
-
|
|
18138
|
-
/** An interface for a host call implementation */
|
|
18139
|
-
interface HostCallHandler {
|
|
18140
|
-
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
18141
|
-
readonly index: HostCallIndex;
|
|
18142
|
-
|
|
18143
|
-
/**
|
|
18144
|
-
* The gas cost of invocation of that host call.
|
|
18145
|
-
*
|
|
18146
|
-
* NOTE: `((reg: IHostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
18147
|
-
*/
|
|
18148
|
-
readonly basicGasCost: SmallGas | ((reg: IHostCallRegisters) => Gas);
|
|
18149
|
-
|
|
18150
|
-
/** Currently executing service id. */
|
|
18151
|
-
readonly currentServiceId: U32;
|
|
18152
|
-
|
|
18153
|
-
/** Input&Output registers that we should add to tracing log. */
|
|
18154
|
-
readonly tracedRegisters: RegisterIndex[];
|
|
18542
|
+
}
|
|
18155
18543
|
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
* NOTE the call is ALLOWED and expected to modify registers and memory.
|
|
18160
|
-
*/
|
|
18161
|
-
execute(gas: GasCounter, regs: IHostCallRegisters, memory: IHostCallMemory): Promise<undefined | PvmExecution>;
|
|
18162
|
-
}
|
|
18544
|
+
getMemoryPage(pageNumber: number): null | Uint8Array {
|
|
18545
|
+
return this.memory.getPageDump(tryAsPageNumber(pageNumber));
|
|
18546
|
+
}
|
|
18163
18547
|
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18548
|
+
calculateBlockGasCost(): Map<string, number> {
|
|
18549
|
+
const codeLength = this.code.length;
|
|
18550
|
+
const blocks: Map<string, number> = new Map();
|
|
18551
|
+
let currentBlock = "0";
|
|
18552
|
+
let gasCost = 0;
|
|
18553
|
+
const getNextIstructionIndex = (index: number) => index + 1 + this.mask.getNoOfBytesToNextInstruction(index + 1);
|
|
18168
18554
|
|
|
18169
|
-
|
|
18170
|
-
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
this.missing = missing;
|
|
18555
|
+
for (let index = 0; index < codeLength; index = getNextIstructionIndex(index)) {
|
|
18556
|
+
const instruction = this.code[index];
|
|
18557
|
+
if (this.basicBlocks.isBeginningOfBasicBlock(index)) {
|
|
18558
|
+
blocks.set(currentBlock, gasCost);
|
|
18559
|
+
currentBlock = index.toString();
|
|
18560
|
+
gasCost = 0;
|
|
18561
|
+
}
|
|
18177
18562
|
|
|
18178
|
-
|
|
18179
|
-
check`${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
18180
|
-
this.hostCalls.set(handler.index, handler);
|
|
18563
|
+
gasCost += instructionGasMap[instruction];
|
|
18181
18564
|
}
|
|
18182
|
-
}
|
|
18183
18565
|
|
|
18184
|
-
|
|
18185
|
-
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
18186
|
-
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
18187
|
-
}
|
|
18566
|
+
blocks.set(currentBlock, gasCost);
|
|
18188
18567
|
|
|
18189
|
-
|
|
18190
|
-
context: string,
|
|
18191
|
-
hostCallIndex: HostCallIndex,
|
|
18192
|
-
hostCallHandler: HostCallHandler,
|
|
18193
|
-
registers: IHostCallRegisters,
|
|
18194
|
-
gas: Gas,
|
|
18195
|
-
) {
|
|
18196
|
-
const { currentServiceId } = hostCallHandler;
|
|
18197
|
-
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
18198
|
-
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
18199
|
-
const registerValues = hostCallHandler.tracedRegisters
|
|
18200
|
-
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
18201
|
-
.filter((v) => v[1] !== 0n)
|
|
18202
|
-
.map(([idx, value]) => {
|
|
18203
|
-
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
18204
|
-
})
|
|
18205
|
-
.join(", ");
|
|
18206
|
-
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
18568
|
+
return blocks;
|
|
18207
18569
|
}
|
|
18208
18570
|
}
|
|
18209
18571
|
|
|
18210
|
-
type
|
|
18572
|
+
type index$6_Interpreter = Interpreter;
|
|
18573
|
+
declare const index$6_Interpreter: typeof Interpreter;
|
|
18574
|
+
type index$6_InterpreterOptions = InterpreterOptions;
|
|
18575
|
+
type index$6_Memory = Memory;
|
|
18576
|
+
declare const index$6_Memory: typeof Memory;
|
|
18577
|
+
type index$6_MemoryBuilder = MemoryBuilder;
|
|
18578
|
+
declare const index$6_MemoryBuilder: typeof MemoryBuilder;
|
|
18579
|
+
type index$6_MemoryIndex = MemoryIndex;
|
|
18580
|
+
type index$6_Registers = Registers;
|
|
18581
|
+
declare const index$6_Registers: typeof Registers;
|
|
18582
|
+
type index$6_SbrkIndex = SbrkIndex;
|
|
18583
|
+
declare const index$6_gasCounter: typeof gasCounter;
|
|
18584
|
+
declare const index$6_logger: typeof logger;
|
|
18585
|
+
declare const index$6_tryAsMemoryIndex: typeof tryAsMemoryIndex;
|
|
18586
|
+
declare const index$6_tryAsSbrkIndex: typeof tryAsSbrkIndex;
|
|
18587
|
+
declare namespace index$6 {
|
|
18588
|
+
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 };
|
|
18589
|
+
export type { index$6_InterpreterOptions as InterpreterOptions, index$6_MemoryIndex as MemoryIndex, index$6_SbrkIndex as SbrkIndex };
|
|
18590
|
+
}
|
|
18591
|
+
|
|
18592
|
+
type ResolveFn = (pvm: IPvmInterpreter) => void;
|
|
18211
18593
|
|
|
18594
|
+
// TODO [MaSo] Delete this & also make host calls independent from intepreters.
|
|
18212
18595
|
declare class InterpreterInstanceManager {
|
|
18213
|
-
private instances: Interpreter[] = [];
|
|
18214
18596
|
private waitingQueue: ResolveFn[] = [];
|
|
18215
18597
|
|
|
18216
|
-
constructor(
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18598
|
+
private constructor(private readonly instances: IPvmInterpreter[]) {}
|
|
18599
|
+
|
|
18600
|
+
static async new(interpreter: PvmBackend): Promise<InterpreterInstanceManager> {
|
|
18601
|
+
const instances: IPvmInterpreter[] = [];
|
|
18602
|
+
switch (interpreter) {
|
|
18603
|
+
case PvmBackend.BuiltIn:
|
|
18604
|
+
instances.push(
|
|
18605
|
+
new Interpreter({
|
|
18606
|
+
useSbrkGas: false,
|
|
18607
|
+
}),
|
|
18608
|
+
);
|
|
18609
|
+
break;
|
|
18610
|
+
case PvmBackend.Ananas:
|
|
18611
|
+
instances.push(await AnanasInterpreter.new());
|
|
18612
|
+
break;
|
|
18613
|
+
default:
|
|
18614
|
+
assertNever(interpreter);
|
|
18223
18615
|
}
|
|
18616
|
+
return new InterpreterInstanceManager(instances);
|
|
18224
18617
|
}
|
|
18225
18618
|
|
|
18226
|
-
async getInstance(): Promise<
|
|
18619
|
+
async getInstance(): Promise<IPvmInterpreter> {
|
|
18227
18620
|
const instance = this.instances.pop();
|
|
18228
18621
|
if (instance !== undefined) {
|
|
18229
18622
|
return Promise.resolve(instance);
|
|
@@ -18233,7 +18626,7 @@ declare class InterpreterInstanceManager {
|
|
|
18233
18626
|
});
|
|
18234
18627
|
}
|
|
18235
18628
|
|
|
18236
|
-
releaseInstance(pvm:
|
|
18629
|
+
releaseInstance(pvm: IPvmInterpreter) {
|
|
18237
18630
|
const waiting = this.waitingQueue.shift();
|
|
18238
18631
|
if (waiting !== undefined) {
|
|
18239
18632
|
return waiting(pvm);
|
|
@@ -18276,21 +18669,22 @@ declare class HostCalls {
|
|
|
18276
18669
|
private hostCalls: HostCallsManager,
|
|
18277
18670
|
) {}
|
|
18278
18671
|
|
|
18279
|
-
private getReturnValue(status: Status, pvmInstance:
|
|
18280
|
-
const gasConsumed = pvmInstance.
|
|
18672
|
+
private getReturnValue(status: Status, pvmInstance: IPvmInterpreter): ReturnValue {
|
|
18673
|
+
const gasConsumed = pvmInstance.gas.used();
|
|
18281
18674
|
if (status === Status.OOG) {
|
|
18282
18675
|
return ReturnValue.fromStatus(gasConsumed, status);
|
|
18283
18676
|
}
|
|
18284
18677
|
|
|
18285
18678
|
if (status === Status.HALT) {
|
|
18286
|
-
const
|
|
18287
|
-
const
|
|
18288
|
-
const
|
|
18289
|
-
|
|
18679
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
18680
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
18681
|
+
const address = regs.get(7);
|
|
18682
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
18683
|
+
const length = Number(regs.get(8) & 0xffff_ffffn);
|
|
18290
18684
|
|
|
18291
|
-
const result = safeAllocUint8Array(
|
|
18292
|
-
|
|
18293
|
-
const loadResult = memory.loadInto(result,
|
|
18685
|
+
const result = safeAllocUint8Array(length);
|
|
18686
|
+
|
|
18687
|
+
const loadResult = memory.loadInto(result, address);
|
|
18294
18688
|
|
|
18295
18689
|
if (loadResult.isError) {
|
|
18296
18690
|
return ReturnValue.fromMemorySlice(gasConsumed, new Uint8Array());
|
|
@@ -18302,7 +18696,7 @@ declare class HostCalls {
|
|
|
18302
18696
|
return ReturnValue.fromStatus(gasConsumed, Status.PANIC);
|
|
18303
18697
|
}
|
|
18304
18698
|
|
|
18305
|
-
private async execute(pvmInstance:
|
|
18699
|
+
private async execute(pvmInstance: IPvmInterpreter) {
|
|
18306
18700
|
pvmInstance.runProgram();
|
|
18307
18701
|
for (;;) {
|
|
18308
18702
|
let status = pvmInstance.getStatus();
|
|
@@ -18314,9 +18708,9 @@ declare class HostCalls {
|
|
|
18314
18708
|
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
18315
18709
|
`;
|
|
18316
18710
|
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
18317
|
-
const gas = pvmInstance.
|
|
18318
|
-
const regs = new HostCallRegisters(pvmInstance.
|
|
18319
|
-
const memory = new HostCallMemory(pvmInstance.
|
|
18711
|
+
const gas = pvmInstance.gas;
|
|
18712
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
18713
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
18320
18714
|
const index = tryAsHostCallIndex(hostCallIndex);
|
|
18321
18715
|
|
|
18322
18716
|
const hostCall = this.hostCalls.get(index);
|
|
@@ -18329,7 +18723,7 @@ declare class HostCalls {
|
|
|
18329
18723
|
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
18330
18724
|
if (underflow) {
|
|
18331
18725
|
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
18332
|
-
return ReturnValue.fromStatus(
|
|
18726
|
+
return ReturnValue.fromStatus(gas.used(), Status.OOG);
|
|
18333
18727
|
}
|
|
18334
18728
|
this.hostCalls.traceHostCall(`${pcLog} Invoking`, index, hostCall, regs, gasBefore);
|
|
18335
18729
|
const result = await hostCall.execute(gas, regs, memory);
|
|
@@ -18340,6 +18734,7 @@ declare class HostCalls {
|
|
|
18340
18734
|
regs,
|
|
18341
18735
|
gas.get(),
|
|
18342
18736
|
);
|
|
18737
|
+
pvmInstance.registers.setAllEncoded(regs.getEncoded());
|
|
18343
18738
|
|
|
18344
18739
|
if (result === PvmExecution.Halt) {
|
|
18345
18740
|
status = Status.HALT;
|
|
@@ -18366,15 +18761,9 @@ declare class HostCalls {
|
|
|
18366
18761
|
}
|
|
18367
18762
|
}
|
|
18368
18763
|
|
|
18369
|
-
async runProgram(
|
|
18370
|
-
rawProgram: Uint8Array,
|
|
18371
|
-
initialPc: number,
|
|
18372
|
-
initialGas: Gas,
|
|
18373
|
-
maybeRegisters?: Registers,
|
|
18374
|
-
maybeMemory?: Memory,
|
|
18375
|
-
): Promise<ReturnValue> {
|
|
18764
|
+
async runProgram(program: Uint8Array, args: Uint8Array, initialPc: number, initialGas: Gas): Promise<ReturnValue> {
|
|
18376
18765
|
const pvmInstance = await this.pvmInstanceManager.getInstance();
|
|
18377
|
-
pvmInstance.
|
|
18766
|
+
pvmInstance.resetJam(program, args, initialPc, initialGas);
|
|
18378
18767
|
try {
|
|
18379
18768
|
return await this.execute(pvmInstance);
|
|
18380
18769
|
} finally {
|
|
@@ -18383,20 +18772,18 @@ declare class HostCalls {
|
|
|
18383
18772
|
}
|
|
18384
18773
|
}
|
|
18385
18774
|
|
|
18386
|
-
type index$
|
|
18387
|
-
type index$
|
|
18388
|
-
declare const index$
|
|
18389
|
-
type index$
|
|
18390
|
-
declare const index$
|
|
18391
|
-
type index$
|
|
18392
|
-
|
|
18393
|
-
|
|
18394
|
-
declare const index$
|
|
18395
|
-
declare
|
|
18396
|
-
|
|
18397
|
-
|
|
18398
|
-
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 };
|
|
18399
|
-
export type { index$7_HostCallHandler as HostCallHandler, index$7_IHostCallMemory as IHostCallMemory, index$7_IHostCallRegisters as IHostCallRegisters };
|
|
18775
|
+
type index$5_HostCallHandler = HostCallHandler;
|
|
18776
|
+
type index$5_HostCallMemory = HostCallMemory;
|
|
18777
|
+
declare const index$5_HostCallMemory: typeof HostCallMemory;
|
|
18778
|
+
type index$5_HostCallRegisters = HostCallRegisters;
|
|
18779
|
+
declare const index$5_HostCallRegisters: typeof HostCallRegisters;
|
|
18780
|
+
type index$5_PvmExecution = PvmExecution;
|
|
18781
|
+
declare const index$5_PvmExecution: typeof PvmExecution;
|
|
18782
|
+
declare const index$5_traceRegisters: typeof traceRegisters;
|
|
18783
|
+
declare const index$5_tryAsHostCallIndex: typeof tryAsHostCallIndex;
|
|
18784
|
+
declare namespace index$5 {
|
|
18785
|
+
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 };
|
|
18786
|
+
export type { index$5_HostCallHandler as HostCallHandler };
|
|
18400
18787
|
}
|
|
18401
18788
|
|
|
18402
18789
|
/**
|
|
@@ -18414,7 +18801,7 @@ type MachineId = Opaque<U64, "MachineId[u64]">;
|
|
|
18414
18801
|
declare const tryAsMachineId = (v: number | bigint): MachineId => asOpaqueType(tryAsU64(v));
|
|
18415
18802
|
|
|
18416
18803
|
declare class MachineInstance {
|
|
18417
|
-
async run(gas: BigGas, registers:
|
|
18804
|
+
async run(gas: BigGas, registers: HostCallRegisters): Promise<MachineResult> {
|
|
18418
18805
|
return {
|
|
18419
18806
|
result: {
|
|
18420
18807
|
status: Status.OK,
|
|
@@ -18442,7 +18829,7 @@ type MachineStatus =
|
|
|
18442
18829
|
type MachineResult = {
|
|
18443
18830
|
result: MachineStatus;
|
|
18444
18831
|
gas: BigGas;
|
|
18445
|
-
registers:
|
|
18832
|
+
registers: HostCallRegisters;
|
|
18446
18833
|
};
|
|
18447
18834
|
|
|
18448
18835
|
/** Types of possbile operations to request by Pages host call. */
|
|
@@ -18514,7 +18901,7 @@ interface RefineExternalities {
|
|
|
18514
18901
|
destinationStart: U64,
|
|
18515
18902
|
sourceStart: U64,
|
|
18516
18903
|
length: U64,
|
|
18517
|
-
destination:
|
|
18904
|
+
destination: HostCallMemory,
|
|
18518
18905
|
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18519
18906
|
|
|
18520
18907
|
/** Write a fragment of memory into `machineIndex` from given source memory. */
|
|
@@ -18523,7 +18910,7 @@ interface RefineExternalities {
|
|
|
18523
18910
|
sourceStart: U64,
|
|
18524
18911
|
destinationStart: U64,
|
|
18525
18912
|
length: U64,
|
|
18526
|
-
source:
|
|
18913
|
+
source: HostCallMemory,
|
|
18527
18914
|
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18528
18915
|
|
|
18529
18916
|
/** Start an inner PVM instance with given entry point and starting code. */
|
|
@@ -18533,7 +18920,7 @@ interface RefineExternalities {
|
|
|
18533
18920
|
machineInvoke(
|
|
18534
18921
|
machineIndex: MachineId,
|
|
18535
18922
|
gas: BigGas,
|
|
18536
|
-
registers:
|
|
18923
|
+
registers: HostCallRegisters,
|
|
18537
18924
|
): Promise<Result$2<MachineResult, NoMachineError>>;
|
|
18538
18925
|
|
|
18539
18926
|
/**
|
|
@@ -18955,7 +19342,7 @@ declare const CURRENT_SERVICE_ID = tryAsServiceId(2 ** 32 - 1);
|
|
|
18955
19342
|
|
|
18956
19343
|
declare function getServiceIdOrCurrent(
|
|
18957
19344
|
regNumber: number,
|
|
18958
|
-
regs:
|
|
19345
|
+
regs: HostCallRegisters,
|
|
18959
19346
|
currentServiceId: ServiceId,
|
|
18960
19347
|
): ServiceId | null {
|
|
18961
19348
|
const regValue = regs.get(regNumber);
|
|
@@ -18986,270 +19373,75 @@ declare function clampU64ToU32(value: U64): U32 {
|
|
|
18986
19373
|
return value > MAX_U32_BIG_INT ? MAX_U32 : tryAsU32(Number(value));
|
|
18987
19374
|
}
|
|
18988
19375
|
|
|
18989
|
-
|
|
18990
|
-
|
|
18991
|
-
|
|
18992
|
-
|
|
18993
|
-
|
|
18994
|
-
|
|
18995
|
-
declare const index$
|
|
18996
|
-
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
declare const index$
|
|
19000
|
-
|
|
19001
|
-
type index$
|
|
19002
|
-
declare const index$
|
|
19003
|
-
|
|
19004
|
-
type index$
|
|
19005
|
-
type index$
|
|
19006
|
-
declare const index$
|
|
19007
|
-
type index$
|
|
19008
|
-
|
|
19009
|
-
type index$
|
|
19010
|
-
|
|
19011
|
-
|
|
19012
|
-
|
|
19013
|
-
type index$
|
|
19014
|
-
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
type index$
|
|
19018
|
-
declare const index$
|
|
19019
|
-
type index$
|
|
19020
|
-
|
|
19021
|
-
|
|
19022
|
-
|
|
19023
|
-
type index$
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
type index$
|
|
19027
|
-
|
|
19028
|
-
declare const index$
|
|
19029
|
-
type index$
|
|
19030
|
-
type index$
|
|
19031
|
-
|
|
19032
|
-
|
|
19033
|
-
type index$
|
|
19034
|
-
|
|
19035
|
-
type index$
|
|
19036
|
-
type index$
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
declare const index$
|
|
19042
|
-
|
|
19043
|
-
declare const index$
|
|
19044
|
-
declare const index$
|
|
19045
|
-
declare const index$
|
|
19046
|
-
declare const index$
|
|
19047
|
-
declare const index$
|
|
19048
|
-
declare const index$
|
|
19049
|
-
declare const index$
|
|
19050
|
-
declare
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
declare const NO_OF_REGISTERS = 13;
|
|
19056
|
-
|
|
19057
|
-
declare class MemorySegment extends WithDebug {
|
|
19058
|
-
static from({ start, end, data }: Omit<MemorySegment, never>) {
|
|
19059
|
-
return new MemorySegment(start, end, data);
|
|
19060
|
-
}
|
|
19061
|
-
|
|
19062
|
-
constructor(
|
|
19063
|
-
public readonly start: number,
|
|
19064
|
-
public readonly end: number,
|
|
19065
|
-
public readonly data: Uint8Array | null,
|
|
19066
|
-
) {
|
|
19067
|
-
super();
|
|
19068
|
-
}
|
|
19069
|
-
}
|
|
19070
|
-
declare class SpiMemory extends WithDebug {
|
|
19071
|
-
constructor(
|
|
19072
|
-
public readonly readable: MemorySegment[],
|
|
19073
|
-
public readonly writeable: MemorySegment[],
|
|
19074
|
-
public readonly sbrkIndex: number,
|
|
19075
|
-
public readonly heapEnd: number,
|
|
19076
|
-
) {
|
|
19077
|
-
super();
|
|
19078
|
-
}
|
|
19079
|
-
}
|
|
19080
|
-
|
|
19081
|
-
declare class SpiProgram extends WithDebug {
|
|
19082
|
-
constructor(
|
|
19083
|
-
public readonly code: Uint8Array,
|
|
19084
|
-
public readonly memory: SpiMemory,
|
|
19085
|
-
public readonly registers: BigUint64Array,
|
|
19086
|
-
) {
|
|
19087
|
-
super();
|
|
19088
|
-
}
|
|
19089
|
-
}
|
|
19090
|
-
|
|
19091
|
-
/**
|
|
19092
|
-
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
19093
|
-
*
|
|
19094
|
-
* E_n - little endian encoding, n - length
|
|
19095
|
-
* o - initial read only data
|
|
19096
|
-
* w - initial heap
|
|
19097
|
-
* z - heap pages filled with zeros
|
|
19098
|
-
* s - stack size
|
|
19099
|
-
* c - program code
|
|
19100
|
-
*
|
|
19101
|
-
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
19102
|
-
*/
|
|
19103
|
-
declare function decodeStandardProgram(program: Uint8Array, args: Uint8Array) {
|
|
19104
|
-
const decoder = Decoder.fromBlob(program);
|
|
19105
|
-
const oLength = decoder.u24();
|
|
19106
|
-
const wLength = decoder.u24();
|
|
19107
|
-
check`${args.length <= DATA_LENGTH} Incorrect arguments length`;
|
|
19108
|
-
check`${oLength <= DATA_LENGTH} Incorrect readonly segment length`;
|
|
19109
|
-
const readOnlyLength = oLength;
|
|
19110
|
-
check`${wLength <= DATA_LENGTH} Incorrect heap segment length`;
|
|
19111
|
-
const heapLength = wLength;
|
|
19112
|
-
const noOfHeapZerosPages = decoder.u16();
|
|
19113
|
-
const stackSize = decoder.u24();
|
|
19114
|
-
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
19115
|
-
const initialHeap = decoder.bytes(heapLength).raw;
|
|
19116
|
-
const codeLength = decoder.u32();
|
|
19117
|
-
const code = decoder.bytes(codeLength).raw;
|
|
19118
|
-
decoder.finish();
|
|
19119
|
-
|
|
19120
|
-
const readonlyDataStart = SEGMENT_SIZE;
|
|
19121
|
-
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
19122
|
-
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
19123
|
-
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
19124
|
-
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
19125
|
-
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
19126
|
-
const stackEnd = STACK_SEGMENT;
|
|
19127
|
-
const argsStart = ARGS_SEGMENT;
|
|
19128
|
-
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
19129
|
-
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
19130
|
-
|
|
19131
|
-
function nonEmpty(s: MemorySegment | false): s is MemorySegment {
|
|
19132
|
-
return s !== false;
|
|
19133
|
-
}
|
|
19134
|
-
|
|
19135
|
-
const readableMemory = [
|
|
19136
|
-
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
19137
|
-
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
19138
|
-
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
19139
|
-
].filter(nonEmpty);
|
|
19140
|
-
const writeableMemory = [
|
|
19141
|
-
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
19142
|
-
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
19143
|
-
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
19144
|
-
].filter(nonEmpty);
|
|
19145
|
-
|
|
19146
|
-
return new SpiProgram(
|
|
19147
|
-
code,
|
|
19148
|
-
new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart),
|
|
19149
|
-
getRegisters(args.length),
|
|
19150
|
-
);
|
|
19151
|
-
}
|
|
19152
|
-
|
|
19153
|
-
declare function getMemorySegment(start: number, end: number, data: Uint8Array | null = null) {
|
|
19154
|
-
return new MemorySegment(start, end, data);
|
|
19155
|
-
}
|
|
19156
|
-
|
|
19157
|
-
declare function getRegisters(argsLength: number) {
|
|
19158
|
-
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
19159
|
-
|
|
19160
|
-
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
19161
|
-
regs[0] = BigInt(LAST_PAGE);
|
|
19162
|
-
regs[1] = BigInt(STACK_SEGMENT);
|
|
19163
|
-
regs[7] = BigInt(ARGS_SEGMENT);
|
|
19164
|
-
regs[8] = BigInt(argsLength);
|
|
19165
|
-
|
|
19166
|
-
return regs;
|
|
19167
|
-
}
|
|
19168
|
-
|
|
19169
|
-
type index$5_MemorySegment = MemorySegment;
|
|
19170
|
-
declare const index$5_MemorySegment: typeof MemorySegment;
|
|
19171
|
-
declare const index$5_NO_OF_REGISTERS: typeof NO_OF_REGISTERS;
|
|
19172
|
-
type index$5_SpiMemory = SpiMemory;
|
|
19173
|
-
declare const index$5_SpiMemory: typeof SpiMemory;
|
|
19174
|
-
type index$5_SpiProgram = SpiProgram;
|
|
19175
|
-
declare const index$5_SpiProgram: typeof SpiProgram;
|
|
19176
|
-
declare const index$5_decodeStandardProgram: typeof decodeStandardProgram;
|
|
19177
|
-
declare const index$5_getMemorySegment: typeof getMemorySegment;
|
|
19178
|
-
declare const index$5_getRegisters: typeof getRegisters;
|
|
19179
|
-
declare namespace index$5 {
|
|
19180
|
-
export {
|
|
19181
|
-
index$5_MemorySegment as MemorySegment,
|
|
19182
|
-
index$5_NO_OF_REGISTERS as NO_OF_REGISTERS,
|
|
19183
|
-
index$5_SpiMemory as SpiMemory,
|
|
19184
|
-
index$5_SpiProgram as SpiProgram,
|
|
19185
|
-
index$5_decodeStandardProgram as decodeStandardProgram,
|
|
19186
|
-
index$5_getMemorySegment as getMemorySegment,
|
|
19187
|
-
index$5_getRegisters as getRegisters,
|
|
19188
|
-
};
|
|
19189
|
-
}
|
|
19190
|
-
|
|
19191
|
-
declare class Program {
|
|
19192
|
-
static fromSpi(blob: Uint8Array, args: Uint8Array, hasMetadata: boolean) {
|
|
19193
|
-
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
19194
|
-
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
19195
|
-
const regs = new Registers();
|
|
19196
|
-
regs.copyFrom(registers);
|
|
19197
|
-
const memoryBuilder = new MemoryBuilder();
|
|
19198
|
-
|
|
19199
|
-
for (const { start, end, data } of rawMemory.readable) {
|
|
19200
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
19201
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
19202
|
-
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
19203
|
-
}
|
|
19204
|
-
|
|
19205
|
-
for (const { start, end, data } of rawMemory.writeable) {
|
|
19206
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
19207
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
19208
|
-
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
19209
|
-
}
|
|
19210
|
-
|
|
19211
|
-
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
19212
|
-
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
19213
|
-
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
19214
|
-
|
|
19215
|
-
return new Program(code, regs, memory, metadata);
|
|
19216
|
-
}
|
|
19217
|
-
|
|
19218
|
-
static fromGeneric(blob: Uint8Array, hasMetadata: boolean) {
|
|
19219
|
-
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
19220
|
-
const regs = new Registers();
|
|
19221
|
-
const memory = new Memory();
|
|
19222
|
-
return new Program(code, regs, memory, metadata);
|
|
19223
|
-
}
|
|
19224
|
-
|
|
19225
|
-
private constructor(
|
|
19226
|
-
public readonly code: Uint8Array,
|
|
19227
|
-
public readonly registers: Registers,
|
|
19228
|
-
public readonly memory: Memory,
|
|
19229
|
-
public metadata: Uint8Array = new Uint8Array(),
|
|
19230
|
-
) {}
|
|
19231
|
-
}
|
|
19232
|
-
|
|
19233
|
-
/**
|
|
19234
|
-
* A function that splits preimage into metadata and code.
|
|
19235
|
-
*
|
|
19236
|
-
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
19237
|
-
*/
|
|
19238
|
-
declare function extractCodeAndMetadata(blobWithMetadata: Uint8Array) {
|
|
19239
|
-
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
19240
|
-
const metadata = decoder.bytesBlob().raw;
|
|
19241
|
-
const code = decoder.remainingBytes().raw;
|
|
19242
|
-
return { metadata, code };
|
|
19243
|
-
}
|
|
19244
|
-
|
|
19245
|
-
type index$4_Program = Program;
|
|
19246
|
-
declare const index$4_Program: typeof Program;
|
|
19247
|
-
declare const index$4_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
19376
|
+
declare function emptyRegistersBuffer(): Uint8Array {
|
|
19377
|
+
return safeAllocUint8Array(NO_OF_REGISTERS * REGISTER_BYTE_SIZE);
|
|
19378
|
+
}
|
|
19379
|
+
|
|
19380
|
+
type index$4_AccumulationStateUpdate = AccumulationStateUpdate;
|
|
19381
|
+
declare const index$4_AccumulationStateUpdate: typeof AccumulationStateUpdate;
|
|
19382
|
+
declare const index$4_CURRENT_SERVICE_ID: typeof CURRENT_SERVICE_ID;
|
|
19383
|
+
type index$4_EjectError = EjectError;
|
|
19384
|
+
declare const index$4_EjectError: typeof EjectError;
|
|
19385
|
+
type index$4_ForgetPreimageError = ForgetPreimageError;
|
|
19386
|
+
declare const index$4_ForgetPreimageError: typeof ForgetPreimageError;
|
|
19387
|
+
declare const index$4_HostCallResult: typeof HostCallResult;
|
|
19388
|
+
type index$4_InsufficientFundsError = InsufficientFundsError;
|
|
19389
|
+
declare const index$4_MAX_U32: typeof MAX_U32;
|
|
19390
|
+
declare const index$4_MAX_U32_BIG_INT: typeof MAX_U32_BIG_INT;
|
|
19391
|
+
type index$4_MachineId = MachineId;
|
|
19392
|
+
type index$4_MachineInstance = MachineInstance;
|
|
19393
|
+
declare const index$4_MachineInstance: typeof MachineInstance;
|
|
19394
|
+
type index$4_MachineResult = MachineResult;
|
|
19395
|
+
type index$4_MachineStatus = MachineStatus;
|
|
19396
|
+
type index$4_MemoryOperation = MemoryOperation;
|
|
19397
|
+
declare const index$4_MemoryOperation: typeof MemoryOperation;
|
|
19398
|
+
type index$4_NewServiceError = NewServiceError;
|
|
19399
|
+
declare const index$4_NewServiceError: typeof NewServiceError;
|
|
19400
|
+
type index$4_NoMachineError = NoMachineError;
|
|
19401
|
+
type index$4_PagesError = PagesError;
|
|
19402
|
+
declare const index$4_PagesError: typeof PagesError;
|
|
19403
|
+
type index$4_PartialState = PartialState;
|
|
19404
|
+
type index$4_PartiallyUpdatedState<T extends StateSlice = StateSlice> = PartiallyUpdatedState<T>;
|
|
19405
|
+
declare const index$4_PartiallyUpdatedState: typeof PartiallyUpdatedState;
|
|
19406
|
+
type index$4_PeekPokeError = PeekPokeError;
|
|
19407
|
+
declare const index$4_PeekPokeError: typeof PeekPokeError;
|
|
19408
|
+
type index$4_PendingTransfer = PendingTransfer;
|
|
19409
|
+
declare const index$4_PendingTransfer: typeof PendingTransfer;
|
|
19410
|
+
type index$4_PreimageStatus = PreimageStatus;
|
|
19411
|
+
type index$4_PreimageStatusKind = PreimageStatusKind;
|
|
19412
|
+
declare const index$4_PreimageStatusKind: typeof PreimageStatusKind;
|
|
19413
|
+
type index$4_ProgramCounter = ProgramCounter;
|
|
19414
|
+
type index$4_ProvidePreimageError = ProvidePreimageError;
|
|
19415
|
+
declare const index$4_ProvidePreimageError: typeof ProvidePreimageError;
|
|
19416
|
+
type index$4_RefineExternalities = RefineExternalities;
|
|
19417
|
+
type index$4_RequestPreimageError = RequestPreimageError;
|
|
19418
|
+
declare const index$4_RequestPreimageError: typeof RequestPreimageError;
|
|
19419
|
+
declare const index$4_SERVICE_ID_BYTES: typeof SERVICE_ID_BYTES;
|
|
19420
|
+
type index$4_SegmentExportError = SegmentExportError;
|
|
19421
|
+
type index$4_ServiceStateUpdate = ServiceStateUpdate;
|
|
19422
|
+
type index$4_StateSlice = StateSlice;
|
|
19423
|
+
type index$4_TRANSFER_MEMO_BYTES = TRANSFER_MEMO_BYTES;
|
|
19424
|
+
type index$4_TransferError = TransferError;
|
|
19425
|
+
declare const index$4_TransferError: typeof TransferError;
|
|
19426
|
+
type index$4_UnprivilegedError = UnprivilegedError;
|
|
19427
|
+
type index$4_UpdatePrivilegesError = UpdatePrivilegesError;
|
|
19428
|
+
declare const index$4_UpdatePrivilegesError: typeof UpdatePrivilegesError;
|
|
19429
|
+
type index$4_ZeroVoidError = ZeroVoidError;
|
|
19430
|
+
declare const index$4_ZeroVoidError: typeof ZeroVoidError;
|
|
19431
|
+
declare const index$4_clampU64ToU32: typeof clampU64ToU32;
|
|
19432
|
+
declare const index$4_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
19433
|
+
declare const index$4_emptyRegistersBuffer: typeof emptyRegistersBuffer;
|
|
19434
|
+
declare const index$4_getServiceId: typeof getServiceId;
|
|
19435
|
+
declare const index$4_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
19436
|
+
declare const index$4_preimageLenAsU32: typeof preimageLenAsU32;
|
|
19437
|
+
declare const index$4_slotsToPreimageStatus: typeof slotsToPreimageStatus;
|
|
19438
|
+
declare const index$4_toMemoryOperation: typeof toMemoryOperation;
|
|
19439
|
+
declare const index$4_tryAsMachineId: typeof tryAsMachineId;
|
|
19440
|
+
declare const index$4_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
19441
|
+
declare const index$4_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
19248
19442
|
declare namespace index$4 {
|
|
19249
|
-
export {
|
|
19250
|
-
|
|
19251
|
-
index$4_extractCodeAndMetadata as extractCodeAndMetadata,
|
|
19252
|
-
};
|
|
19443
|
+
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 };
|
|
19444
|
+
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 };
|
|
19253
19445
|
}
|
|
19254
19446
|
|
|
19255
19447
|
declare class DebuggerAdapter {
|
|
@@ -19265,11 +19457,11 @@ declare class DebuggerAdapter {
|
|
|
19265
19457
|
}
|
|
19266
19458
|
|
|
19267
19459
|
resetGeneric(rawProgram: Uint8Array, flatRegisters: Uint8Array, initialGas: bigint) {
|
|
19268
|
-
this.pvm.
|
|
19460
|
+
this.pvm.resetGeneric(rawProgram, 0, tryAsGas(initialGas), new Registers(flatRegisters));
|
|
19269
19461
|
}
|
|
19270
19462
|
|
|
19271
19463
|
reset(rawProgram: Uint8Array, pc: number, gas: bigint, maybeRegisters?: Registers, maybeMemory?: Memory) {
|
|
19272
|
-
this.pvm.
|
|
19464
|
+
this.pvm.resetGeneric(rawProgram, pc, tryAsGas(gas), maybeRegisters, maybeMemory);
|
|
19273
19465
|
}
|
|
19274
19466
|
|
|
19275
19467
|
getPageDump(pageNumber: number): null | Uint8Array {
|
|
@@ -19292,7 +19484,7 @@ declare class DebuggerAdapter {
|
|
|
19292
19484
|
}
|
|
19293
19485
|
|
|
19294
19486
|
setMemory(address: number, value: Uint8Array) {
|
|
19295
|
-
this.pvm.
|
|
19487
|
+
this.pvm.memory.storeFrom(tryAsMemoryIndex(address), value);
|
|
19296
19488
|
}
|
|
19297
19489
|
|
|
19298
19490
|
getExitArg(): number {
|
|
@@ -19319,11 +19511,11 @@ declare class DebuggerAdapter {
|
|
|
19319
19511
|
}
|
|
19320
19512
|
|
|
19321
19513
|
getRegisters(): BigUint64Array {
|
|
19322
|
-
return this.pvm.
|
|
19514
|
+
return this.pvm.registers.getAllU64();
|
|
19323
19515
|
}
|
|
19324
19516
|
|
|
19325
19517
|
setRegisters(registers: Uint8Array) {
|
|
19326
|
-
this.pvm.
|
|
19518
|
+
this.pvm.registers.copyFrom(new Registers(registers));
|
|
19327
19519
|
}
|
|
19328
19520
|
|
|
19329
19521
|
getProgramCounter(): number {
|
|
@@ -19335,11 +19527,11 @@ declare class DebuggerAdapter {
|
|
|
19335
19527
|
}
|
|
19336
19528
|
|
|
19337
19529
|
getGasLeft(): bigint {
|
|
19338
|
-
return BigInt(this.pvm.
|
|
19530
|
+
return BigInt(this.pvm.gas.get());
|
|
19339
19531
|
}
|
|
19340
19532
|
|
|
19341
19533
|
setGasLeft(gas: bigint) {
|
|
19342
|
-
this.pvm.
|
|
19534
|
+
this.pvm.gas.set(tryAsGas(gas));
|
|
19343
19535
|
}
|
|
19344
19536
|
}
|
|
19345
19537
|
|
|
@@ -19366,8 +19558,6 @@ declare const index$3_HostCallMemory: typeof HostCallMemory;
|
|
|
19366
19558
|
type index$3_HostCallRegisters = HostCallRegisters;
|
|
19367
19559
|
declare const index$3_HostCallRegisters: typeof HostCallRegisters;
|
|
19368
19560
|
declare const index$3_HostCallResult: typeof HostCallResult;
|
|
19369
|
-
type index$3_IHostCallMemory = IHostCallMemory;
|
|
19370
|
-
type index$3_IHostCallRegisters = IHostCallRegisters;
|
|
19371
19561
|
type index$3_ImmediateDecoder = ImmediateDecoder;
|
|
19372
19562
|
declare const index$3_ImmediateDecoder: typeof ImmediateDecoder;
|
|
19373
19563
|
type index$3_InsufficientFundsError = InsufficientFundsError;
|
|
@@ -19450,6 +19640,7 @@ declare const index$3_clampU64ToU32: typeof clampU64ToU32;
|
|
|
19450
19640
|
declare const index$3_createResults: typeof createResults;
|
|
19451
19641
|
declare const index$3_decodeStandardProgram: typeof decodeStandardProgram;
|
|
19452
19642
|
declare const index$3_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
19643
|
+
declare const index$3_emptyRegistersBuffer: typeof emptyRegistersBuffer;
|
|
19453
19644
|
declare const index$3_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
19454
19645
|
declare const index$3_getServiceId: typeof getServiceId;
|
|
19455
19646
|
declare const index$3_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
@@ -19457,6 +19648,7 @@ declare const index$3_inspect: typeof inspect;
|
|
|
19457
19648
|
declare const index$3_instructionArgumentTypeMap: typeof instructionArgumentTypeMap;
|
|
19458
19649
|
declare const index$3_isBrowser: typeof isBrowser;
|
|
19459
19650
|
declare const index$3_isTaggedError: typeof isTaggedError;
|
|
19651
|
+
declare const index$3_lazyInspect: typeof lazyInspect;
|
|
19460
19652
|
declare const index$3_maybeTaggedErrorToString: typeof maybeTaggedErrorToString;
|
|
19461
19653
|
declare const index$3_measure: typeof measure;
|
|
19462
19654
|
declare const index$3_preimageLenAsU32: typeof preimageLenAsU32;
|
|
@@ -19468,8 +19660,8 @@ declare const index$3_tryAsMachineId: typeof tryAsMachineId;
|
|
|
19468
19660
|
declare const index$3_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
19469
19661
|
declare const index$3_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
19470
19662
|
declare namespace index$3 {
|
|
19471
|
-
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$
|
|
19472
|
-
export type { index$3_Args as Args, index$3_EnumMapping as EnumMapping, index$3_ErrorResult as ErrorResult, index$
|
|
19663
|
+
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_lazyInspect as lazyInspect, 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 };
|
|
19664
|
+
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 };
|
|
19473
19665
|
}
|
|
19474
19666
|
|
|
19475
19667
|
declare const ENTROPY_BYTES = 32;
|
|
@@ -20062,10 +20254,10 @@ declare const fullStateDumpFromJson = (spec: ChainSpec) =>
|
|
|
20062
20254
|
chi_v: "number",
|
|
20063
20255
|
chi_r: json.optional("number"),
|
|
20064
20256
|
chi_g: json.nullable(
|
|
20065
|
-
json.
|
|
20066
|
-
|
|
20067
|
-
|
|
20068
|
-
|
|
20257
|
+
json.map(
|
|
20258
|
+
"number",
|
|
20259
|
+
json.fromNumber((v) => tryAsServiceGas(v)),
|
|
20260
|
+
),
|
|
20069
20261
|
),
|
|
20070
20262
|
},
|
|
20071
20263
|
pi: JsonStatisticsData.fromJson,
|
|
@@ -20132,7 +20324,7 @@ declare const fullStateDumpFromJson = (spec: ChainSpec) =>
|
|
|
20132
20324
|
assigners: chi.chi_a,
|
|
20133
20325
|
delegator: chi.chi_v,
|
|
20134
20326
|
registrar: chi.chi_r ?? tryAsServiceId(2 ** 32 - 1),
|
|
20135
|
-
autoAccumulateServices: chi.chi_g ??
|
|
20327
|
+
autoAccumulateServices: chi.chi_g ?? new Map(),
|
|
20136
20328
|
}),
|
|
20137
20329
|
statistics: JsonStatisticsData.toStatisticsData(spec, pi),
|
|
20138
20330
|
accumulationQueue: omega,
|
|
@@ -20361,4 +20553,4 @@ declare namespace index {
|
|
|
20361
20553
|
export type { index_PreimagesInput as PreimagesInput, index_PreimagesState as PreimagesState, index_PreimagesStateUpdate as PreimagesStateUpdate };
|
|
20362
20554
|
}
|
|
20363
20555
|
|
|
20364
|
-
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$
|
|
20556
|
+
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 };
|