@typeberry/lib 0.2.0-adde0dd → 0.2.0-b525add
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 +2674 -2150
- package/index.d.ts +2145 -1909
- package/index.js +2672 -2148
- 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 {
|
|
@@ -1467,8 +1463,8 @@ declare class Decoder {
|
|
|
1467
1463
|
/**
|
|
1468
1464
|
* Create a new [`Decoder`] instance given a raw array of bytes as a source.
|
|
1469
1465
|
*/
|
|
1470
|
-
static fromBlob(source: Uint8Array) {
|
|
1471
|
-
return new Decoder(source);
|
|
1466
|
+
static fromBlob(source: Uint8Array, context?: unknown) {
|
|
1467
|
+
return new Decoder(source, undefined, context);
|
|
1472
1468
|
}
|
|
1473
1469
|
|
|
1474
1470
|
/**
|
|
@@ -1818,7 +1814,7 @@ declare class Decoder {
|
|
|
1818
1814
|
private ensureHasBytes(bytes: number) {
|
|
1819
1815
|
check`${bytes >= 0} Negative number of bytes given.`;
|
|
1820
1816
|
if (this.offset + bytes > this.source.length) {
|
|
1821
|
-
throw new
|
|
1817
|
+
throw new EndOfDataError(
|
|
1822
1818
|
`Attempting to decode more data than there is left. Need ${bytes}, left: ${this.source.length - this.offset}.`,
|
|
1823
1819
|
);
|
|
1824
1820
|
}
|
|
@@ -1837,6 +1833,8 @@ declare function decodeVariableLengthExtraBytes(firstByte: number) {
|
|
|
1837
1833
|
return 0;
|
|
1838
1834
|
}
|
|
1839
1835
|
|
|
1836
|
+
declare class EndOfDataError extends Error {}
|
|
1837
|
+
|
|
1840
1838
|
/** Hint for how big the encoded object will be. */
|
|
1841
1839
|
type SizeHint = {
|
|
1842
1840
|
/** Number of bytes in the encoding. */
|
|
@@ -2879,6 +2877,15 @@ declare namespace codec$1 {
|
|
|
2879
2877
|
};
|
|
2880
2878
|
})();
|
|
2881
2879
|
|
|
2880
|
+
/** Zero-size `void` value. */
|
|
2881
|
+
export const nothing = Descriptor.new<void>(
|
|
2882
|
+
"void",
|
|
2883
|
+
{ bytes: 0, isExact: true },
|
|
2884
|
+
(_e, _v) => {},
|
|
2885
|
+
(_d) => {},
|
|
2886
|
+
(_s) => {},
|
|
2887
|
+
);
|
|
2888
|
+
|
|
2882
2889
|
/** Variable-length U32. */
|
|
2883
2890
|
export const varU32 = Descriptor.new<U32>(
|
|
2884
2891
|
"var_u32",
|
|
@@ -3346,6 +3353,9 @@ declare function forEachDescriptor<T>(
|
|
|
3346
3353
|
try {
|
|
3347
3354
|
f(k, descriptors[k]);
|
|
3348
3355
|
} catch (e) {
|
|
3356
|
+
if (e instanceof EndOfDataError) {
|
|
3357
|
+
throw new EndOfDataError(`${key}: ${e}`);
|
|
3358
|
+
}
|
|
3349
3359
|
throw new Error(`${key}: ${e}`);
|
|
3350
3360
|
}
|
|
3351
3361
|
}
|
|
@@ -3469,6 +3479,8 @@ type index$q_DescriptorRecord<T> = DescriptorRecord<T>;
|
|
|
3469
3479
|
type index$q_Encode<T> = Encode<T>;
|
|
3470
3480
|
type index$q_Encoder = Encoder;
|
|
3471
3481
|
declare const index$q_Encoder: typeof Encoder;
|
|
3482
|
+
type index$q_EndOfDataError = EndOfDataError;
|
|
3483
|
+
declare const index$q_EndOfDataError: typeof EndOfDataError;
|
|
3472
3484
|
type index$q_LengthRange = LengthRange;
|
|
3473
3485
|
declare const index$q_MASKS: typeof MASKS;
|
|
3474
3486
|
declare const index$q_MAX_LENGTH: typeof MAX_LENGTH;
|
|
@@ -3497,7 +3509,7 @@ declare const index$q_sequenceViewVarLen: typeof sequenceViewVarLen;
|
|
|
3497
3509
|
declare const index$q_tryAsExactBytes: typeof tryAsExactBytes;
|
|
3498
3510
|
declare const index$q_validateLength: typeof validateLength;
|
|
3499
3511
|
declare namespace index$q {
|
|
3500
|
-
export { index$q_DEFAULT_START_LENGTH as DEFAULT_START_LENGTH, index$q_Decoder as Decoder, index$q_Descriptor as Descriptor, index$q_Encoder as Encoder, index$q_MASKS as MASKS, index$q_MAX_LENGTH as MAX_LENGTH, index$q_ObjectView as ObjectView, index$q_SequenceView as SequenceView, index$q_TYPICAL_DICTIONARY_LENGTH as TYPICAL_DICTIONARY_LENGTH, index$q_TYPICAL_SEQUENCE_LENGTH as TYPICAL_SEQUENCE_LENGTH, index$q_ViewField as ViewField, index$q_addSizeHints as addSizeHints, codec$1 as codec, index$q_decodeVariableLengthExtraBytes as decodeVariableLengthExtraBytes, index$q_exactHint as exactHint, index$q_forEachDescriptor as forEachDescriptor, index$q_hasUniqueView as hasUniqueView, index$q_objectView as objectView, index$q_readonlyArray as readonlyArray, index$q_sequenceViewFixLen as sequenceViewFixLen, index$q_sequenceViewVarLen as sequenceViewVarLen, index$q_tryAsExactBytes as tryAsExactBytes, index$q_validateLength as validateLength };
|
|
3512
|
+
export { index$q_DEFAULT_START_LENGTH as DEFAULT_START_LENGTH, index$q_Decoder as Decoder, index$q_Descriptor as Descriptor, index$q_Encoder as Encoder, index$q_EndOfDataError as EndOfDataError, index$q_MASKS as MASKS, index$q_MAX_LENGTH as MAX_LENGTH, index$q_ObjectView as ObjectView, index$q_SequenceView as SequenceView, index$q_TYPICAL_DICTIONARY_LENGTH as TYPICAL_DICTIONARY_LENGTH, index$q_TYPICAL_SEQUENCE_LENGTH as TYPICAL_SEQUENCE_LENGTH, index$q_ViewField as ViewField, index$q_addSizeHints as addSizeHints, codec$1 as codec, index$q_decodeVariableLengthExtraBytes as decodeVariableLengthExtraBytes, index$q_exactHint as exactHint, index$q_forEachDescriptor as forEachDescriptor, index$q_hasUniqueView as hasUniqueView, index$q_objectView as objectView, index$q_readonlyArray as readonlyArray, index$q_sequenceViewFixLen as sequenceViewFixLen, index$q_sequenceViewVarLen as sequenceViewVarLen, index$q_tryAsExactBytes as tryAsExactBytes, index$q_validateLength as validateLength };
|
|
3501
3513
|
export type { index$q_ClassConstructor as ClassConstructor, index$q_Codec as Codec, index$q_CodecRecord as CodecRecord, index$q_CodecWithView as CodecWithView, index$q_Decode as Decode, index$q_DescribedBy as DescribedBy, index$q_DescriptorRecord as DescriptorRecord, index$q_Encode as Encode, index$q_LengthRange as LengthRange, index$q_OptionalRecord as OptionalRecord, Options$1 as Options, index$q_PropertyKeys as PropertyKeys, index$q_SimpleDescriptorRecord as SimpleDescriptorRecord, index$q_SizeHint as SizeHint, index$q_ViewOf as ViewOf };
|
|
3502
3514
|
}
|
|
3503
3515
|
|
|
@@ -4263,7 +4275,7 @@ declare class SortedArray<V> implements ImmutableSortedArray<V> {
|
|
|
4263
4275
|
};
|
|
4264
4276
|
}
|
|
4265
4277
|
|
|
4266
|
-
/** Create a new
|
|
4278
|
+
/** Create a new SortedArray from two sorted collections. */
|
|
4267
4279
|
static fromTwoSortedCollections<V>(first: ImmutableSortedArray<V>, second: ImmutableSortedArray<V>) {
|
|
4268
4280
|
check`${first.comparator === second.comparator} Cannot merge arrays if they do not use the same comparator`;
|
|
4269
4281
|
const comparator = first.comparator;
|
|
@@ -5070,29 +5082,6 @@ declare const fullChainSpec = new ChainSpec({
|
|
|
5070
5082
|
maxLookupAnchorAge: tryAsU32(14_400),
|
|
5071
5083
|
});
|
|
5072
5084
|
|
|
5073
|
-
/**
|
|
5074
|
-
* Configuration object for typeberry workers.
|
|
5075
|
-
*/
|
|
5076
|
-
declare class WorkerConfig {
|
|
5077
|
-
/**
|
|
5078
|
-
* Since we loose prototypes when transferring the context,
|
|
5079
|
-
* this function is re-initializing proper types.
|
|
5080
|
-
*
|
|
5081
|
-
* TODO [ToDr] instead of doing this hack, we might prefer to pass data
|
|
5082
|
-
* between workers using JAM codec maybe?
|
|
5083
|
-
*/
|
|
5084
|
-
static reInit(config: unknown) {
|
|
5085
|
-
const { chainSpec, dbPath, omitSealVerification } = config as WorkerConfig;
|
|
5086
|
-
return new WorkerConfig(new ChainSpec(chainSpec), dbPath, omitSealVerification);
|
|
5087
|
-
}
|
|
5088
|
-
|
|
5089
|
-
constructor(
|
|
5090
|
-
public readonly chainSpec: ChainSpec,
|
|
5091
|
-
public readonly dbPath: string,
|
|
5092
|
-
public readonly omitSealVerification: boolean = false,
|
|
5093
|
-
) {}
|
|
5094
|
-
}
|
|
5095
|
-
|
|
5096
5085
|
/** Peer id. */
|
|
5097
5086
|
type PeerId = Opaque<string, "peerId">;
|
|
5098
5087
|
|
|
@@ -5124,6 +5113,17 @@ declare class Bootnode implements PeerAddress {
|
|
|
5124
5113
|
}
|
|
5125
5114
|
}
|
|
5126
5115
|
|
|
5116
|
+
/** Implemented PVM Backends names in THE SAME ORDER as enum. */
|
|
5117
|
+
declare const PvmBackendNames = ["built-in", "ananas"];
|
|
5118
|
+
|
|
5119
|
+
/** Implemented PVM Backends to choose from. */
|
|
5120
|
+
declare enum PvmBackend {
|
|
5121
|
+
/** Built-in aka. Typeberry 🫐 interpreter. */
|
|
5122
|
+
BuiltIn = 0,
|
|
5123
|
+
/** Ananas 🍍 interpreter. */
|
|
5124
|
+
Ananas = 1,
|
|
5125
|
+
}
|
|
5126
|
+
|
|
5127
5127
|
type index$m_Bootnode = Bootnode;
|
|
5128
5128
|
declare const index$m_Bootnode: typeof Bootnode;
|
|
5129
5129
|
type index$m_ChainSpec = ChainSpec;
|
|
@@ -5135,12 +5135,13 @@ declare const index$m_EST_VALIDATORS: typeof EST_VALIDATORS;
|
|
|
5135
5135
|
declare const index$m_EST_VALIDATORS_SUPER_MAJORITY: typeof EST_VALIDATORS_SUPER_MAJORITY;
|
|
5136
5136
|
type index$m_PeerAddress = PeerAddress;
|
|
5137
5137
|
type index$m_PeerId = PeerId;
|
|
5138
|
-
type index$
|
|
5139
|
-
declare const index$
|
|
5138
|
+
type index$m_PvmBackend = PvmBackend;
|
|
5139
|
+
declare const index$m_PvmBackend: typeof PvmBackend;
|
|
5140
|
+
declare const index$m_PvmBackendNames: typeof PvmBackendNames;
|
|
5140
5141
|
declare const index$m_fullChainSpec: typeof fullChainSpec;
|
|
5141
5142
|
declare const index$m_tinyChainSpec: typeof tinyChainSpec;
|
|
5142
5143
|
declare namespace index$m {
|
|
5143
|
-
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$
|
|
5144
|
+
export { index$m_Bootnode as Bootnode, index$m_ChainSpec as ChainSpec, index$m_EC_SEGMENT_SIZE as EC_SEGMENT_SIZE, index$m_EST_CORES as EST_CORES, index$m_EST_EPOCH_LENGTH as EST_EPOCH_LENGTH, index$m_EST_VALIDATORS as EST_VALIDATORS, index$m_EST_VALIDATORS_SUPER_MAJORITY as EST_VALIDATORS_SUPER_MAJORITY, index$m_PvmBackend as PvmBackend, index$m_PvmBackendNames as PvmBackendNames, index$m_fullChainSpec as fullChainSpec, index$m_tinyChainSpec as tinyChainSpec };
|
|
5144
5145
|
export type { index$m_PeerAddress as PeerAddress, index$m_PeerId as PeerId };
|
|
5145
5146
|
}
|
|
5146
5147
|
|
|
@@ -8164,6 +8165,7 @@ declare const DEFAULT_CONFIG = "default";
|
|
|
8164
8165
|
declare const NODE_DEFAULTS = {
|
|
8165
8166
|
name: isBrowser() ? "browser" : os.hostname(),
|
|
8166
8167
|
config: DEFAULT_CONFIG,
|
|
8168
|
+
pvm: PvmBackend.BuiltIn,
|
|
8167
8169
|
};
|
|
8168
8170
|
|
|
8169
8171
|
/** Chain spec chooser. */
|
|
@@ -8192,7 +8194,7 @@ declare class NodeConfiguration {
|
|
|
8192
8194
|
version: "number",
|
|
8193
8195
|
flavor: knownChainSpecFromJson,
|
|
8194
8196
|
chain_spec: JipChainSpec.fromJson,
|
|
8195
|
-
database_base_path: "string",
|
|
8197
|
+
database_base_path: json.optional("string"),
|
|
8196
8198
|
authorship: AuthorshipOptions.fromJson,
|
|
8197
8199
|
},
|
|
8198
8200
|
NodeConfiguration.new,
|
|
@@ -8202,7 +8204,7 @@ declare class NodeConfiguration {
|
|
|
8202
8204
|
if (version !== 1) {
|
|
8203
8205
|
throw new Error("Only version=1 config is supported.");
|
|
8204
8206
|
}
|
|
8205
|
-
return new NodeConfiguration($schema, version, flavor, chain_spec, database_base_path, authorship);
|
|
8207
|
+
return new NodeConfiguration($schema, version, flavor, chain_spec, database_base_path ?? undefined, authorship);
|
|
8206
8208
|
}
|
|
8207
8209
|
|
|
8208
8210
|
private constructor(
|
|
@@ -8210,7 +8212,8 @@ declare class NodeConfiguration {
|
|
|
8210
8212
|
public readonly version: number,
|
|
8211
8213
|
public readonly flavor: KnownChainSpec,
|
|
8212
8214
|
public readonly chainSpec: JipChainSpec,
|
|
8213
|
-
|
|
8215
|
+
/** If database path is not provided, we load an in-memory db. */
|
|
8216
|
+
public readonly databaseBasePath: string | undefined,
|
|
8214
8217
|
public readonly authorship: AuthorshipOptions,
|
|
8215
8218
|
) {}
|
|
8216
8219
|
}
|
|
@@ -8285,6 +8288,8 @@ interface BlocksDb {
|
|
|
8285
8288
|
* NOTE: this is not extrinsic hash!
|
|
8286
8289
|
*/
|
|
8287
8290
|
getExtrinsic(hash: HeaderHash): ExtrinsicView | null;
|
|
8291
|
+
/** Close the database and free resources. */
|
|
8292
|
+
close(): Promise<void>;
|
|
8288
8293
|
}
|
|
8289
8294
|
|
|
8290
8295
|
/** In-memory (non-persistent) blocks database. */
|
|
@@ -8343,6 +8348,8 @@ declare class InMemoryBlocks implements BlocksDb {
|
|
|
8343
8348
|
getExtrinsic(hash: HeaderHash): ExtrinsicView | null {
|
|
8344
8349
|
return this.extrinsicsByHeaderHash.get(hash) ?? null;
|
|
8345
8350
|
}
|
|
8351
|
+
|
|
8352
|
+
async close() {}
|
|
8346
8353
|
}
|
|
8347
8354
|
|
|
8348
8355
|
type StateKey$1 = Opaque<OpaqueHash, "trieStateKey">;
|
|
@@ -12251,6 +12258,18 @@ declare class StateEntries {
|
|
|
12251
12258
|
return Object.fromEntries(this.entries);
|
|
12252
12259
|
}
|
|
12253
12260
|
|
|
12261
|
+
/** Dump state entries to JSON string (format compatible with stf vectors). */
|
|
12262
|
+
toString() {
|
|
12263
|
+
return JSON.stringify(
|
|
12264
|
+
Array.from(this.entries.entries()).map(([key, value]) => ({
|
|
12265
|
+
key,
|
|
12266
|
+
value,
|
|
12267
|
+
})),
|
|
12268
|
+
null,
|
|
12269
|
+
2,
|
|
12270
|
+
);
|
|
12271
|
+
}
|
|
12272
|
+
|
|
12254
12273
|
[Symbol.iterator]() {
|
|
12255
12274
|
return this.entries[Symbol.iterator]();
|
|
12256
12275
|
}
|
|
@@ -12665,7 +12684,7 @@ interface ValuesDb {
|
|
|
12665
12684
|
* Missing value is considered an irrecoverable error, so the implementations
|
|
12666
12685
|
* are free to throw if that happens.
|
|
12667
12686
|
*/
|
|
12668
|
-
get(key:
|
|
12687
|
+
get(key: ValueHash): Uint8Array;
|
|
12669
12688
|
}
|
|
12670
12689
|
|
|
12671
12690
|
/**
|
|
@@ -12698,15 +12717,20 @@ declare class LeafDb implements SerializedStateBackend {
|
|
|
12698
12717
|
return Result.ok(new LeafDb(leaves, db));
|
|
12699
12718
|
}
|
|
12700
12719
|
|
|
12720
|
+
/** Create leaf db from sorted set of leaves. */
|
|
12721
|
+
static fromLeaves(leaves: SortedSet<LeafNode>, db: ValuesDb): LeafDb {
|
|
12722
|
+
return new LeafDb(leaves, db);
|
|
12723
|
+
}
|
|
12724
|
+
|
|
12701
12725
|
/** A mapping between an embedded value or db lookup key. */
|
|
12702
12726
|
private readonly lookup: TruncatedHashDictionary<StateKey, Lookup>;
|
|
12703
12727
|
|
|
12704
12728
|
private constructor(
|
|
12705
|
-
public readonly
|
|
12729
|
+
public readonly leafs: SortedSet<LeafNode>,
|
|
12706
12730
|
public readonly db: ValuesDb,
|
|
12707
12731
|
) {
|
|
12708
12732
|
this.lookup = TruncatedHashDictionary.fromEntries(
|
|
12709
|
-
|
|
12733
|
+
leafs.array.map((leaf) => {
|
|
12710
12734
|
const key: StateKey = leaf.getKey().asOpaque();
|
|
12711
12735
|
const value: Lookup = leaf.hasEmbeddedValue()
|
|
12712
12736
|
? {
|
|
@@ -12715,7 +12739,7 @@ declare class LeafDb implements SerializedStateBackend {
|
|
|
12715
12739
|
}
|
|
12716
12740
|
: {
|
|
12717
12741
|
kind: LookupKind.DbKey,
|
|
12718
|
-
key: leaf.getValueHash()
|
|
12742
|
+
key: leaf.getValueHash(),
|
|
12719
12743
|
};
|
|
12720
12744
|
return [key, value];
|
|
12721
12745
|
}),
|
|
@@ -12741,7 +12765,7 @@ declare class LeafDb implements SerializedStateBackend {
|
|
|
12741
12765
|
|
|
12742
12766
|
getStateRoot(blake2b: Blake2b): StateRootHash {
|
|
12743
12767
|
const blake2bTrieHasher = getBlake2bTrieHasher(blake2b);
|
|
12744
|
-
return InMemoryTrie.computeStateRoot(blake2bTrieHasher, this.
|
|
12768
|
+
return InMemoryTrie.computeStateRoot(blake2bTrieHasher, this.leafs).asOpaque();
|
|
12745
12769
|
}
|
|
12746
12770
|
|
|
12747
12771
|
intoStateEntries(): StateEntries {
|
|
@@ -12775,9 +12799,42 @@ type Lookup =
|
|
|
12775
12799
|
}
|
|
12776
12800
|
| {
|
|
12777
12801
|
kind: LookupKind.DbKey;
|
|
12778
|
-
key:
|
|
12802
|
+
key: ValueHash;
|
|
12779
12803
|
};
|
|
12780
12804
|
|
|
12805
|
+
declare function updateLeafs(
|
|
12806
|
+
leafs: SortedSet<LeafNode>,
|
|
12807
|
+
blake2b: Blake2b,
|
|
12808
|
+
data: Iterable<[StateEntryUpdateAction, StateKey | TruncatedHash, BytesBlob]>,
|
|
12809
|
+
): {
|
|
12810
|
+
values: [ValueHash, BytesBlob][];
|
|
12811
|
+
leafs: SortedSet<LeafNode>;
|
|
12812
|
+
} {
|
|
12813
|
+
const blake2bTrieHasher = getBlake2bTrieHasher(blake2b);
|
|
12814
|
+
// We will collect all values that don't fit directly into leaf nodes.
|
|
12815
|
+
const values: [ValueHash, BytesBlob][] = [];
|
|
12816
|
+
for (const [action, key, value] of data) {
|
|
12817
|
+
if (action === StateEntryUpdateAction.Insert) {
|
|
12818
|
+
const leafNode = InMemoryTrie.constructLeaf(blake2bTrieHasher, key.asOpaque(), value);
|
|
12819
|
+
leafs.replace(leafNode);
|
|
12820
|
+
if (!leafNode.hasEmbeddedValue()) {
|
|
12821
|
+
values.push([leafNode.getValueHash(), value]);
|
|
12822
|
+
}
|
|
12823
|
+
} else if (action === StateEntryUpdateAction.Remove) {
|
|
12824
|
+
const leafNode = InMemoryTrie.constructLeaf(blake2bTrieHasher, key.asOpaque(), BytesBlob.empty());
|
|
12825
|
+
leafs.removeOne(leafNode);
|
|
12826
|
+
// TODO [ToDr] Handle ref-counting values or updating some header-hash-based references.
|
|
12827
|
+
} else {
|
|
12828
|
+
assertNever(action);
|
|
12829
|
+
}
|
|
12830
|
+
}
|
|
12831
|
+
|
|
12832
|
+
return {
|
|
12833
|
+
values,
|
|
12834
|
+
leafs,
|
|
12835
|
+
};
|
|
12836
|
+
}
|
|
12837
|
+
|
|
12781
12838
|
/** A potential error that occured during state update. */
|
|
12782
12839
|
declare enum StateUpdateError {
|
|
12783
12840
|
/** A conflicting state update has been provided. */
|
|
@@ -12785,6 +12842,13 @@ declare enum StateUpdateError {
|
|
|
12785
12842
|
/** There was an error committing the changes. */
|
|
12786
12843
|
Commit = 1,
|
|
12787
12844
|
}
|
|
12845
|
+
|
|
12846
|
+
/** Interface to initialize states db. Typically used in conjunction with `StatesDb`. */
|
|
12847
|
+
interface InitStatesDb<T = State> {
|
|
12848
|
+
/** Insert a pre-defined initial state directly into the database. */
|
|
12849
|
+
insertInitialState(headerHash: HeaderHash, initialState: T): Promise<Result$2<OK, StateUpdateError>>;
|
|
12850
|
+
}
|
|
12851
|
+
|
|
12788
12852
|
/**
|
|
12789
12853
|
* Interface for accessing states stored in the database.
|
|
12790
12854
|
*
|
|
@@ -12810,12 +12874,18 @@ interface StatesDb<T extends State = State> {
|
|
|
12810
12874
|
|
|
12811
12875
|
/** Retrieve posterior state of given header. */
|
|
12812
12876
|
getState(header: HeaderHash): T | null;
|
|
12877
|
+
|
|
12878
|
+
/** Close the database and free resources. */
|
|
12879
|
+
close(): Promise<void>;
|
|
12813
12880
|
}
|
|
12814
12881
|
|
|
12815
12882
|
declare class InMemoryStates implements StatesDb<InMemoryState> {
|
|
12816
|
-
private readonly db: HashDictionary<HeaderHash,
|
|
12883
|
+
private readonly db: HashDictionary<HeaderHash, InMemoryState> = HashDictionary.new();
|
|
12884
|
+
private readonly blake2b: Promise<Blake2b>;
|
|
12817
12885
|
|
|
12818
|
-
constructor(private readonly spec: ChainSpec) {
|
|
12886
|
+
constructor(private readonly spec: ChainSpec) {
|
|
12887
|
+
this.blake2b = Blake2b.createHasher();
|
|
12888
|
+
}
|
|
12819
12889
|
|
|
12820
12890
|
async updateAndSetState(
|
|
12821
12891
|
headerHash: HeaderHash,
|
|
@@ -12824,7 +12894,7 @@ declare class InMemoryStates implements StatesDb<InMemoryState> {
|
|
|
12824
12894
|
): Promise<Result$2<OK, StateUpdateError>> {
|
|
12825
12895
|
const res = state.applyUpdate(update);
|
|
12826
12896
|
if (res.isOk) {
|
|
12827
|
-
return await this.
|
|
12897
|
+
return await this.insertInitialState(headerHash, state);
|
|
12828
12898
|
}
|
|
12829
12899
|
|
|
12830
12900
|
switch (res.error) {
|
|
@@ -12838,32 +12908,126 @@ declare class InMemoryStates implements StatesDb<InMemoryState> {
|
|
|
12838
12908
|
}
|
|
12839
12909
|
|
|
12840
12910
|
async getStateRoot(state: InMemoryState): Promise<StateRootHash> {
|
|
12841
|
-
const blake2b = await
|
|
12911
|
+
const blake2b = await this.blake2b;
|
|
12842
12912
|
return StateEntries.serializeInMemory(this.spec, blake2b, state).getRootHash(blake2b);
|
|
12843
12913
|
}
|
|
12844
12914
|
|
|
12845
12915
|
/** Insert a full state into the database. */
|
|
12846
|
-
async
|
|
12847
|
-
const
|
|
12848
|
-
this.db.set(headerHash,
|
|
12916
|
+
async insertInitialState(headerHash: HeaderHash, state: InMemoryState): Promise<Result$2<OK, StateUpdateError>> {
|
|
12917
|
+
const copy = InMemoryState.copyFrom(this.spec, state, state.intoServicesData());
|
|
12918
|
+
this.db.set(headerHash, copy);
|
|
12849
12919
|
return Result.ok(OK);
|
|
12850
12920
|
}
|
|
12851
12921
|
|
|
12852
12922
|
getState(headerHash: HeaderHash): InMemoryState | null {
|
|
12853
|
-
const
|
|
12854
|
-
if (
|
|
12923
|
+
const state = this.db.get(headerHash);
|
|
12924
|
+
if (state === undefined) {
|
|
12855
12925
|
return null;
|
|
12856
12926
|
}
|
|
12857
12927
|
|
|
12858
|
-
return
|
|
12928
|
+
return InMemoryState.copyFrom(this.spec, state, state.intoServicesData());
|
|
12929
|
+
}
|
|
12930
|
+
|
|
12931
|
+
async close() {}
|
|
12932
|
+
}
|
|
12933
|
+
|
|
12934
|
+
/** Root database. */
|
|
12935
|
+
interface RootDb<TBlocks = BlocksDb, TStates = StatesDb> {
|
|
12936
|
+
/** Blocks DB. */
|
|
12937
|
+
getBlocksDb(): TBlocks;
|
|
12938
|
+
|
|
12939
|
+
/** States DB. */
|
|
12940
|
+
getStatesDb(): TStates;
|
|
12941
|
+
|
|
12942
|
+
/** Close access to the DB. */
|
|
12943
|
+
close(): Promise<void>;
|
|
12944
|
+
}
|
|
12945
|
+
|
|
12946
|
+
/** Abstract serialized-states db. */
|
|
12947
|
+
type SerializedStatesDb = StatesDb<SerializedState<LeafDb>> & InitStatesDb<StateEntries>;
|
|
12948
|
+
|
|
12949
|
+
/** In-memory serialized-states db. */
|
|
12950
|
+
declare class InMemorySerializedStates implements StatesDb<SerializedState<LeafDb>>, InitStatesDb<StateEntries> {
|
|
12951
|
+
private readonly db: HashDictionary<HeaderHash, SortedSet<LeafNode>> = HashDictionary.new();
|
|
12952
|
+
private readonly valuesDb: HashDictionary<ValueHash, BytesBlob> = HashDictionary.new();
|
|
12953
|
+
|
|
12954
|
+
constructor(
|
|
12955
|
+
private readonly spec: ChainSpec,
|
|
12956
|
+
private readonly blake2b: Blake2b,
|
|
12957
|
+
) {}
|
|
12958
|
+
|
|
12959
|
+
async insertInitialState(headerHash: HeaderHash, entries: StateEntries): Promise<Result$2<OK, StateUpdateError>> {
|
|
12960
|
+
// convert state entries into leafdb
|
|
12961
|
+
const { values, leafs } = updateLeafs(
|
|
12962
|
+
SortedSet.fromArray(leafComparator, []),
|
|
12963
|
+
this.blake2b,
|
|
12964
|
+
Array.from(entries, (x) => [StateEntryUpdateAction.Insert, x[0], x[1]]),
|
|
12965
|
+
);
|
|
12966
|
+
|
|
12967
|
+
// insert values to the db.
|
|
12968
|
+
for (const val of values) {
|
|
12969
|
+
this.valuesDb.set(val[0], val[1]);
|
|
12970
|
+
}
|
|
12971
|
+
|
|
12972
|
+
this.db.set(headerHash, leafs);
|
|
12973
|
+
return Result.ok(OK);
|
|
12974
|
+
}
|
|
12975
|
+
|
|
12976
|
+
async getStateRoot(state: SerializedState<LeafDb>): Promise<StateRootHash> {
|
|
12977
|
+
return state.backend.getStateRoot(this.blake2b);
|
|
12978
|
+
}
|
|
12979
|
+
|
|
12980
|
+
async updateAndSetState(
|
|
12981
|
+
header: HeaderHash,
|
|
12982
|
+
state: SerializedState<LeafDb>,
|
|
12983
|
+
update: Partial<State & ServicesUpdate>,
|
|
12984
|
+
): Promise<Result$2<OK, StateUpdateError>> {
|
|
12985
|
+
const blake2b = this.blake2b;
|
|
12986
|
+
const updatedValues = serializeStateUpdate(this.spec, blake2b, update);
|
|
12987
|
+
const { values, leafs } = updateLeafs(state.backend.leafs, blake2b, updatedValues);
|
|
12988
|
+
|
|
12989
|
+
// insert values to the db
|
|
12990
|
+
// valuesdb can be shared between all states because it's just
|
|
12991
|
+
// <valuehash> -> <value> mapping and existence is managed by trie leafs.
|
|
12992
|
+
for (const val of values) {
|
|
12993
|
+
this.valuesDb.set(val[0], val[1]);
|
|
12994
|
+
}
|
|
12995
|
+
|
|
12996
|
+
// make sure to clone the leafs before writing, since the collection is re-used.
|
|
12997
|
+
this.db.set(header, SortedSet.fromSortedArray(leafComparator, leafs.slice()));
|
|
12998
|
+
|
|
12999
|
+
return Result.ok(OK);
|
|
13000
|
+
}
|
|
13001
|
+
|
|
13002
|
+
getState(header: HeaderHash): SerializedState<LeafDb> | null {
|
|
13003
|
+
const leafs = this.db.get(header);
|
|
13004
|
+
if (leafs === undefined) {
|
|
13005
|
+
return null;
|
|
13006
|
+
}
|
|
13007
|
+
// now create a leafdb with shared values db.
|
|
13008
|
+
const leafDb = LeafDb.fromLeaves(leafs, {
|
|
13009
|
+
get: (key: ValueHash) => {
|
|
13010
|
+
const val = this.valuesDb.get(key);
|
|
13011
|
+
if (val === undefined) {
|
|
13012
|
+
throw new Error(`Missing value at key: ${key}`);
|
|
13013
|
+
}
|
|
13014
|
+
return val.raw;
|
|
13015
|
+
},
|
|
13016
|
+
});
|
|
13017
|
+
return SerializedState.new(this.spec, this.blake2b, leafDb);
|
|
12859
13018
|
}
|
|
13019
|
+
|
|
13020
|
+
async close() {}
|
|
12860
13021
|
}
|
|
12861
13022
|
|
|
12862
13023
|
type index$c_BlocksDb = BlocksDb;
|
|
12863
13024
|
type index$c_InMemoryBlocks = InMemoryBlocks;
|
|
12864
13025
|
declare const index$c_InMemoryBlocks: typeof InMemoryBlocks;
|
|
13026
|
+
type index$c_InMemorySerializedStates = InMemorySerializedStates;
|
|
13027
|
+
declare const index$c_InMemorySerializedStates: typeof InMemorySerializedStates;
|
|
12865
13028
|
type index$c_InMemoryStates = InMemoryStates;
|
|
12866
13029
|
declare const index$c_InMemoryStates: typeof InMemoryStates;
|
|
13030
|
+
type index$c_InitStatesDb<T = State> = InitStatesDb<T>;
|
|
12867
13031
|
type index$c_LeafDb = LeafDb;
|
|
12868
13032
|
declare const index$c_LeafDb: typeof LeafDb;
|
|
12869
13033
|
type index$c_LeafDbError = LeafDbError;
|
|
@@ -12871,13 +13035,16 @@ declare const index$c_LeafDbError: typeof LeafDbError;
|
|
|
12871
13035
|
type index$c_Lookup = Lookup;
|
|
12872
13036
|
type index$c_LookupKind = LookupKind;
|
|
12873
13037
|
declare const index$c_LookupKind: typeof LookupKind;
|
|
13038
|
+
type index$c_RootDb<TBlocks = BlocksDb, TStates = StatesDb> = RootDb<TBlocks, TStates>;
|
|
13039
|
+
type index$c_SerializedStatesDb = SerializedStatesDb;
|
|
12874
13040
|
type index$c_StateUpdateError = StateUpdateError;
|
|
12875
13041
|
declare const index$c_StateUpdateError: typeof StateUpdateError;
|
|
12876
13042
|
type index$c_StatesDb<T extends State = State> = StatesDb<T>;
|
|
12877
13043
|
type index$c_ValuesDb = ValuesDb;
|
|
13044
|
+
declare const index$c_updateLeafs: typeof updateLeafs;
|
|
12878
13045
|
declare namespace index$c {
|
|
12879
|
-
export { index$c_InMemoryBlocks as InMemoryBlocks, index$c_InMemoryStates as InMemoryStates, index$c_LeafDb as LeafDb, index$c_LeafDbError as LeafDbError, index$c_LookupKind as LookupKind, index$c_StateUpdateError as StateUpdateError };
|
|
12880
|
-
export type { index$c_BlocksDb as BlocksDb, index$c_Lookup as Lookup, index$c_StatesDb as StatesDb, index$c_ValuesDb as ValuesDb };
|
|
13046
|
+
export { index$c_InMemoryBlocks as InMemoryBlocks, index$c_InMemorySerializedStates as InMemorySerializedStates, index$c_InMemoryStates as InMemoryStates, index$c_LeafDb as LeafDb, index$c_LeafDbError as LeafDbError, index$c_LookupKind as LookupKind, index$c_StateUpdateError as StateUpdateError, index$c_updateLeafs as updateLeafs };
|
|
13047
|
+
export type { index$c_BlocksDb as BlocksDb, index$c_InitStatesDb as InitStatesDb, index$c_Lookup as Lookup, index$c_RootDb as RootDb, index$c_SerializedStatesDb as SerializedStatesDb, index$c_StatesDb as StatesDb, index$c_ValuesDb as ValuesDb };
|
|
12881
13048
|
}
|
|
12882
13049
|
|
|
12883
13050
|
/**
|
|
@@ -14178,48 +14345,133 @@ declare class PendingTransfer {
|
|
|
14178
14345
|
}
|
|
14179
14346
|
}
|
|
14180
14347
|
|
|
14181
|
-
/** Gas measuring type. Can be either U64 or U32 for performance reasons. */
|
|
14182
|
-
type Gas = BigGas | SmallGas;
|
|
14183
14348
|
/** A U64 version of `Gas`. */
|
|
14184
14349
|
type BigGas = Opaque<U64, "BigGas[U64]">;
|
|
14185
14350
|
/** A U32 version of `Gas`. */
|
|
14186
14351
|
type SmallGas = Opaque<U32, "SmallGas[U32]">;
|
|
14187
|
-
|
|
14188
|
-
|
|
14189
|
-
declare const tryAsSmallGas = (v: number): SmallGas => asOpaqueType(tryAsU32(v));
|
|
14190
|
-
|
|
14191
|
-
/** Attempt to convert given number into U64 gas representation. */
|
|
14192
|
-
declare const tryAsBigGas = (v: number | bigint): BigGas => asOpaqueType(tryAsU64(v));
|
|
14193
|
-
|
|
14194
|
-
/** Attempt to convert given number into gas. */
|
|
14195
|
-
declare const tryAsGas = (v: number | bigint): Gas =>
|
|
14196
|
-
typeof v === "number" && v < 2 ** 32 ? tryAsSmallGas(v) : tryAsBigGas(v);
|
|
14197
|
-
|
|
14198
|
-
/** Create a new gas counter instance depending on the gas value. */
|
|
14199
|
-
declare function gasCounter(gas: Gas): GasCounter {
|
|
14200
|
-
return new GasCounterU64(tryAsU64(gas));
|
|
14201
|
-
}
|
|
14352
|
+
/** Gas measuring type. Can be either U64 or U32 for performance reasons. */
|
|
14353
|
+
type Gas = BigGas | SmallGas;
|
|
14202
14354
|
|
|
14203
14355
|
/** An abstraction over gas counter.
|
|
14204
14356
|
*
|
|
14205
14357
|
* It can be optimized to use numbers instead of bigint in case of small gas.
|
|
14206
14358
|
*/
|
|
14207
|
-
interface
|
|
14359
|
+
interface IGasCounter {
|
|
14360
|
+
/**
|
|
14361
|
+
* Set during initialization of GasCounter.
|
|
14362
|
+
*
|
|
14363
|
+
* NOTE: Needed to calculate `used()` gas.
|
|
14364
|
+
*/
|
|
14365
|
+
initialGas: Gas;
|
|
14366
|
+
|
|
14208
14367
|
/** Return remaining gas. */
|
|
14209
14368
|
get(): Gas;
|
|
14210
14369
|
|
|
14211
|
-
/**
|
|
14370
|
+
/**
|
|
14371
|
+
* Overwrite remaining gas.
|
|
14372
|
+
*
|
|
14373
|
+
* NOTE: Could cause `used()` gas calculation to be incorrect.
|
|
14374
|
+
*
|
|
14375
|
+
* @see
|
|
14376
|
+
* Prefer sub method instead.
|
|
14377
|
+
*/
|
|
14212
14378
|
set(g: Gas): void;
|
|
14213
14379
|
|
|
14214
14380
|
/** Returns true if there was an underflow. */
|
|
14215
14381
|
sub(g: Gas): boolean;
|
|
14382
|
+
|
|
14383
|
+
/**
|
|
14384
|
+
* Calculates used gas since creation of GasCounter.
|
|
14385
|
+
*
|
|
14386
|
+
* The interface does not handle negative or more than `initialGas` values.
|
|
14387
|
+
*
|
|
14388
|
+
* NOTE: We can use at most `initialGas` and as little as `0`.
|
|
14389
|
+
*/
|
|
14390
|
+
used(): Gas;
|
|
14391
|
+
}
|
|
14392
|
+
|
|
14393
|
+
type PageFault$1 = {
|
|
14394
|
+
address: U32;
|
|
14395
|
+
};
|
|
14396
|
+
|
|
14397
|
+
/** Allows store and read segments of memory. */
|
|
14398
|
+
interface IMemory {
|
|
14399
|
+
/** Store bytes into memory at given address. */
|
|
14400
|
+
store(address: U32, bytes: Uint8Array): Result$2<OK, PageFault$1>;
|
|
14401
|
+
|
|
14402
|
+
/** Load bytes from memory from given address into given buffer. */
|
|
14403
|
+
read(address: U32, result: Uint8Array): Result$2<OK, PageFault$1>;
|
|
14216
14404
|
}
|
|
14217
14405
|
|
|
14218
14406
|
declare const NO_OF_REGISTERS$1 = 13;
|
|
14219
14407
|
|
|
14408
|
+
/** Allow to set and get all registers encoded into little-endian bytes. */
|
|
14409
|
+
interface IRegisters {
|
|
14410
|
+
/**
|
|
14411
|
+
* Get all registers encoded into little-endian bytes.
|
|
14412
|
+
*
|
|
14413
|
+
* NOTE: Total length of bytes must be NO_OF_REGISTERS * REGISTER_BYTE_SIZE.
|
|
14414
|
+
*/
|
|
14415
|
+
getAllEncoded(): Uint8Array;
|
|
14416
|
+
/**
|
|
14417
|
+
* Set all registers from little-endian encoded bytes.
|
|
14418
|
+
*
|
|
14419
|
+
* NOTE: Total length of bytes must be NO_OF_REGISTERS * REGISTER_BYTE_SIZE.
|
|
14420
|
+
*/
|
|
14421
|
+
setAllEncoded(bytes: Uint8Array): void;
|
|
14422
|
+
}
|
|
14423
|
+
|
|
14424
|
+
/**
|
|
14425
|
+
* Result codes for the PVM execution.
|
|
14426
|
+
*
|
|
14427
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/2e43002e4300?v=0.7.2
|
|
14428
|
+
*/
|
|
14429
|
+
declare enum Status {
|
|
14430
|
+
/** Continue */
|
|
14431
|
+
OK = 255,
|
|
14432
|
+
/** Finished */
|
|
14433
|
+
HALT = 0,
|
|
14434
|
+
/** Panic */
|
|
14435
|
+
PANIC = 1,
|
|
14436
|
+
/** Page-fault */
|
|
14437
|
+
FAULT = 2,
|
|
14438
|
+
/** Host-call */
|
|
14439
|
+
HOST = 3,
|
|
14440
|
+
/** Out of gas */
|
|
14441
|
+
OOG = 4,
|
|
14442
|
+
}
|
|
14443
|
+
|
|
14444
|
+
interface IPvmInterpreter {
|
|
14445
|
+
/** Manipulate gas. */
|
|
14446
|
+
readonly gas: IGasCounter;
|
|
14447
|
+
|
|
14448
|
+
/** Manipulate registers. */
|
|
14449
|
+
readonly registers: IRegisters;
|
|
14450
|
+
|
|
14451
|
+
/** Manipulate memory. */
|
|
14452
|
+
readonly memory: IMemory;
|
|
14453
|
+
|
|
14454
|
+
/** Prepare SPI program to be executed. */
|
|
14455
|
+
resetJam(program: Uint8Array, args: Uint8Array, pc: number, gas: Gas): void;
|
|
14456
|
+
|
|
14457
|
+
/** Execute loaded program. */
|
|
14458
|
+
runProgram(): void;
|
|
14459
|
+
|
|
14460
|
+
/** Get current Status. */
|
|
14461
|
+
getStatus(): Status;
|
|
14462
|
+
|
|
14463
|
+
/** Get current Program Counter. */
|
|
14464
|
+
getPC(): number;
|
|
14465
|
+
|
|
14466
|
+
/** Get exit args. Needed in case of HOST or FAULT. */
|
|
14467
|
+
getExitParam(): U32 | null;
|
|
14468
|
+
}
|
|
14469
|
+
|
|
14470
|
+
// x << 3 === x * 8
|
|
14471
|
+
|
|
14220
14472
|
type RegisterIndex = Opaque<number, "register index">;
|
|
14221
14473
|
|
|
14222
|
-
declare class Registers {
|
|
14474
|
+
declare class Registers implements IRegisters {
|
|
14223
14475
|
private asSigned: BigInt64Array;
|
|
14224
14476
|
private asUnsigned: BigUint64Array;
|
|
14225
14477
|
|
|
@@ -14229,6 +14481,15 @@ declare class Registers {
|
|
|
14229
14481
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14230
14482
|
}
|
|
14231
14483
|
|
|
14484
|
+
getAllEncoded(): Uint8Array {
|
|
14485
|
+
return this.bytes;
|
|
14486
|
+
}
|
|
14487
|
+
|
|
14488
|
+
setAllEncoded(bytes: Uint8Array): void {
|
|
14489
|
+
check`${bytes.length === this.bytes.length} Incorrect size of input registers. Got: ${bytes.length}, need: ${this.bytes.length}`;
|
|
14490
|
+
this.bytes.set(bytes, 0);
|
|
14491
|
+
}
|
|
14492
|
+
|
|
14232
14493
|
static fromBytes(bytes: Uint8Array) {
|
|
14233
14494
|
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14234
14495
|
return new Registers(bytes);
|
|
@@ -14239,10 +14500,6 @@ declare class Registers {
|
|
|
14239
14500
|
return this.bytes.subarray(offset, offset + len);
|
|
14240
14501
|
}
|
|
14241
14502
|
|
|
14242
|
-
getAllBytesAsLittleEndian() {
|
|
14243
|
-
return this.bytes;
|
|
14244
|
-
}
|
|
14245
|
-
|
|
14246
14503
|
copyFrom(regs: Registers | BigUint64Array) {
|
|
14247
14504
|
const array = regs instanceof BigUint64Array ? regs : regs.asUnsigned;
|
|
14248
14505
|
this.asUnsigned.set(array);
|
|
@@ -14291,1493 +14548,1856 @@ declare class Registers {
|
|
|
14291
14548
|
}
|
|
14292
14549
|
}
|
|
14293
14550
|
|
|
14294
|
-
|
|
14295
|
-
|
|
14296
|
-
|
|
14297
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/237201239801
|
|
14298
|
-
*/
|
|
14299
|
-
declare class Mask {
|
|
14551
|
+
declare class HostCallMemory {
|
|
14552
|
+
constructor(private readonly memory: IMemory) {}
|
|
14553
|
+
|
|
14300
14554
|
/**
|
|
14301
|
-
*
|
|
14302
|
-
* In case the value is non-zero it signifies the offset to the index with next instruction.
|
|
14555
|
+
* Save some bytes into memory under given address.
|
|
14303
14556
|
*
|
|
14304
|
-
*
|
|
14305
|
-
*
|
|
14306
|
-
* 0..1..2..3..4..5..6..7..8..9 # Indices
|
|
14307
|
-
* 0..2..1..0..1..0..3..2..1..0 # lookupTable forward values
|
|
14308
|
-
* ```
|
|
14309
|
-
* There are instructions at indices `0, 3, 5, 9`.
|
|
14557
|
+
* NOTE: Given address is U64 (pure register value),
|
|
14558
|
+
* but we use only lower 32-bits.
|
|
14310
14559
|
*/
|
|
14311
|
-
|
|
14312
|
-
|
|
14313
|
-
|
|
14314
|
-
|
|
14315
|
-
}
|
|
14316
|
-
|
|
14317
|
-
isInstruction(index: number) {
|
|
14318
|
-
return this.lookupTableForward[index] === 0;
|
|
14319
|
-
}
|
|
14560
|
+
storeFrom(regAddress: U64, bytes: Uint8Array): Result$2<OK, PageFault$1> {
|
|
14561
|
+
if (bytes.length === 0) {
|
|
14562
|
+
return Result.ok(OK);
|
|
14563
|
+
}
|
|
14320
14564
|
|
|
14321
|
-
|
|
14322
|
-
|
|
14323
|
-
|
|
14565
|
+
// NOTE: We always take lower 32 bits from register value.
|
|
14566
|
+
//
|
|
14567
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
14568
|
+
const address = tryAsU32(Number(regAddress & 0xffff_ffffn));
|
|
14569
|
+
return this.memory.store(address, bytes);
|
|
14324
14570
|
}
|
|
14325
14571
|
|
|
14326
|
-
|
|
14327
|
-
|
|
14328
|
-
|
|
14329
|
-
|
|
14330
|
-
|
|
14331
|
-
|
|
14332
|
-
|
|
14333
|
-
|
|
14334
|
-
|
|
14335
|
-
table[i] = lastInstructionOffset;
|
|
14572
|
+
/**
|
|
14573
|
+
* Read some bytes from memory under given address.
|
|
14574
|
+
*
|
|
14575
|
+
* NOTE: Given address is U64 (pure register value),
|
|
14576
|
+
* but we use only lower 32-bits.
|
|
14577
|
+
*/
|
|
14578
|
+
loadInto(output: Uint8Array, regAddress: U64): Result$2<OK, PageFault$1> {
|
|
14579
|
+
if (output.length === 0) {
|
|
14580
|
+
return Result.ok(OK);
|
|
14336
14581
|
}
|
|
14337
|
-
return table;
|
|
14338
|
-
}
|
|
14339
14582
|
|
|
14340
|
-
|
|
14341
|
-
|
|
14583
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/25ed0025ed00?v=0.7.2
|
|
14584
|
+
//
|
|
14585
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
14586
|
+
const address = tryAsU32(Number(regAddress & 0xffff_ffffn));
|
|
14587
|
+
return this.memory.read(address, output);
|
|
14342
14588
|
}
|
|
14343
14589
|
}
|
|
14344
14590
|
|
|
14345
|
-
declare
|
|
14346
|
-
|
|
14347
|
-
ONE_IMMEDIATE = 1,
|
|
14348
|
-
TWO_IMMEDIATES = 2,
|
|
14349
|
-
ONE_OFFSET = 3,
|
|
14350
|
-
ONE_REGISTER_ONE_IMMEDIATE = 4,
|
|
14351
|
-
ONE_REGISTER_TWO_IMMEDIATES = 5,
|
|
14352
|
-
ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET = 6,
|
|
14353
|
-
TWO_REGISTERS = 7,
|
|
14354
|
-
TWO_REGISTERS_ONE_IMMEDIATE = 8,
|
|
14355
|
-
TWO_REGISTERS_ONE_OFFSET = 9,
|
|
14356
|
-
TWO_REGISTERS_TWO_IMMEDIATES = 10,
|
|
14357
|
-
THREE_REGISTERS = 11,
|
|
14358
|
-
ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE = 12,
|
|
14359
|
-
}
|
|
14360
|
-
|
|
14361
|
-
declare class ExtendedWitdthImmediateDecoder {
|
|
14362
|
-
private unsignedImmediate: BigUint64Array;
|
|
14363
|
-
private bytes: Uint8Array;
|
|
14591
|
+
declare class HostCallRegisters {
|
|
14592
|
+
private readonly registers: DataView;
|
|
14364
14593
|
|
|
14365
|
-
constructor() {
|
|
14366
|
-
|
|
14367
|
-
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
14368
|
-
this.bytes = new Uint8Array(buffer);
|
|
14594
|
+
constructor(private readonly bytes: Uint8Array) {
|
|
14595
|
+
this.registers = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
14369
14596
|
}
|
|
14370
14597
|
|
|
14371
|
-
|
|
14372
|
-
|
|
14373
|
-
|
|
14374
|
-
this.bytes[i] = bytes[i];
|
|
14375
|
-
}
|
|
14376
|
-
|
|
14377
|
-
for (; i < IMMEDIATE_SIZE; i++) {
|
|
14378
|
-
this.bytes[i] = 0;
|
|
14379
|
-
}
|
|
14598
|
+
/** Get U64 register value. */
|
|
14599
|
+
get(registerIndex: number): U64 {
|
|
14600
|
+
return tryAsU64(this.registers.getBigUint64(registerIndex * REGISTER_BYTE_SIZE, true));
|
|
14380
14601
|
}
|
|
14381
14602
|
|
|
14382
|
-
|
|
14383
|
-
|
|
14603
|
+
/** Set U64 register value. */
|
|
14604
|
+
set(registerIndex: number, value: U64) {
|
|
14605
|
+
this.registers.setBigUint64(registerIndex * REGISTER_BYTE_SIZE, value, true);
|
|
14384
14606
|
}
|
|
14385
14607
|
|
|
14386
|
-
|
|
14387
|
-
|
|
14608
|
+
/** Get all registers encoded into little-endian bytes. */
|
|
14609
|
+
getEncoded(): Uint8Array {
|
|
14610
|
+
return this.bytes;
|
|
14388
14611
|
}
|
|
14389
14612
|
}
|
|
14390
14613
|
|
|
14391
|
-
|
|
14392
|
-
|
|
14393
|
-
|
|
14394
|
-
|
|
14395
|
-
private i64: BigInt64Array;
|
|
14396
|
-
private view: DataView;
|
|
14397
|
-
private bytes: Uint8Array;
|
|
14398
|
-
|
|
14399
|
-
constructor() {
|
|
14400
|
-
const buffer = new ArrayBuffer(BUFFER_SIZE);
|
|
14401
|
-
this.u32 = new Uint32Array(buffer);
|
|
14402
|
-
this.i32 = new Int32Array(buffer);
|
|
14403
|
-
this.u64 = new BigUint64Array(buffer);
|
|
14404
|
-
this.i64 = new BigInt64Array(buffer);
|
|
14405
|
-
this.view = new DataView(buffer);
|
|
14406
|
-
this.bytes = new Uint8Array(buffer);
|
|
14407
|
-
}
|
|
14614
|
+
/** Strictly-typed host call index. */
|
|
14615
|
+
type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
14616
|
+
/** Attempt to convert a number into `HostCallIndex`. */
|
|
14617
|
+
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
14408
14618
|
|
|
14409
|
-
|
|
14410
|
-
|
|
14411
|
-
|
|
14412
|
-
|
|
14413
|
-
|
|
14619
|
+
/**
|
|
14620
|
+
* Host-call exit reason.
|
|
14621
|
+
*
|
|
14622
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
14623
|
+
*/
|
|
14624
|
+
declare enum PvmExecution {
|
|
14625
|
+
Halt = 0,
|
|
14626
|
+
Panic = 1,
|
|
14627
|
+
OOG = 2, // out-of-gas
|
|
14628
|
+
}
|
|
14414
14629
|
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14630
|
+
/** A utility function to easily trace a bunch of registers. */
|
|
14631
|
+
declare function traceRegisters(...regs: number[]) {
|
|
14632
|
+
return regs.map(tryAsRegisterIndex);
|
|
14633
|
+
}
|
|
14418
14634
|
|
|
14419
|
-
|
|
14420
|
-
|
|
14421
|
-
|
|
14422
|
-
|
|
14635
|
+
/** An interface for a host call implementation */
|
|
14636
|
+
interface HostCallHandler {
|
|
14637
|
+
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
14638
|
+
readonly index: HostCallIndex;
|
|
14423
14639
|
|
|
14424
14640
|
/**
|
|
14425
|
-
*
|
|
14641
|
+
* The gas cost of invocation of that host call.
|
|
14642
|
+
*
|
|
14643
|
+
* NOTE: `((reg: HostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
14426
14644
|
*/
|
|
14427
|
-
|
|
14428
|
-
|
|
14429
|
-
|
|
14645
|
+
readonly basicGasCost: SmallGas | ((reg: HostCallRegisters) => Gas);
|
|
14646
|
+
|
|
14647
|
+
/** Currently executing service id. */
|
|
14648
|
+
readonly currentServiceId: U32;
|
|
14649
|
+
|
|
14650
|
+
/** Input&Output registers that we should add to tracing log. */
|
|
14651
|
+
readonly tracedRegisters: RegisterIndex[];
|
|
14430
14652
|
|
|
14431
14653
|
/**
|
|
14432
|
-
*
|
|
14654
|
+
* Actually execute the host call.
|
|
14655
|
+
*
|
|
14656
|
+
* NOTE the call is ALLOWED and expected to modify registers and memory.
|
|
14433
14657
|
*/
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
}
|
|
14658
|
+
execute(gas: IGasCounter, regs: HostCallRegisters, memory: HostCallMemory): Promise<undefined | PvmExecution>;
|
|
14659
|
+
}
|
|
14437
14660
|
|
|
14438
|
-
|
|
14439
|
-
|
|
14440
|
-
|
|
14661
|
+
/** Container for all available host calls. */
|
|
14662
|
+
declare class HostCallsManager {
|
|
14663
|
+
private readonly hostCalls = new Map<HostCallIndex, HostCallHandler>();
|
|
14664
|
+
private readonly missing;
|
|
14441
14665
|
|
|
14442
|
-
|
|
14443
|
-
|
|
14666
|
+
constructor({
|
|
14667
|
+
missing,
|
|
14668
|
+
handlers = [],
|
|
14669
|
+
}: {
|
|
14670
|
+
missing: HostCallHandler;
|
|
14671
|
+
handlers?: HostCallHandler[];
|
|
14672
|
+
}) {
|
|
14673
|
+
this.missing = missing;
|
|
14674
|
+
|
|
14675
|
+
for (const handler of handlers) {
|
|
14676
|
+
check`${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
14677
|
+
this.hostCalls.set(handler.index, handler);
|
|
14678
|
+
}
|
|
14444
14679
|
}
|
|
14445
14680
|
|
|
14446
|
-
|
|
14447
|
-
|
|
14681
|
+
/** Get a host call by index. */
|
|
14682
|
+
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
14683
|
+
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
14448
14684
|
}
|
|
14449
14685
|
|
|
14450
|
-
|
|
14451
|
-
|
|
14686
|
+
traceHostCall(
|
|
14687
|
+
context: string,
|
|
14688
|
+
hostCallIndex: HostCallIndex,
|
|
14689
|
+
hostCallHandler: HostCallHandler,
|
|
14690
|
+
registers: HostCallRegisters,
|
|
14691
|
+
gas: Gas,
|
|
14692
|
+
) {
|
|
14693
|
+
const { currentServiceId } = hostCallHandler;
|
|
14694
|
+
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
14695
|
+
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
14696
|
+
const registerValues = hostCallHandler.tracedRegisters
|
|
14697
|
+
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
14698
|
+
.filter((v) => v[1] !== 0n)
|
|
14699
|
+
.map(([idx, value]) => {
|
|
14700
|
+
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
14701
|
+
})
|
|
14702
|
+
.join(", ");
|
|
14703
|
+
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
14452
14704
|
}
|
|
14705
|
+
}
|
|
14453
14706
|
|
|
14454
|
-
|
|
14455
|
-
|
|
14707
|
+
/** Create a new gas counter instance depending on the gas value. */
|
|
14708
|
+
declare function gasCounter(gas: Gas): IGasCounter {
|
|
14709
|
+
return new GasCounterU64(tryAsU64(gas));
|
|
14710
|
+
}
|
|
14711
|
+
|
|
14712
|
+
type MemoryIndex = Opaque<number, "memory index">;
|
|
14713
|
+
|
|
14714
|
+
declare const tryAsMemoryIndex = (index: number): MemoryIndex => {
|
|
14715
|
+
check`${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
14716
|
+
return asOpaqueType(index);
|
|
14717
|
+
};
|
|
14718
|
+
|
|
14719
|
+
type SbrkIndex = Opaque<number, "sbrk index">;
|
|
14720
|
+
|
|
14721
|
+
declare const tryAsSbrkIndex = (index: number): SbrkIndex => {
|
|
14722
|
+
check`${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
14723
|
+
return asOpaqueType(index);
|
|
14724
|
+
};
|
|
14725
|
+
|
|
14726
|
+
type PageIndex = Opaque<number, "memory page index">;
|
|
14727
|
+
type PageNumber = Opaque<number, "memory page number">;
|
|
14728
|
+
|
|
14729
|
+
declare class PageFault implements PageFault$1 {
|
|
14730
|
+
private constructor(
|
|
14731
|
+
public address: U32,
|
|
14732
|
+
public isAccessFault = true,
|
|
14733
|
+
) {}
|
|
14734
|
+
|
|
14735
|
+
static fromPageNumber(maybePageNumber: number, isAccessFault = false) {
|
|
14736
|
+
const pageNumber = tryAsPageNumber(maybePageNumber);
|
|
14737
|
+
const startPageIndex = getStartPageIndexFromPageNumber(pageNumber);
|
|
14738
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
14456
14739
|
}
|
|
14457
14740
|
|
|
14458
|
-
|
|
14459
|
-
|
|
14741
|
+
static fromMemoryIndex(maybeMemoryIndex: number, isAccessFault = false) {
|
|
14742
|
+
const memoryIndex = tryAsMemoryIndex(maybeMemoryIndex % MEMORY_SIZE);
|
|
14743
|
+
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
14744
|
+
return new PageFault(tryAsU32(startPageIndex), isAccessFault);
|
|
14460
14745
|
}
|
|
14461
14746
|
}
|
|
14462
14747
|
|
|
14463
|
-
|
|
14464
|
-
|
|
14748
|
+
/**
|
|
14749
|
+
* A representation of open-ended range of consecutive indices in memory,
|
|
14750
|
+
* possibly empty or wrapping around.
|
|
14751
|
+
*
|
|
14752
|
+
* `[start, start + length)`
|
|
14753
|
+
*/
|
|
14754
|
+
declare class MemoryRange {
|
|
14755
|
+
/**
|
|
14756
|
+
* Exclusive end index of the range.
|
|
14757
|
+
*
|
|
14758
|
+
* NOTE: The index may be wrapped around and smaller than `start`!
|
|
14759
|
+
*/
|
|
14760
|
+
public readonly end: MemoryIndex;
|
|
14761
|
+
/**
|
|
14762
|
+
* Inclusive last index of the range (present unless the range is empty).
|
|
14763
|
+
*
|
|
14764
|
+
* NOTE: the index may be wrapped around and smaller than `start`!
|
|
14765
|
+
*/
|
|
14766
|
+
public readonly lastIndex: MemoryIndex | null = null;
|
|
14465
14767
|
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
|
|
14768
|
+
private constructor(
|
|
14769
|
+
public readonly start: MemoryIndex,
|
|
14770
|
+
public readonly length: number,
|
|
14771
|
+
) {
|
|
14772
|
+
this.end = tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
14469
14773
|
|
|
14470
|
-
|
|
14471
|
-
|
|
14774
|
+
if (length > 0) {
|
|
14775
|
+
this.lastIndex = tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
14776
|
+
}
|
|
14472
14777
|
}
|
|
14473
14778
|
|
|
14474
|
-
|
|
14475
|
-
|
|
14779
|
+
/** Creates a memory range from given starting point and length */
|
|
14780
|
+
static fromStartAndLength(start: MemoryIndex, length: number) {
|
|
14781
|
+
if (!Number.isInteger(length) || length < 0 || length > MEMORY_SIZE) {
|
|
14782
|
+
throw new TypeError(`length must be a non-negative integer and less than ${MEMORY_SIZE}, got ${length}`);
|
|
14783
|
+
}
|
|
14784
|
+
|
|
14785
|
+
return new MemoryRange(start, length);
|
|
14476
14786
|
}
|
|
14477
14787
|
|
|
14478
|
-
|
|
14479
|
-
|
|
14788
|
+
/** Checks if a range is empty (`length === 0`) */
|
|
14789
|
+
isEmpty() {
|
|
14790
|
+
return this.length === 0;
|
|
14480
14791
|
}
|
|
14481
14792
|
|
|
14482
|
-
|
|
14483
|
-
|
|
14793
|
+
/** Returns true if the range is wrapped (`start` >= `end`) and is not empty */
|
|
14794
|
+
isWrapped() {
|
|
14795
|
+
return this.start >= this.end && !this.isEmpty();
|
|
14484
14796
|
}
|
|
14485
14797
|
|
|
14486
|
-
|
|
14487
|
-
|
|
14798
|
+
/** Checks if given memory address is within the range */
|
|
14799
|
+
isInRange(address: MemoryIndex) {
|
|
14800
|
+
if (this.isWrapped()) {
|
|
14801
|
+
return address >= this.start || address < this.end;
|
|
14802
|
+
}
|
|
14803
|
+
|
|
14804
|
+
return address >= this.start && address < this.end;
|
|
14488
14805
|
}
|
|
14489
14806
|
|
|
14490
|
-
|
|
14491
|
-
|
|
14807
|
+
/** Checks if this range overlaps with another range */
|
|
14808
|
+
overlapsWith(other: MemoryRange) {
|
|
14809
|
+
if (this.lastIndex === null || other.lastIndex === null) {
|
|
14810
|
+
return false;
|
|
14811
|
+
}
|
|
14812
|
+
|
|
14813
|
+
return (
|
|
14814
|
+
this.isInRange(other.start) ||
|
|
14815
|
+
this.isInRange(other.lastIndex) ||
|
|
14816
|
+
other.isInRange(this.start) ||
|
|
14817
|
+
other.isInRange(this.lastIndex)
|
|
14818
|
+
);
|
|
14492
14819
|
}
|
|
14493
14820
|
}
|
|
14494
14821
|
|
|
14495
|
-
|
|
14496
|
-
|
|
14497
|
-
noOfBytesToSkip: number;
|
|
14498
|
-
};
|
|
14822
|
+
declare abstract class MemoryPage {
|
|
14823
|
+
public start: MemoryIndex;
|
|
14499
14824
|
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
/** V_X */
|
|
14504
|
-
immediateDecoder: ImmediateDecoder;
|
|
14505
|
-
};
|
|
14825
|
+
constructor(pageNumber: PageNumber) {
|
|
14826
|
+
this.start = getStartPageIndexFromPageNumber(pageNumber);
|
|
14827
|
+
}
|
|
14506
14828
|
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
noOfBytesToSkip: number;
|
|
14510
|
-
/** W_A */
|
|
14511
|
-
firstRegisterIndex: number;
|
|
14512
|
-
/** W_B */
|
|
14513
|
-
secondRegisterIndex: number;
|
|
14514
|
-
/** W_D */
|
|
14515
|
-
thirdRegisterIndex: number;
|
|
14516
|
-
};
|
|
14829
|
+
/** Returns `true` if the page is writeable. */
|
|
14830
|
+
abstract isWriteable(): boolean;
|
|
14517
14831
|
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
14529
|
-
noOfBytesToSkip: number;
|
|
14530
|
-
/** W_A */
|
|
14531
|
-
firstRegisterIndex: number;
|
|
14532
|
-
/** W_B */
|
|
14533
|
-
secondRegisterIndex: number;
|
|
14534
|
-
/** V_X */
|
|
14535
|
-
immediateDecoder: ImmediateDecoder;
|
|
14536
|
-
};
|
|
14832
|
+
/**
|
|
14833
|
+
* Load exactly `length` bytes from memory page, starting at index `address`
|
|
14834
|
+
* into the `res` array.
|
|
14835
|
+
*
|
|
14836
|
+
* Note that the `res` might be bigger than the number of bytes length, but cannot be smaller.
|
|
14837
|
+
*
|
|
14838
|
+
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
14839
|
+
* NOTE That the `result` might be partially modified in case `PageFault` occurs!
|
|
14840
|
+
*/
|
|
14841
|
+
abstract loadInto(res: Uint8Array, address: PageIndex, length: number): Result$2<OK, PageFault>;
|
|
14537
14842
|
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14843
|
+
/**
|
|
14844
|
+
* Copy all bytes from the `data` into the page at index `address`.
|
|
14845
|
+
*
|
|
14846
|
+
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
14847
|
+
*/
|
|
14848
|
+
abstract storeFrom(address: PageIndex, data: Uint8Array): Result$2<OK, PageFault>;
|
|
14849
|
+
/**
|
|
14850
|
+
* Get dump of the entire page. Should only be used for the debugger-adapter because it
|
|
14851
|
+
* might be inefficient.
|
|
14852
|
+
*/
|
|
14853
|
+
abstract getPageDump(): Uint8Array;
|
|
14546
14854
|
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
noOfBytesToSkip: number;
|
|
14550
|
-
/** W_A */
|
|
14551
|
-
registerIndex: number;
|
|
14552
|
-
/** V_X */
|
|
14553
|
-
immediateDecoder: ExtendedWitdthImmediateDecoder;
|
|
14554
|
-
};
|
|
14855
|
+
abstract setData(pageIndex: PageIndex, data: Uint8Array): void;
|
|
14856
|
+
}
|
|
14555
14857
|
|
|
14556
|
-
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
|
|
14561
|
-
|
|
14562
|
-
|
|
14563
|
-
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14858
|
+
/**
|
|
14859
|
+
* I had to extend ArrayBuffer type to use resizable ArrayBuffer.
|
|
14860
|
+
* We will be able to remove it when this is merged: https://github.com/microsoft/TypeScript/pull/58573
|
|
14861
|
+
* And then a new version of TypeScript is released.
|
|
14862
|
+
*/
|
|
14863
|
+
declare global {
|
|
14864
|
+
interface ArrayBufferConstructor {
|
|
14865
|
+
new (length: number, options?: {
|
|
14866
|
+
maxByteLength: number;
|
|
14867
|
+
}): ArrayBuffer;
|
|
14868
|
+
}
|
|
14869
|
+
interface ArrayBuffer {
|
|
14870
|
+
resize(length: number): void;
|
|
14871
|
+
}
|
|
14872
|
+
}
|
|
14568
14873
|
|
|
14569
|
-
type
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
firstImmediateDecoder: ImmediateDecoder;
|
|
14574
|
-
/** V_Y */
|
|
14575
|
-
secondImmediateDecoder: ImmediateDecoder;
|
|
14874
|
+
type InitialMemoryState = {
|
|
14875
|
+
memory: Map<PageNumber, MemoryPage>;
|
|
14876
|
+
sbrkIndex: SbrkIndex;
|
|
14877
|
+
endHeapIndex: SbrkIndex;
|
|
14576
14878
|
};
|
|
14577
14879
|
|
|
14578
|
-
|
|
14579
|
-
|
|
14580
|
-
|
|
14581
|
-
|
|
14582
|
-
firstRegisterIndex: number;
|
|
14583
|
-
/** W_B */
|
|
14584
|
-
secondRegisterIndex: number;
|
|
14585
|
-
nextPc: number;
|
|
14586
|
-
};
|
|
14880
|
+
declare enum AccessType {
|
|
14881
|
+
READ = 0,
|
|
14882
|
+
WRITE = 1,
|
|
14883
|
+
}
|
|
14587
14884
|
|
|
14588
|
-
|
|
14589
|
-
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
};
|
|
14885
|
+
declare class Memory implements IMemory {
|
|
14886
|
+
static fromInitialMemory(initialMemoryState: InitialMemoryState) {
|
|
14887
|
+
return new Memory(
|
|
14888
|
+
initialMemoryState?.sbrkIndex,
|
|
14889
|
+
initialMemoryState?.sbrkIndex,
|
|
14890
|
+
initialMemoryState?.endHeapIndex,
|
|
14891
|
+
initialMemoryState?.memory,
|
|
14892
|
+
);
|
|
14893
|
+
}
|
|
14598
14894
|
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14603
|
-
|
|
14604
|
-
|
|
14605
|
-
firstImmediateDecoder: ImmediateDecoder;
|
|
14606
|
-
/** V_Y */
|
|
14607
|
-
secondImmediateDecoder: ImmediateDecoder;
|
|
14608
|
-
};
|
|
14895
|
+
constructor(
|
|
14896
|
+
private sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
14897
|
+
private virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end),
|
|
14898
|
+
private endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX),
|
|
14899
|
+
private memory = new Map<PageNumber, MemoryPage>(),
|
|
14900
|
+
) {}
|
|
14609
14901
|
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
|
|
14613
|
-
/** V_X */
|
|
14614
|
-
nextPc: number;
|
|
14615
|
-
};
|
|
14902
|
+
store(address: U32, bytes: Uint8Array): Result$2<OK, PageFault$1> {
|
|
14903
|
+
return this.storeFrom(tryAsMemoryIndex(address), bytes);
|
|
14904
|
+
}
|
|
14616
14905
|
|
|
14617
|
-
|
|
14618
|
-
|
|
14619
|
-
|
|
14620
|
-
| TwoRegistersArgs
|
|
14621
|
-
| ThreeRegistersArgs
|
|
14622
|
-
| TwoRegistersOneImmediateArgs
|
|
14623
|
-
| TwoRegistersTwoImmediatesArgs
|
|
14624
|
-
| OneRegisterOneImmediateOneOffsetArgs
|
|
14625
|
-
| TwoRegistersOneOffsetArgs
|
|
14626
|
-
| OneRegisterOneImmediateArgs
|
|
14627
|
-
| OneOffsetArgs
|
|
14628
|
-
| TwoImmediatesArgs
|
|
14629
|
-
| OneRegisterTwoImmediatesArgs
|
|
14630
|
-
| OneRegisterOneExtendedWidthImmediateArgs;
|
|
14906
|
+
read(address: U32, output: Uint8Array): Result$2<OK, PageFault$1> {
|
|
14907
|
+
return this.loadInto(output, tryAsMemoryIndex(address));
|
|
14908
|
+
}
|
|
14631
14909
|
|
|
14632
|
-
|
|
14633
|
-
|
|
14634
|
-
|
|
14635
|
-
|
|
14636
|
-
|
|
14910
|
+
reset() {
|
|
14911
|
+
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
14912
|
+
this.virtualSbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
14913
|
+
this.endHeapIndex = tryAsSbrkIndex(MAX_MEMORY_INDEX);
|
|
14914
|
+
this.memory = new Map<PageNumber, MemoryPage>(); // TODO [MaSi]: We should keep allocated pages somewhere and reuse it when it is possible
|
|
14915
|
+
}
|
|
14637
14916
|
|
|
14638
|
-
|
|
14639
|
-
this.
|
|
14640
|
-
this.
|
|
14917
|
+
copyFrom(memory: Memory) {
|
|
14918
|
+
this.sbrkIndex = memory.sbrkIndex;
|
|
14919
|
+
this.virtualSbrkIndex = memory.virtualSbrkIndex;
|
|
14920
|
+
this.endHeapIndex = memory.endHeapIndex;
|
|
14921
|
+
this.memory = memory.memory;
|
|
14641
14922
|
}
|
|
14642
14923
|
|
|
14643
|
-
|
|
14644
|
-
|
|
14645
|
-
|
|
14924
|
+
storeFrom(address: MemoryIndex, bytes: Uint8Array): Result$2<OK, PageFault> {
|
|
14925
|
+
if (bytes.length === 0) {
|
|
14926
|
+
return Result.ok(OK);
|
|
14927
|
+
}
|
|
14646
14928
|
|
|
14647
|
-
|
|
14648
|
-
|
|
14649
|
-
break;
|
|
14929
|
+
logger.insane`MEM[${address}] <- ${BytesBlob.blobFrom(bytes)}`;
|
|
14930
|
+
const pagesResult = this.getPages(address, bytes.length, AccessType.WRITE);
|
|
14650
14931
|
|
|
14651
|
-
|
|
14652
|
-
|
|
14653
|
-
|
|
14654
|
-
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
14655
|
-
break;
|
|
14656
|
-
}
|
|
14932
|
+
if (pagesResult.isError) {
|
|
14933
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
14934
|
+
}
|
|
14657
14935
|
|
|
14658
|
-
|
|
14659
|
-
|
|
14660
|
-
|
|
14661
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14662
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14663
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14664
|
-
this.nibblesDecoder.setByte(secondByte);
|
|
14665
|
-
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14666
|
-
break;
|
|
14667
|
-
}
|
|
14936
|
+
const pages = pagesResult.ok;
|
|
14937
|
+
let currentPosition: number = address;
|
|
14938
|
+
let bytesLeft = bytes.length;
|
|
14668
14939
|
|
|
14669
|
-
|
|
14670
|
-
|
|
14671
|
-
|
|
14672
|
-
|
|
14673
|
-
|
|
14940
|
+
for (const page of pages) {
|
|
14941
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE);
|
|
14942
|
+
const bytesToWrite = Math.min(PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
14943
|
+
const sourceStartIndex = currentPosition - address;
|
|
14944
|
+
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
14674
14945
|
|
|
14675
|
-
|
|
14676
|
-
const immediateStartIndex = pc + 2;
|
|
14677
|
-
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
14678
|
-
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
14679
|
-
break;
|
|
14680
|
-
}
|
|
14946
|
+
page.storeFrom(pageStartIndex, source);
|
|
14681
14947
|
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14948
|
+
currentPosition += bytesToWrite;
|
|
14949
|
+
bytesLeft -= bytesToWrite;
|
|
14950
|
+
}
|
|
14951
|
+
return Result.ok(OK);
|
|
14952
|
+
}
|
|
14686
14953
|
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
|
|
14690
|
-
|
|
14954
|
+
private getPages(startAddress: MemoryIndex, length: number, accessType: AccessType): Result$2<MemoryPage[], PageFault> {
|
|
14955
|
+
if (length === 0) {
|
|
14956
|
+
return Result.ok([]);
|
|
14957
|
+
}
|
|
14691
14958
|
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
Math.max(0, nextInstructionDistance - 2 - immediateLength),
|
|
14695
|
-
);
|
|
14696
|
-
const offsetStartIndex = pc + 2 + immediateLength;
|
|
14697
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14698
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
14959
|
+
const memoryRange = MemoryRange.fromStartAndLength(startAddress, length);
|
|
14960
|
+
const pageRange = PageRange.fromMemoryRange(memoryRange);
|
|
14699
14961
|
|
|
14700
|
-
|
|
14701
|
-
break;
|
|
14702
|
-
}
|
|
14703
|
-
|
|
14704
|
-
case ArgumentType.TWO_REGISTERS_ONE_OFFSET: {
|
|
14705
|
-
const firstByte = this.code[pc + 1];
|
|
14706
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14707
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14708
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
14709
|
-
|
|
14710
|
-
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
14711
|
-
const offsetStartIndex = pc + 2;
|
|
14712
|
-
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
14713
|
-
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
14962
|
+
const pages: MemoryPage[] = [];
|
|
14714
14963
|
|
|
14715
|
-
|
|
14716
|
-
|
|
14964
|
+
for (const pageNumber of pageRange) {
|
|
14965
|
+
if (pageNumber < RESERVED_NUMBER_OF_PAGES) {
|
|
14966
|
+
return Result.error(
|
|
14967
|
+
PageFault.fromPageNumber(pageNumber, true),
|
|
14968
|
+
() => `Page fault: attempted to access reserved page ${pageNumber}`,
|
|
14969
|
+
);
|
|
14717
14970
|
}
|
|
14718
14971
|
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14724
|
-
break;
|
|
14972
|
+
const page = this.memory.get(pageNumber);
|
|
14973
|
+
|
|
14974
|
+
if (page === undefined) {
|
|
14975
|
+
return Result.error(PageFault.fromPageNumber(pageNumber), () => `Page fault: page ${pageNumber} not allocated`);
|
|
14725
14976
|
}
|
|
14726
14977
|
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
this.offsetDecoder.setBytes(offsetBytes);
|
|
14733
|
-
const offsetValue = this.offsetDecoder.getSigned();
|
|
14734
|
-
result.nextPc = pc + offsetValue;
|
|
14735
|
-
break;
|
|
14978
|
+
if (accessType === AccessType.WRITE && !page.isWriteable()) {
|
|
14979
|
+
return Result.error(
|
|
14980
|
+
PageFault.fromPageNumber(pageNumber, true),
|
|
14981
|
+
() => `Page fault: attempted to write to read-only page ${pageNumber}`,
|
|
14982
|
+
);
|
|
14736
14983
|
}
|
|
14737
14984
|
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14741
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14985
|
+
pages.push(page);
|
|
14986
|
+
}
|
|
14742
14987
|
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14988
|
+
return Result.ok(pages);
|
|
14989
|
+
}
|
|
14990
|
+
/**
|
|
14991
|
+
* Read content of the memory at `[address, address + result.length)` and
|
|
14992
|
+
* write the result into the `result` buffer.
|
|
14993
|
+
*
|
|
14994
|
+
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
14995
|
+
*/
|
|
14996
|
+
loadInto(result: Uint8Array, startAddress: MemoryIndex): Result$2<OK, PageFault> {
|
|
14997
|
+
if (result.length === 0) {
|
|
14998
|
+
return Result.ok(OK);
|
|
14999
|
+
}
|
|
14750
15000
|
|
|
14751
|
-
|
|
14752
|
-
const firstByte = this.code[pc + 1];
|
|
14753
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14754
|
-
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
14755
|
-
const firstImmediateStartIndex = pc + 2;
|
|
14756
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14757
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14758
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15001
|
+
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
14759
15002
|
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
);
|
|
14764
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14765
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14766
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14767
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14768
|
-
break;
|
|
14769
|
-
}
|
|
15003
|
+
if (pagesResult.isError) {
|
|
15004
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
15005
|
+
}
|
|
14770
15006
|
|
|
14771
|
-
|
|
14772
|
-
const firstByte = this.code[pc + 1];
|
|
14773
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14774
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15007
|
+
const pages = pagesResult.ok;
|
|
14775
15008
|
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14779
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14780
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15009
|
+
let currentPosition: number = startAddress;
|
|
15010
|
+
let bytesLeft = result.length;
|
|
14781
15011
|
|
|
14782
|
-
|
|
14783
|
-
|
|
14784
|
-
|
|
14785
|
-
|
|
14786
|
-
|
|
14787
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14788
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14789
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14790
|
-
break;
|
|
14791
|
-
}
|
|
15012
|
+
for (const page of pages) {
|
|
15013
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE);
|
|
15014
|
+
const bytesToRead = Math.min(PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15015
|
+
const destinationStartIndex = currentPosition - startAddress;
|
|
15016
|
+
const destination = result.subarray(destinationStartIndex);
|
|
14792
15017
|
|
|
14793
|
-
|
|
14794
|
-
const firstByte = this.code[pc + 1];
|
|
14795
|
-
this.nibblesDecoder.setByte(firstByte);
|
|
14796
|
-
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
14797
|
-
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15018
|
+
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
14798
15019
|
|
|
14799
|
-
|
|
14800
|
-
|
|
14801
|
-
|
|
14802
|
-
const firstImmediateStartIndex = pc + 3;
|
|
14803
|
-
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
14804
|
-
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
14805
|
-
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15020
|
+
currentPosition += bytesToRead;
|
|
15021
|
+
bytesLeft -= bytesToRead;
|
|
15022
|
+
}
|
|
14806
15023
|
|
|
14807
|
-
|
|
14808
|
-
|
|
14809
|
-
|
|
14810
|
-
);
|
|
14811
|
-
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
14812
|
-
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
14813
|
-
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
14814
|
-
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
14815
|
-
break;
|
|
14816
|
-
}
|
|
15024
|
+
logger.insane`MEM[${startAddress}] => ${BytesBlob.blobFrom(result)}`;
|
|
15025
|
+
return Result.ok(OK);
|
|
15026
|
+
}
|
|
14817
15027
|
|
|
14818
|
-
|
|
14819
|
-
|
|
14820
|
-
|
|
14821
|
-
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15028
|
+
sbrk(length: number): SbrkIndex {
|
|
15029
|
+
const currentSbrkIndex = this.sbrkIndex;
|
|
15030
|
+
const currentVirtualSbrkIndex = this.virtualSbrkIndex;
|
|
14822
15031
|
|
|
14823
|
-
|
|
14824
|
-
|
|
14825
|
-
|
|
14826
|
-
result.immediateDecoder.setBytes(immediateBytes);
|
|
14827
|
-
break;
|
|
14828
|
-
}
|
|
15032
|
+
// new sbrk index is bigger than 2 ** 32 or endHeapIndex
|
|
15033
|
+
if (MAX_MEMORY_INDEX < currentVirtualSbrkIndex + length || currentVirtualSbrkIndex + length > this.endHeapIndex) {
|
|
15034
|
+
throw new OutOfMemory();
|
|
14829
15035
|
}
|
|
14830
|
-
}
|
|
14831
|
-
}
|
|
14832
15036
|
|
|
14833
|
-
|
|
14834
|
-
const results = new Array(ARGUMENT_TYPE_LENGTH) as Results;
|
|
15037
|
+
const newVirtualSbrkIndex = tryAsSbrkIndex(this.virtualSbrkIndex + length);
|
|
14835
15038
|
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
15039
|
+
// no alllocation needed
|
|
15040
|
+
if (newVirtualSbrkIndex <= currentSbrkIndex) {
|
|
15041
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
15042
|
+
return currentVirtualSbrkIndex;
|
|
15043
|
+
}
|
|
14840
15044
|
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
|
|
15045
|
+
// standard allocation using "Writeable" pages
|
|
15046
|
+
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize(newVirtualSbrkIndex));
|
|
15047
|
+
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
15048
|
+
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15049
|
+
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE;
|
|
15050
|
+
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
14846
15051
|
|
|
14847
|
-
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
secondRegisterIndex: 0,
|
|
14852
|
-
};
|
|
15052
|
+
for (const pageNumber of rangeToAllocate) {
|
|
15053
|
+
const page = new WriteablePage(pageNumber);
|
|
15054
|
+
this.memory.set(pageNumber, page);
|
|
15055
|
+
}
|
|
14853
15056
|
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
secondRegisterIndex: 0,
|
|
14859
|
-
thirdRegisterIndex: 0,
|
|
14860
|
-
};
|
|
15057
|
+
this.virtualSbrkIndex = newVirtualSbrkIndex;
|
|
15058
|
+
this.sbrkIndex = newSbrkIndex;
|
|
15059
|
+
return currentVirtualSbrkIndex;
|
|
15060
|
+
}
|
|
14861
15061
|
|
|
14862
|
-
|
|
14863
|
-
|
|
14864
|
-
|
|
14865
|
-
|
|
14866
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
14867
|
-
nextPc: 0,
|
|
14868
|
-
};
|
|
15062
|
+
getPageDump(pageNumber: PageNumber) {
|
|
15063
|
+
const page = this.memory.get(pageNumber);
|
|
15064
|
+
return page?.getPageDump() ?? null;
|
|
15065
|
+
}
|
|
14869
15066
|
|
|
14870
|
-
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
secondRegisterIndex: 0,
|
|
14875
|
-
nextPc: 0,
|
|
14876
|
-
};
|
|
15067
|
+
getDirtyPages() {
|
|
15068
|
+
return this.memory.keys();
|
|
15069
|
+
}
|
|
15070
|
+
}
|
|
14877
15071
|
|
|
14878
|
-
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
firstRegisterIndex: 0,
|
|
14882
|
-
secondRegisterIndex: 0,
|
|
14883
|
-
immediateDecoder: new ImmediateDecoder(),
|
|
14884
|
-
};
|
|
15072
|
+
declare class MemoryBuilder {
|
|
15073
|
+
private readonly initialMemory: Map<PageNumber, MemoryPage> = new Map();
|
|
15074
|
+
private isFinalized = false;
|
|
14885
15075
|
|
|
14886
|
-
|
|
14887
|
-
|
|
14888
|
-
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
};
|
|
15076
|
+
private ensureNotFinalized() {
|
|
15077
|
+
if (this.isFinalized) {
|
|
15078
|
+
throw new FinalizedBuilderModification();
|
|
15079
|
+
}
|
|
15080
|
+
}
|
|
14892
15081
|
|
|
14893
|
-
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
14899
|
-
};
|
|
15082
|
+
private ensureNoReservedMemoryUsage(range: MemoryRange) {
|
|
15083
|
+
if (range.overlapsWith(RESERVED_MEMORY_RANGE)) {
|
|
15084
|
+
throw new ReservedMemoryFault();
|
|
15085
|
+
}
|
|
15086
|
+
}
|
|
14900
15087
|
|
|
14901
|
-
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
|
|
15088
|
+
/**
|
|
15089
|
+
* Create entire readable pages to handle the `[start, end)` range.
|
|
15090
|
+
*
|
|
15091
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
15092
|
+
* they need to be the start indices of the pages.
|
|
15093
|
+
*
|
|
15094
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
15095
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
15096
|
+
*/
|
|
15097
|
+
setReadablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15098
|
+
this.ensureNotFinalized();
|
|
15099
|
+
check`${start < end} end has to be bigger than start`;
|
|
15100
|
+
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15101
|
+
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15102
|
+
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
14906
15103
|
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
noOfBytesToSkip: 1,
|
|
14910
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
14911
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
14912
|
-
};
|
|
15104
|
+
const length = end - start;
|
|
15105
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
14913
15106
|
|
|
14914
|
-
|
|
14915
|
-
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES,
|
|
14916
|
-
noOfBytesToSkip: 1,
|
|
14917
|
-
firstImmediateDecoder: new ImmediateDecoder(),
|
|
14918
|
-
secondImmediateDecoder: new ImmediateDecoder(),
|
|
14919
|
-
firstRegisterIndex: 0,
|
|
14920
|
-
secondRegisterIndex: 0,
|
|
14921
|
-
};
|
|
15107
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
14922
15108
|
|
|
14923
|
-
|
|
14924
|
-
|
|
14925
|
-
noOfBytesToSkip: 9,
|
|
14926
|
-
registerIndex: 0,
|
|
14927
|
-
immediateDecoder: new ExtendedWitdthImmediateDecoder(),
|
|
14928
|
-
};
|
|
15109
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
15110
|
+
const noOfPages = pages.length;
|
|
14929
15111
|
|
|
14930
|
-
|
|
14931
|
-
|
|
15112
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
15113
|
+
const pageNumber = pages[i];
|
|
15114
|
+
const dataChunk = data.subarray(i * PAGE_SIZE, (i + 1) * PAGE_SIZE);
|
|
15115
|
+
const page = new ReadablePage(pageNumber, dataChunk);
|
|
15116
|
+
this.initialMemory.set(pageNumber, page);
|
|
15117
|
+
}
|
|
14932
15118
|
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
FALLTHROUGH = 1,
|
|
14936
|
-
ECALLI = 10,
|
|
14937
|
-
LOAD_IMM_64 = 20,
|
|
14938
|
-
STORE_IMM_U8 = 30,
|
|
14939
|
-
STORE_IMM_U16 = 31,
|
|
14940
|
-
STORE_IMM_U32 = 32,
|
|
14941
|
-
STORE_IMM_U64 = 33,
|
|
14942
|
-
JUMP = 40,
|
|
14943
|
-
JUMP_IND = 50,
|
|
14944
|
-
LOAD_IMM = 51,
|
|
14945
|
-
LOAD_U8 = 52,
|
|
14946
|
-
LOAD_I8 = 53,
|
|
14947
|
-
LOAD_U16 = 54,
|
|
14948
|
-
LOAD_I16 = 55,
|
|
14949
|
-
LOAD_U32 = 56,
|
|
14950
|
-
LOAD_I32 = 57,
|
|
14951
|
-
LOAD_U64 = 58,
|
|
14952
|
-
STORE_U8 = 59,
|
|
14953
|
-
STORE_U16 = 60,
|
|
14954
|
-
STORE_U32 = 61,
|
|
14955
|
-
STORE_U64 = 62,
|
|
14956
|
-
STORE_IMM_IND_U8 = 70,
|
|
14957
|
-
STORE_IMM_IND_U16 = 71,
|
|
14958
|
-
STORE_IMM_IND_U32 = 72,
|
|
14959
|
-
STORE_IMM_IND_U64 = 73,
|
|
14960
|
-
LOAD_IMM_JUMP = 80,
|
|
14961
|
-
BRANCH_EQ_IMM = 81,
|
|
14962
|
-
BRANCH_NE_IMM = 82,
|
|
14963
|
-
BRANCH_LT_U_IMM = 83,
|
|
14964
|
-
BRANCH_LE_U_IMM = 84,
|
|
14965
|
-
BRANCH_GE_U_IMM = 85,
|
|
14966
|
-
BRANCH_GT_U_IMM = 86,
|
|
14967
|
-
BRANCH_LT_S_IMM = 87,
|
|
14968
|
-
BRANCH_LE_S_IMM = 88,
|
|
14969
|
-
BRANCH_GE_S_IMM = 89,
|
|
14970
|
-
BRANCH_GT_S_IMM = 90,
|
|
14971
|
-
MOVE_REG = 100,
|
|
14972
|
-
SBRK = 101,
|
|
14973
|
-
COUNT_SET_BITS_64 = 102,
|
|
14974
|
-
COUNT_SET_BITS_32 = 103,
|
|
14975
|
-
LEADING_ZERO_BITS_64 = 104,
|
|
14976
|
-
LEADING_ZERO_BITS_32 = 105,
|
|
14977
|
-
TRAILING_ZERO_BITS_64 = 106,
|
|
14978
|
-
TRAILING_ZERO_BITS_32 = 107,
|
|
14979
|
-
SIGN_EXTEND_8 = 108,
|
|
14980
|
-
SIGN_EXTEND_16 = 109,
|
|
14981
|
-
ZERO_EXTEND_16 = 110,
|
|
14982
|
-
REVERSE_BYTES = 111,
|
|
14983
|
-
STORE_IND_U8 = 120,
|
|
14984
|
-
STORE_IND_U16 = 121,
|
|
14985
|
-
STORE_IND_U32 = 122,
|
|
14986
|
-
STORE_IND_U64 = 123,
|
|
14987
|
-
LOAD_IND_U8 = 124,
|
|
14988
|
-
LOAD_IND_I8 = 125,
|
|
14989
|
-
LOAD_IND_U16 = 126,
|
|
14990
|
-
LOAD_IND_I16 = 127,
|
|
14991
|
-
LOAD_IND_U32 = 128,
|
|
14992
|
-
LOAD_IND_I32 = 129,
|
|
14993
|
-
LOAD_IND_U64 = 130,
|
|
14994
|
-
ADD_IMM_32 = 131,
|
|
14995
|
-
AND_IMM = 132,
|
|
14996
|
-
XOR_IMM = 133,
|
|
14997
|
-
OR_IMM = 134,
|
|
14998
|
-
MUL_IMM_32 = 135,
|
|
14999
|
-
SET_LT_U_IMM = 136,
|
|
15000
|
-
SET_LT_S_IMM = 137,
|
|
15001
|
-
SHLO_L_IMM_32 = 138,
|
|
15002
|
-
SHLO_R_IMM_32 = 139,
|
|
15003
|
-
SHAR_R_IMM_32 = 140,
|
|
15004
|
-
NEG_ADD_IMM_32 = 141,
|
|
15005
|
-
SET_GT_U_IMM = 142,
|
|
15006
|
-
SET_GT_S_IMM = 143,
|
|
15007
|
-
SHLO_L_IMM_ALT_32 = 144,
|
|
15008
|
-
SHLO_R_IMM_ALT_32 = 145,
|
|
15009
|
-
SHAR_R_IMM_ALT_32 = 146,
|
|
15010
|
-
CMOV_IZ_IMM = 147,
|
|
15011
|
-
CMOV_NZ_IMM = 148,
|
|
15012
|
-
ADD_IMM_64 = 149,
|
|
15013
|
-
MUL_IMM_64 = 150,
|
|
15014
|
-
SHLO_L_IMM_64 = 151,
|
|
15015
|
-
SHLO_R_IMM_64 = 152,
|
|
15016
|
-
SHAR_R_IMM_64 = 153,
|
|
15017
|
-
NEG_ADD_IMM_64 = 154,
|
|
15018
|
-
SHLO_L_IMM_ALT_64 = 155,
|
|
15019
|
-
SHLO_R_IMM_ALT_64 = 156,
|
|
15020
|
-
SHAR_R_IMM_ALT_64 = 157,
|
|
15021
|
-
ROT_R_64_IMM = 158,
|
|
15022
|
-
ROT_R_64_IMM_ALT = 159,
|
|
15023
|
-
ROT_R_32_IMM = 160,
|
|
15024
|
-
ROT_R_32_IMM_ALT = 161,
|
|
15025
|
-
BRANCH_EQ = 170,
|
|
15026
|
-
BRANCH_NE = 171,
|
|
15027
|
-
BRANCH_LT_U = 172,
|
|
15028
|
-
BRANCH_LT_S = 173,
|
|
15029
|
-
BRANCH_GE_U = 174,
|
|
15030
|
-
BRANCH_GE_S = 175,
|
|
15031
|
-
LOAD_IMM_JUMP_IND = 180,
|
|
15032
|
-
ADD_32 = 190,
|
|
15033
|
-
SUB_32 = 191,
|
|
15034
|
-
MUL_32 = 192,
|
|
15035
|
-
DIV_U_32 = 193,
|
|
15036
|
-
DIV_S_32 = 194,
|
|
15037
|
-
REM_U_32 = 195,
|
|
15038
|
-
REM_S_32 = 196,
|
|
15039
|
-
SHLO_L_32 = 197,
|
|
15040
|
-
SHLO_R_32 = 198,
|
|
15041
|
-
SHAR_R_32 = 199,
|
|
15042
|
-
ADD_64 = 200,
|
|
15043
|
-
SUB_64 = 201,
|
|
15044
|
-
MUL_64 = 202,
|
|
15045
|
-
DIV_U_64 = 203,
|
|
15046
|
-
DIV_S_64 = 204,
|
|
15047
|
-
REM_U_64 = 205,
|
|
15048
|
-
REM_S_64 = 206,
|
|
15049
|
-
SHLO_L_64 = 207,
|
|
15050
|
-
SHLO_R_64 = 208,
|
|
15051
|
-
SHAR_R_64 = 209,
|
|
15052
|
-
AND = 210,
|
|
15053
|
-
XOR = 211,
|
|
15054
|
-
OR = 212,
|
|
15055
|
-
MUL_UPPER_S_S = 213,
|
|
15056
|
-
MUL_UPPER_U_U = 214,
|
|
15057
|
-
MUL_UPPER_S_U = 215,
|
|
15058
|
-
SET_LT_U = 216,
|
|
15059
|
-
SET_LT_S = 217,
|
|
15060
|
-
CMOV_IZ = 218,
|
|
15061
|
-
CMOV_NZ = 219,
|
|
15062
|
-
ROT_L_64 = 220,
|
|
15063
|
-
ROT_L_32 = 221,
|
|
15064
|
-
ROT_R_64 = 222,
|
|
15065
|
-
ROT_R_32 = 223,
|
|
15066
|
-
AND_INV = 224,
|
|
15067
|
-
OR_INV = 225,
|
|
15068
|
-
XNOR = 226,
|
|
15069
|
-
MAX = 227,
|
|
15070
|
-
MAX_U = 228,
|
|
15071
|
-
MIN = 229,
|
|
15072
|
-
MIN_U = 230,
|
|
15073
|
-
}
|
|
15119
|
+
return this;
|
|
15120
|
+
}
|
|
15074
15121
|
|
|
15075
|
-
|
|
15076
|
-
|
|
15122
|
+
/**
|
|
15123
|
+
* Create entire writeable pages to handle the `[start, end)` range.
|
|
15124
|
+
*
|
|
15125
|
+
* Note that both `start` and `end` must be multiple of the `PAGE_SIZE`, i.e.
|
|
15126
|
+
* they need to be the start indices of the pages.
|
|
15127
|
+
*
|
|
15128
|
+
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
15129
|
+
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
15130
|
+
*/
|
|
15131
|
+
setWriteablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15132
|
+
this.ensureNotFinalized();
|
|
15133
|
+
check`${start < end} end has to be bigger than start`;
|
|
15134
|
+
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15135
|
+
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15136
|
+
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15077
15137
|
|
|
15078
|
-
|
|
15079
|
-
|
|
15138
|
+
const length = end - start;
|
|
15139
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15080
15140
|
|
|
15081
|
-
|
|
15141
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15082
15142
|
|
|
15083
|
-
|
|
15143
|
+
const pages = Array.from(PageRange.fromMemoryRange(range));
|
|
15144
|
+
const noOfPages = pages.length;
|
|
15084
15145
|
|
|
15085
|
-
|
|
15086
|
-
|
|
15087
|
-
|
|
15088
|
-
|
|
15146
|
+
for (let i = 0; i < noOfPages; i++) {
|
|
15147
|
+
const pageNumber = pages[i];
|
|
15148
|
+
const dataChunk = data.subarray(i * PAGE_SIZE, (i + 1) * PAGE_SIZE);
|
|
15149
|
+
const page = new WriteablePage(pageNumber, dataChunk);
|
|
15150
|
+
this.initialMemory.set(pageNumber, page);
|
|
15151
|
+
}
|
|
15089
15152
|
|
|
15090
|
-
|
|
15153
|
+
return this;
|
|
15154
|
+
}
|
|
15091
15155
|
|
|
15092
|
-
|
|
15093
|
-
|
|
15094
|
-
|
|
15095
|
-
|
|
15096
|
-
|
|
15097
|
-
|
|
15098
|
-
|
|
15099
|
-
|
|
15100
|
-
|
|
15101
|
-
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15102
|
-
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15103
|
-
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15104
|
-
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15105
|
-
|
|
15106
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U8] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15107
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U16] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15108
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15109
|
-
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15110
|
-
|
|
15111
|
-
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15112
|
-
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15113
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15114
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15115
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15116
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15117
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15118
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15119
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15120
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15121
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15122
|
-
|
|
15123
|
-
instructionArgumentTypeMap[Instruction.MOVE_REG] = ArgumentType.TWO_REGISTERS;
|
|
15124
|
-
instructionArgumentTypeMap[Instruction.SBRK] = ArgumentType.TWO_REGISTERS;
|
|
15125
|
-
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
15126
|
-
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
15127
|
-
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
15128
|
-
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
15129
|
-
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
15130
|
-
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
15131
|
-
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_8] = ArgumentType.TWO_REGISTERS;
|
|
15132
|
-
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
15133
|
-
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
15134
|
-
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
15156
|
+
/**
|
|
15157
|
+
* This function can be useful when page map and initial memory data are provided separatelly.
|
|
15158
|
+
* You can use setWriteablePages/setReadablePages to create empty pages and then setData to fill them
|
|
15159
|
+
*/
|
|
15160
|
+
setData(start: MemoryIndex, data: Uint8Array) {
|
|
15161
|
+
this.ensureNotFinalized();
|
|
15162
|
+
const pageOffset = start % PAGE_SIZE;
|
|
15163
|
+
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15164
|
+
check`${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15135
15165
|
|
|
15136
|
-
|
|
15137
|
-
|
|
15138
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15139
|
-
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15140
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15141
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15142
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15143
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15144
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15145
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15146
|
-
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15147
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15148
|
-
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15149
|
-
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15150
|
-
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15151
|
-
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15152
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15153
|
-
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15154
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15155
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15156
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15157
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15158
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15159
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15160
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15161
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15162
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15163
|
-
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15164
|
-
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15165
|
-
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15166
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15167
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15168
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15169
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15170
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15171
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15172
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15173
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15174
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15175
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15176
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15177
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15166
|
+
const length = data.length;
|
|
15167
|
+
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15178
15168
|
|
|
15179
|
-
|
|
15180
|
-
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15181
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15182
|
-
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15183
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15184
|
-
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15169
|
+
this.ensureNoReservedMemoryUsage(range);
|
|
15185
15170
|
|
|
15186
|
-
|
|
15171
|
+
const pageNumber = getPageNumber(start);
|
|
15172
|
+
const page = this.initialMemory.get(pageNumber);
|
|
15187
15173
|
|
|
15188
|
-
|
|
15189
|
-
|
|
15190
|
-
|
|
15191
|
-
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
15192
|
-
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
15193
|
-
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
15194
|
-
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
15195
|
-
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
15196
|
-
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
15197
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
15198
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
15199
|
-
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
15200
|
-
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
15201
|
-
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
15202
|
-
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
15203
|
-
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
15204
|
-
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
15205
|
-
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
15206
|
-
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
15207
|
-
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
15208
|
-
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
15209
|
-
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
15210
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
15211
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15212
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15213
|
-
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
15214
|
-
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15215
|
-
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15216
|
-
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
15217
|
-
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
15218
|
-
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
15219
|
-
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
15220
|
-
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
15221
|
-
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
15222
|
-
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
15223
|
-
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
15224
|
-
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
15225
|
-
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
15226
|
-
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
15227
|
-
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
15228
|
-
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
15174
|
+
if (page === undefined) {
|
|
15175
|
+
throw new PageNotExist();
|
|
15176
|
+
}
|
|
15229
15177
|
|
|
15230
|
-
|
|
15231
|
-
|
|
15178
|
+
const startPageIndex = tryAsPageIndex(start - page.start);
|
|
15179
|
+
page.setData(startPageIndex, data);
|
|
15232
15180
|
|
|
15233
|
-
|
|
15234
|
-
|
|
15181
|
+
return this;
|
|
15182
|
+
}
|
|
15235
15183
|
|
|
15236
|
-
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
|
|
15184
|
+
finalize(startHeapIndex: MemoryIndex, endHeapIndex: SbrkIndex): Memory {
|
|
15185
|
+
check`
|
|
15186
|
+
${startHeapIndex <= endHeapIndex}
|
|
15187
|
+
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
15188
|
+
`;
|
|
15189
|
+
this.ensureNotFinalized();
|
|
15240
15190
|
|
|
15241
|
-
const
|
|
15242
|
-
|
|
15191
|
+
const heapRange = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
15192
|
+
const heapPagesRange = PageRange.fromMemoryRange(heapRange);
|
|
15193
|
+
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
15243
15194
|
|
|
15244
|
-
for (
|
|
15245
|
-
if (
|
|
15246
|
-
|
|
15195
|
+
for (const pageNumber of initializedPageNumbers) {
|
|
15196
|
+
if (heapPagesRange.isInRange(pageNumber)) {
|
|
15197
|
+
throw new IncorrectSbrkIndex();
|
|
15247
15198
|
}
|
|
15248
15199
|
}
|
|
15249
|
-
}
|
|
15250
|
-
|
|
15251
|
-
isBeginningOfBasicBlock(index: number) {
|
|
15252
|
-
return this.basicBlocks.has(index);
|
|
15253
|
-
}
|
|
15254
|
-
}
|
|
15255
|
-
|
|
15256
|
-
declare enum Result {
|
|
15257
|
-
HALT = 0,
|
|
15258
|
-
PANIC = 1,
|
|
15259
|
-
FAULT_ACCESS = 2,
|
|
15260
|
-
FAULT = 3,
|
|
15261
|
-
HOST = 4,
|
|
15262
|
-
}
|
|
15263
15200
|
|
|
15264
|
-
|
|
15265
|
-
|
|
15266
|
-
|
|
15267
|
-
|
|
15268
|
-
|
|
15269
|
-
*
|
|
15270
|
-
* In case of a `status === Result.FAULT` this will be the memory address
|
|
15271
|
-
* that triggered the fault.
|
|
15272
|
-
* In case of a `status === Result.HOST` this will be the host call index
|
|
15273
|
-
* that should be invoked.
|
|
15274
|
-
*
|
|
15275
|
-
* In any other circumstance the value should be `null`.
|
|
15276
|
-
*/
|
|
15277
|
-
public exitParam: number | null = null;
|
|
15201
|
+
const memory = Memory.fromInitialMemory({
|
|
15202
|
+
memory: this.initialMemory,
|
|
15203
|
+
sbrkIndex: tryAsSbrkIndex(startHeapIndex),
|
|
15204
|
+
endHeapIndex,
|
|
15205
|
+
});
|
|
15278
15206
|
|
|
15279
|
-
|
|
15280
|
-
|
|
15281
|
-
this.status = null;
|
|
15282
|
-
this.exitParam = null;
|
|
15207
|
+
this.isFinalized = true;
|
|
15208
|
+
return memory;
|
|
15283
15209
|
}
|
|
15284
15210
|
}
|
|
15285
15211
|
|
|
15286
|
-
|
|
15287
|
-
|
|
15288
|
-
declare const tryAsMemoryIndex = (index: number): MemoryIndex => {
|
|
15289
|
-
check`${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15290
|
-
return asOpaqueType(index);
|
|
15291
|
-
};
|
|
15292
|
-
|
|
15293
|
-
type SbrkIndex = Opaque<number, "sbrk index">;
|
|
15294
|
-
|
|
15295
|
-
declare const tryAsSbrkIndex = (index: number): SbrkIndex => {
|
|
15296
|
-
check`${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
15297
|
-
return asOpaqueType(index);
|
|
15298
|
-
};
|
|
15299
|
-
|
|
15300
|
-
type PageIndex = Opaque<number, "memory page index">;
|
|
15301
|
-
type PageNumber = Opaque<number, "memory page number">;
|
|
15302
|
-
|
|
15303
|
-
declare class PageFault {
|
|
15304
|
-
private constructor(
|
|
15305
|
-
public address: MemoryIndex,
|
|
15306
|
-
public isAccessFault = true,
|
|
15307
|
-
) {}
|
|
15212
|
+
declare const NO_OF_REGISTERS = 13;
|
|
15308
15213
|
|
|
15309
|
-
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
return new PageFault(startPageIndex, isAccessFault);
|
|
15214
|
+
declare class MemorySegment extends WithDebug {
|
|
15215
|
+
static from({ start, end, data }: Omit<MemorySegment, never>) {
|
|
15216
|
+
return new MemorySegment(start, end, data);
|
|
15313
15217
|
}
|
|
15314
15218
|
|
|
15315
|
-
|
|
15316
|
-
|
|
15317
|
-
|
|
15318
|
-
|
|
15219
|
+
constructor(
|
|
15220
|
+
public readonly start: number,
|
|
15221
|
+
public readonly end: number,
|
|
15222
|
+
public readonly data: Uint8Array | null,
|
|
15223
|
+
) {
|
|
15224
|
+
super();
|
|
15319
15225
|
}
|
|
15320
15226
|
}
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15227
|
+
declare class SpiMemory extends WithDebug {
|
|
15228
|
+
constructor(
|
|
15229
|
+
public readonly readable: MemorySegment[],
|
|
15230
|
+
public readonly writeable: MemorySegment[],
|
|
15231
|
+
public readonly sbrkIndex: number,
|
|
15232
|
+
public readonly heapEnd: number,
|
|
15233
|
+
) {
|
|
15234
|
+
super();
|
|
15325
15235
|
}
|
|
15326
15236
|
}
|
|
15327
15237
|
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15238
|
+
declare class SpiProgram extends WithDebug {
|
|
15239
|
+
constructor(
|
|
15240
|
+
public readonly code: Uint8Array,
|
|
15241
|
+
public readonly memory: SpiMemory,
|
|
15242
|
+
public readonly registers: BigUint64Array,
|
|
15243
|
+
) {
|
|
15244
|
+
super();
|
|
15245
|
+
}
|
|
15246
|
+
}
|
|
15247
|
+
|
|
15248
|
+
/**
|
|
15249
|
+
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
15331
15250
|
*
|
|
15332
|
-
*
|
|
15251
|
+
* E_n - little endian encoding, n - length
|
|
15252
|
+
* o - initial read only data
|
|
15253
|
+
* w - initial heap
|
|
15254
|
+
* z - heap pages filled with zeros
|
|
15255
|
+
* s - stack size
|
|
15256
|
+
* c - program code
|
|
15257
|
+
*
|
|
15258
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
15333
15259
|
*/
|
|
15334
|
-
declare
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
|
|
15343
|
-
|
|
15344
|
-
|
|
15345
|
-
|
|
15346
|
-
|
|
15260
|
+
declare function decodeStandardProgram(program: Uint8Array, args: Uint8Array) {
|
|
15261
|
+
const decoder = Decoder.fromBlob(program);
|
|
15262
|
+
const oLength = decoder.u24();
|
|
15263
|
+
const wLength = decoder.u24();
|
|
15264
|
+
check`${args.length <= DATA_LENGTH} Incorrect arguments length`;
|
|
15265
|
+
check`${oLength <= DATA_LENGTH} Incorrect readonly segment length`;
|
|
15266
|
+
const readOnlyLength = oLength;
|
|
15267
|
+
check`${wLength <= DATA_LENGTH} Incorrect heap segment length`;
|
|
15268
|
+
const heapLength = wLength;
|
|
15269
|
+
const noOfHeapZerosPages = decoder.u16();
|
|
15270
|
+
const stackSize = decoder.u24();
|
|
15271
|
+
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
15272
|
+
const initialHeap = decoder.bytes(heapLength).raw;
|
|
15273
|
+
const codeLength = decoder.u32();
|
|
15274
|
+
const code = decoder.bytes(codeLength).raw;
|
|
15275
|
+
decoder.finish();
|
|
15347
15276
|
|
|
15348
|
-
|
|
15349
|
-
|
|
15350
|
-
|
|
15351
|
-
)
|
|
15352
|
-
|
|
15277
|
+
const readonlyDataStart = SEGMENT_SIZE;
|
|
15278
|
+
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
15279
|
+
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
15280
|
+
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
15281
|
+
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
15282
|
+
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
15283
|
+
const stackEnd = STACK_SEGMENT;
|
|
15284
|
+
const argsStart = ARGS_SEGMENT;
|
|
15285
|
+
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
15286
|
+
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
15353
15287
|
|
|
15354
|
-
|
|
15355
|
-
|
|
15356
|
-
}
|
|
15288
|
+
function nonEmpty(s: MemorySegment | false): s is MemorySegment {
|
|
15289
|
+
return s !== false;
|
|
15357
15290
|
}
|
|
15358
15291
|
|
|
15359
|
-
|
|
15360
|
-
|
|
15361
|
-
|
|
15362
|
-
|
|
15363
|
-
|
|
15364
|
-
|
|
15365
|
-
|
|
15366
|
-
|
|
15292
|
+
const readableMemory = [
|
|
15293
|
+
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
15294
|
+
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
15295
|
+
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
15296
|
+
].filter(nonEmpty);
|
|
15297
|
+
const writeableMemory = [
|
|
15298
|
+
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
15299
|
+
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
15300
|
+
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
15301
|
+
].filter(nonEmpty);
|
|
15367
15302
|
|
|
15368
|
-
|
|
15369
|
-
|
|
15370
|
-
|
|
15371
|
-
|
|
15303
|
+
return new SpiProgram(
|
|
15304
|
+
code,
|
|
15305
|
+
new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart),
|
|
15306
|
+
getRegisters(args.length),
|
|
15307
|
+
);
|
|
15308
|
+
}
|
|
15372
15309
|
|
|
15373
|
-
|
|
15374
|
-
|
|
15375
|
-
|
|
15376
|
-
}
|
|
15310
|
+
declare function getMemorySegment(start: number, end: number, data: Uint8Array | null = null) {
|
|
15311
|
+
return new MemorySegment(start, end, data);
|
|
15312
|
+
}
|
|
15377
15313
|
|
|
15378
|
-
|
|
15379
|
-
|
|
15380
|
-
if (this.isWrapped()) {
|
|
15381
|
-
return address >= this.start || address < this.end;
|
|
15382
|
-
}
|
|
15314
|
+
declare function getRegisters(argsLength: number) {
|
|
15315
|
+
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
15383
15316
|
|
|
15384
|
-
|
|
15385
|
-
|
|
15317
|
+
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
15318
|
+
regs[0] = BigInt(LAST_PAGE);
|
|
15319
|
+
regs[1] = BigInt(STACK_SEGMENT);
|
|
15320
|
+
regs[7] = BigInt(ARGS_SEGMENT);
|
|
15321
|
+
regs[8] = BigInt(argsLength);
|
|
15386
15322
|
|
|
15387
|
-
|
|
15388
|
-
|
|
15389
|
-
if (this.lastIndex === null || other.lastIndex === null) {
|
|
15390
|
-
return false;
|
|
15391
|
-
}
|
|
15323
|
+
return regs;
|
|
15324
|
+
}
|
|
15392
15325
|
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
|
|
15397
|
-
|
|
15398
|
-
|
|
15399
|
-
|
|
15326
|
+
type index$8_MemorySegment = MemorySegment;
|
|
15327
|
+
declare const index$8_MemorySegment: typeof MemorySegment;
|
|
15328
|
+
declare const index$8_NO_OF_REGISTERS: typeof NO_OF_REGISTERS;
|
|
15329
|
+
type index$8_SpiMemory = SpiMemory;
|
|
15330
|
+
declare const index$8_SpiMemory: typeof SpiMemory;
|
|
15331
|
+
type index$8_SpiProgram = SpiProgram;
|
|
15332
|
+
declare const index$8_SpiProgram: typeof SpiProgram;
|
|
15333
|
+
declare const index$8_decodeStandardProgram: typeof decodeStandardProgram;
|
|
15334
|
+
declare const index$8_getMemorySegment: typeof getMemorySegment;
|
|
15335
|
+
declare const index$8_getRegisters: typeof getRegisters;
|
|
15336
|
+
declare namespace index$8 {
|
|
15337
|
+
export {
|
|
15338
|
+
index$8_MemorySegment as MemorySegment,
|
|
15339
|
+
index$8_NO_OF_REGISTERS as NO_OF_REGISTERS,
|
|
15340
|
+
index$8_SpiMemory as SpiMemory,
|
|
15341
|
+
index$8_SpiProgram as SpiProgram,
|
|
15342
|
+
index$8_decodeStandardProgram as decodeStandardProgram,
|
|
15343
|
+
index$8_getMemorySegment as getMemorySegment,
|
|
15344
|
+
index$8_getRegisters as getRegisters,
|
|
15345
|
+
};
|
|
15400
15346
|
}
|
|
15401
15347
|
|
|
15402
|
-
declare
|
|
15403
|
-
|
|
15348
|
+
declare class Program {
|
|
15349
|
+
static fromSpi(blob: Uint8Array, args: Uint8Array, hasMetadata: boolean) {
|
|
15350
|
+
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15351
|
+
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
15352
|
+
const regs = new Registers();
|
|
15353
|
+
regs.copyFrom(registers);
|
|
15354
|
+
const memoryBuilder = new MemoryBuilder();
|
|
15404
15355
|
|
|
15405
|
-
|
|
15406
|
-
|
|
15407
|
-
|
|
15356
|
+
for (const { start, end, data } of rawMemory.readable) {
|
|
15357
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
15358
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
15359
|
+
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15360
|
+
}
|
|
15408
15361
|
|
|
15409
|
-
|
|
15410
|
-
|
|
15362
|
+
for (const { start, end, data } of rawMemory.writeable) {
|
|
15363
|
+
const startIndex = tryAsMemoryIndex(start);
|
|
15364
|
+
const endIndex = tryAsMemoryIndex(end);
|
|
15365
|
+
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15366
|
+
}
|
|
15411
15367
|
|
|
15412
|
-
|
|
15413
|
-
|
|
15414
|
-
|
|
15415
|
-
*
|
|
15416
|
-
* Note that the `res` might be bigger than the number of bytes length, but cannot be smaller.
|
|
15417
|
-
*
|
|
15418
|
-
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
15419
|
-
* NOTE That the `result` might be partially modified in case `PageFault` occurs!
|
|
15420
|
-
*/
|
|
15421
|
-
abstract loadInto(res: Uint8Array, address: PageIndex, length: number): Result$2<OK, PageFault>;
|
|
15368
|
+
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
15369
|
+
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
15370
|
+
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
15422
15371
|
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
*
|
|
15426
|
-
* Returns `null` if copying was successful and [`PageFault`] otherwise.
|
|
15427
|
-
*/
|
|
15428
|
-
abstract storeFrom(address: PageIndex, data: Uint8Array): Result$2<OK, PageFault>;
|
|
15429
|
-
/**
|
|
15430
|
-
* Get dump of the entire page. Should only be used for the debugger-adapter because it
|
|
15431
|
-
* might be inefficient.
|
|
15432
|
-
*/
|
|
15433
|
-
abstract getPageDump(): Uint8Array;
|
|
15372
|
+
return new Program(code, regs, memory, metadata);
|
|
15373
|
+
}
|
|
15434
15374
|
|
|
15435
|
-
|
|
15375
|
+
static fromGeneric(blob: Uint8Array, hasMetadata: boolean) {
|
|
15376
|
+
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15377
|
+
const regs = new Registers();
|
|
15378
|
+
const memory = new Memory();
|
|
15379
|
+
return new Program(code, regs, memory, metadata);
|
|
15380
|
+
}
|
|
15381
|
+
|
|
15382
|
+
private constructor(
|
|
15383
|
+
public readonly code: Uint8Array,
|
|
15384
|
+
public readonly registers: Registers,
|
|
15385
|
+
public readonly memory: Memory,
|
|
15386
|
+
public metadata: Uint8Array = new Uint8Array(),
|
|
15387
|
+
) {}
|
|
15436
15388
|
}
|
|
15437
15389
|
|
|
15438
15390
|
/**
|
|
15439
|
-
*
|
|
15440
|
-
*
|
|
15441
|
-
*
|
|
15391
|
+
* A function that splits preimage into metadata and code.
|
|
15392
|
+
*
|
|
15393
|
+
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
15442
15394
|
*/
|
|
15443
|
-
declare
|
|
15444
|
-
|
|
15445
|
-
|
|
15446
|
-
|
|
15447
|
-
|
|
15448
|
-
}
|
|
15449
|
-
interface ArrayBuffer {
|
|
15450
|
-
resize(length: number): void;
|
|
15451
|
-
}
|
|
15395
|
+
declare function extractCodeAndMetadata(blobWithMetadata: Uint8Array) {
|
|
15396
|
+
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
15397
|
+
const metadata = decoder.bytesBlob().raw;
|
|
15398
|
+
const code = decoder.remainingBytes().raw;
|
|
15399
|
+
return { metadata, code };
|
|
15452
15400
|
}
|
|
15453
15401
|
|
|
15454
|
-
type
|
|
15455
|
-
|
|
15456
|
-
|
|
15457
|
-
|
|
15458
|
-
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
WRITE = 1,
|
|
15402
|
+
type index$7_Program = Program;
|
|
15403
|
+
declare const index$7_Program: typeof Program;
|
|
15404
|
+
declare const index$7_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
15405
|
+
declare namespace index$7 {
|
|
15406
|
+
export {
|
|
15407
|
+
index$7_Program as Program,
|
|
15408
|
+
index$7_extractCodeAndMetadata as extractCodeAndMetadata,
|
|
15409
|
+
};
|
|
15463
15410
|
}
|
|
15464
15411
|
|
|
15465
|
-
|
|
15466
|
-
|
|
15467
|
-
|
|
15468
|
-
|
|
15469
|
-
|
|
15470
|
-
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15475
|
-
|
|
15476
|
-
|
|
15477
|
-
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
this.
|
|
15486
|
-
this.memory = new Map<PageNumber, MemoryPage>(); // TODO [MaSi]: We should keep allocated pages somewhere and reuse it when it is possible
|
|
15487
|
-
}
|
|
15488
|
-
|
|
15489
|
-
copyFrom(memory: Memory) {
|
|
15490
|
-
this.sbrkIndex = memory.sbrkIndex;
|
|
15491
|
-
this.virtualSbrkIndex = memory.virtualSbrkIndex;
|
|
15492
|
-
this.endHeapIndex = memory.endHeapIndex;
|
|
15493
|
-
this.memory = memory.memory;
|
|
15412
|
+
/**
|
|
15413
|
+
* Mask class is an implementation of skip function defined in GP.
|
|
15414
|
+
*
|
|
15415
|
+
* https://graypaper.fluffylabs.dev/#/5f542d7/237201239801
|
|
15416
|
+
*/
|
|
15417
|
+
declare class Mask {
|
|
15418
|
+
/**
|
|
15419
|
+
* The lookup table will have `0` at the index which corresponds to an instruction on the same index in the bytecode.
|
|
15420
|
+
* In case the value is non-zero it signifies the offset to the index with next instruction.
|
|
15421
|
+
*
|
|
15422
|
+
* Example:
|
|
15423
|
+
* ```
|
|
15424
|
+
* 0..1..2..3..4..5..6..7..8..9 # Indices
|
|
15425
|
+
* 0..2..1..0..1..0..3..2..1..0 # lookupTable forward values
|
|
15426
|
+
* ```
|
|
15427
|
+
* There are instructions at indices `0, 3, 5, 9`.
|
|
15428
|
+
*/
|
|
15429
|
+
private lookupTableForward: Uint8Array;
|
|
15430
|
+
|
|
15431
|
+
constructor(mask: BitVec) {
|
|
15432
|
+
this.lookupTableForward = this.buildLookupTableForward(mask);
|
|
15494
15433
|
}
|
|
15495
15434
|
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
}
|
|
15435
|
+
isInstruction(index: number) {
|
|
15436
|
+
return this.lookupTableForward[index] === 0;
|
|
15437
|
+
}
|
|
15500
15438
|
|
|
15501
|
-
|
|
15502
|
-
|
|
15439
|
+
getNoOfBytesToNextInstruction(index: number) {
|
|
15440
|
+
check`${index >= 0} index (${index}) cannot be a negative number`;
|
|
15441
|
+
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
15442
|
+
}
|
|
15503
15443
|
|
|
15504
|
-
|
|
15505
|
-
|
|
15444
|
+
private buildLookupTableForward(mask: BitVec) {
|
|
15445
|
+
const table = safeAllocUint8Array(mask.bitLength);
|
|
15446
|
+
let lastInstructionOffset = 0;
|
|
15447
|
+
for (let i = mask.bitLength - 1; i >= 0; i--) {
|
|
15448
|
+
if (mask.isSet(i)) {
|
|
15449
|
+
lastInstructionOffset = 0;
|
|
15450
|
+
} else {
|
|
15451
|
+
lastInstructionOffset++;
|
|
15452
|
+
}
|
|
15453
|
+
table[i] = lastInstructionOffset;
|
|
15506
15454
|
}
|
|
15455
|
+
return table;
|
|
15456
|
+
}
|
|
15507
15457
|
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15458
|
+
static empty() {
|
|
15459
|
+
return new Mask(BitVec.empty(0));
|
|
15460
|
+
}
|
|
15461
|
+
}
|
|
15511
15462
|
|
|
15512
|
-
|
|
15513
|
-
|
|
15514
|
-
|
|
15515
|
-
|
|
15516
|
-
|
|
15463
|
+
declare enum ArgumentType {
|
|
15464
|
+
NO_ARGUMENTS = 0,
|
|
15465
|
+
ONE_IMMEDIATE = 1,
|
|
15466
|
+
TWO_IMMEDIATES = 2,
|
|
15467
|
+
ONE_OFFSET = 3,
|
|
15468
|
+
ONE_REGISTER_ONE_IMMEDIATE = 4,
|
|
15469
|
+
ONE_REGISTER_TWO_IMMEDIATES = 5,
|
|
15470
|
+
ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET = 6,
|
|
15471
|
+
TWO_REGISTERS = 7,
|
|
15472
|
+
TWO_REGISTERS_ONE_IMMEDIATE = 8,
|
|
15473
|
+
TWO_REGISTERS_ONE_OFFSET = 9,
|
|
15474
|
+
TWO_REGISTERS_TWO_IMMEDIATES = 10,
|
|
15475
|
+
THREE_REGISTERS = 11,
|
|
15476
|
+
ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE = 12,
|
|
15477
|
+
}
|
|
15517
15478
|
|
|
15518
|
-
|
|
15479
|
+
declare class ExtendedWitdthImmediateDecoder {
|
|
15480
|
+
private unsignedImmediate: BigUint64Array;
|
|
15481
|
+
private bytes: Uint8Array;
|
|
15519
15482
|
|
|
15520
|
-
|
|
15521
|
-
|
|
15522
|
-
|
|
15523
|
-
|
|
15483
|
+
constructor() {
|
|
15484
|
+
const buffer = new ArrayBuffer(IMMEDIATE_SIZE);
|
|
15485
|
+
this.unsignedImmediate = new BigUint64Array(buffer);
|
|
15486
|
+
this.bytes = new Uint8Array(buffer);
|
|
15524
15487
|
}
|
|
15525
15488
|
|
|
15526
|
-
|
|
15527
|
-
|
|
15528
|
-
|
|
15489
|
+
setBytes(bytes: Uint8Array) {
|
|
15490
|
+
let i = 0;
|
|
15491
|
+
for (; i < bytes.length; i++) {
|
|
15492
|
+
this.bytes[i] = bytes[i];
|
|
15529
15493
|
}
|
|
15530
15494
|
|
|
15531
|
-
|
|
15532
|
-
|
|
15495
|
+
for (; i < IMMEDIATE_SIZE; i++) {
|
|
15496
|
+
this.bytes[i] = 0;
|
|
15497
|
+
}
|
|
15498
|
+
}
|
|
15533
15499
|
|
|
15534
|
-
|
|
15500
|
+
getValue() {
|
|
15501
|
+
return this.unsignedImmediate[0];
|
|
15502
|
+
}
|
|
15535
15503
|
|
|
15536
|
-
|
|
15537
|
-
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
() => `Page fault: attempted to access reserved page ${pageNumber}`,
|
|
15541
|
-
);
|
|
15542
|
-
}
|
|
15504
|
+
getBytesAsLittleEndian() {
|
|
15505
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE);
|
|
15506
|
+
}
|
|
15507
|
+
}
|
|
15543
15508
|
|
|
15544
|
-
|
|
15509
|
+
declare class ImmediateDecoder {
|
|
15510
|
+
private u32: Uint32Array;
|
|
15511
|
+
private i32: Int32Array;
|
|
15512
|
+
private u64: BigUint64Array;
|
|
15513
|
+
private i64: BigInt64Array;
|
|
15514
|
+
private view: DataView;
|
|
15515
|
+
private bytes: Uint8Array;
|
|
15545
15516
|
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
|
|
15517
|
+
constructor() {
|
|
15518
|
+
const buffer = new ArrayBuffer(BUFFER_SIZE);
|
|
15519
|
+
this.u32 = new Uint32Array(buffer);
|
|
15520
|
+
this.i32 = new Int32Array(buffer);
|
|
15521
|
+
this.u64 = new BigUint64Array(buffer);
|
|
15522
|
+
this.i64 = new BigInt64Array(buffer);
|
|
15523
|
+
this.view = new DataView(buffer);
|
|
15524
|
+
this.bytes = new Uint8Array(buffer);
|
|
15525
|
+
}
|
|
15549
15526
|
|
|
15550
|
-
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15555
|
-
}
|
|
15527
|
+
setBytes(bytes: Uint8Array) {
|
|
15528
|
+
const n = bytes.length;
|
|
15529
|
+
const msb = n > 0 ? bytes[n - 1] & 0x80 : 0;
|
|
15530
|
+
const noOfBytes = Math.min(n, BUFFER_SIZE);
|
|
15531
|
+
const prefix = msb !== 0 ? 0xff : 0x00;
|
|
15556
15532
|
|
|
15557
|
-
|
|
15533
|
+
for (let i = 0; i < noOfBytes; i++) {
|
|
15534
|
+
this.view.setUint8(i, bytes[i]);
|
|
15558
15535
|
}
|
|
15559
15536
|
|
|
15560
|
-
|
|
15537
|
+
for (let i = n; i < BUFFER_SIZE; i++) {
|
|
15538
|
+
this.view.setUint8(i, prefix);
|
|
15539
|
+
}
|
|
15561
15540
|
}
|
|
15541
|
+
|
|
15562
15542
|
/**
|
|
15563
|
-
*
|
|
15564
|
-
* write the result into the `result` buffer.
|
|
15565
|
-
*
|
|
15566
|
-
* Returns `null` if the data was read successfully or `PageFault` otherwise.
|
|
15543
|
+
* @deprecated Use getU32 instead
|
|
15567
15544
|
*/
|
|
15568
|
-
|
|
15569
|
-
|
|
15570
|
-
|
|
15571
|
-
}
|
|
15572
|
-
|
|
15573
|
-
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
15574
|
-
|
|
15575
|
-
if (pagesResult.isError) {
|
|
15576
|
-
return Result.error(pagesResult.error, pagesResult.details);
|
|
15577
|
-
}
|
|
15578
|
-
|
|
15579
|
-
const pages = pagesResult.ok;
|
|
15580
|
-
|
|
15581
|
-
let currentPosition: number = startAddress;
|
|
15582
|
-
let bytesLeft = result.length;
|
|
15583
|
-
|
|
15584
|
-
for (const page of pages) {
|
|
15585
|
-
const pageStartIndex = tryAsPageIndex(currentPosition % PAGE_SIZE);
|
|
15586
|
-
const bytesToRead = Math.min(PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15587
|
-
const destinationStartIndex = currentPosition - startAddress;
|
|
15588
|
-
const destination = result.subarray(destinationStartIndex);
|
|
15545
|
+
getUnsigned() {
|
|
15546
|
+
return this.u32[U32_INDEX];
|
|
15547
|
+
}
|
|
15589
15548
|
|
|
15590
|
-
|
|
15549
|
+
/**
|
|
15550
|
+
* @deprecated Use getI32 instead
|
|
15551
|
+
*/
|
|
15552
|
+
getSigned() {
|
|
15553
|
+
return this.i32[U32_INDEX];
|
|
15554
|
+
}
|
|
15591
15555
|
|
|
15592
|
-
|
|
15593
|
-
|
|
15594
|
-
|
|
15556
|
+
getU32(): number {
|
|
15557
|
+
return this.u32[U32_INDEX];
|
|
15558
|
+
}
|
|
15595
15559
|
|
|
15596
|
-
|
|
15597
|
-
return
|
|
15560
|
+
getI32(): number {
|
|
15561
|
+
return this.i32[U32_INDEX];
|
|
15598
15562
|
}
|
|
15599
15563
|
|
|
15600
|
-
|
|
15601
|
-
|
|
15602
|
-
|
|
15564
|
+
getU64(): bigint {
|
|
15565
|
+
return this.u64[U64_INDEX];
|
|
15566
|
+
}
|
|
15603
15567
|
|
|
15604
|
-
|
|
15605
|
-
|
|
15606
|
-
|
|
15607
|
-
}
|
|
15568
|
+
getI64(): bigint {
|
|
15569
|
+
return this.i64[U64_INDEX];
|
|
15570
|
+
}
|
|
15608
15571
|
|
|
15609
|
-
|
|
15572
|
+
getBytesAsLittleEndian() {
|
|
15573
|
+
return this.bytes.subarray(0, IMMEDIATE_SIZE);
|
|
15574
|
+
}
|
|
15610
15575
|
|
|
15611
|
-
|
|
15612
|
-
|
|
15613
|
-
|
|
15614
|
-
|
|
15615
|
-
}
|
|
15576
|
+
getExtendedBytesAsLittleEndian() {
|
|
15577
|
+
return this.bytes;
|
|
15578
|
+
}
|
|
15579
|
+
}
|
|
15616
15580
|
|
|
15617
|
-
|
|
15618
|
-
|
|
15619
|
-
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
15620
|
-
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15621
|
-
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / PAGE_SIZE;
|
|
15622
|
-
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
15581
|
+
declare class NibblesDecoder {
|
|
15582
|
+
private byte = new Int8Array(1);
|
|
15623
15583
|
|
|
15624
|
-
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
}
|
|
15584
|
+
setByte(byte: number) {
|
|
15585
|
+
this.byte[0] = byte;
|
|
15586
|
+
}
|
|
15628
15587
|
|
|
15629
|
-
|
|
15630
|
-
this.
|
|
15631
|
-
return currentVirtualSbrkIndex;
|
|
15588
|
+
getHighNibble() {
|
|
15589
|
+
return (this.byte[0] & 0xf0) >>> 4;
|
|
15632
15590
|
}
|
|
15633
15591
|
|
|
15634
|
-
|
|
15635
|
-
|
|
15636
|
-
return page?.getPageDump() ?? null;
|
|
15592
|
+
getLowNibble() {
|
|
15593
|
+
return this.byte[0] & 0x0f;
|
|
15637
15594
|
}
|
|
15638
15595
|
|
|
15639
|
-
|
|
15640
|
-
return this.
|
|
15596
|
+
getHighNibbleAsRegisterIndex() {
|
|
15597
|
+
return Math.min(this.getHighNibble(), MAX_REGISTER_INDEX);
|
|
15641
15598
|
}
|
|
15642
|
-
}
|
|
15643
15599
|
|
|
15644
|
-
|
|
15645
|
-
|
|
15646
|
-
|
|
15600
|
+
getLowNibbleAsRegisterIndex() {
|
|
15601
|
+
return Math.min(this.getLowNibble(), MAX_REGISTER_INDEX);
|
|
15602
|
+
}
|
|
15647
15603
|
|
|
15648
|
-
|
|
15649
|
-
|
|
15650
|
-
throw new FinalizedBuilderModification();
|
|
15651
|
-
}
|
|
15604
|
+
getHighNibbleAsLength() {
|
|
15605
|
+
return Math.min(this.getHighNibble(), MAX_LENGTH);
|
|
15652
15606
|
}
|
|
15653
15607
|
|
|
15654
|
-
|
|
15655
|
-
|
|
15656
|
-
throw new ReservedMemoryFault();
|
|
15657
|
-
}
|
|
15608
|
+
getLowNibbleAsLength() {
|
|
15609
|
+
return Math.min(this.getLowNibble(), MAX_LENGTH);
|
|
15658
15610
|
}
|
|
15611
|
+
}
|
|
15659
15612
|
|
|
15660
|
-
|
|
15661
|
-
|
|
15662
|
-
|
|
15663
|
-
|
|
15664
|
-
* they need to be the start indices of the pages.
|
|
15665
|
-
*
|
|
15666
|
-
* The data passed will be placed at `start`, but might be shorter than the requested range,
|
|
15667
|
-
* prepend it with zeros if you don't wish to have it at the beginning of the page.
|
|
15668
|
-
*/
|
|
15669
|
-
setReadablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15670
|
-
this.ensureNotFinalized();
|
|
15671
|
-
check`${start < end} end has to be bigger than start`;
|
|
15672
|
-
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15673
|
-
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15674
|
-
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15613
|
+
type EmptyArgs = {
|
|
15614
|
+
type: ArgumentType.NO_ARGUMENTS;
|
|
15615
|
+
noOfBytesToSkip: number;
|
|
15616
|
+
};
|
|
15675
15617
|
|
|
15676
|
-
|
|
15677
|
-
|
|
15618
|
+
type OneImmediateArgs = {
|
|
15619
|
+
type: ArgumentType.ONE_IMMEDIATE;
|
|
15620
|
+
noOfBytesToSkip: number;
|
|
15621
|
+
/** V_X */
|
|
15622
|
+
immediateDecoder: ImmediateDecoder;
|
|
15623
|
+
};
|
|
15678
15624
|
|
|
15679
|
-
|
|
15625
|
+
type ThreeRegistersArgs = {
|
|
15626
|
+
type: ArgumentType.THREE_REGISTERS;
|
|
15627
|
+
noOfBytesToSkip: number;
|
|
15628
|
+
/** W_A */
|
|
15629
|
+
firstRegisterIndex: number;
|
|
15630
|
+
/** W_B */
|
|
15631
|
+
secondRegisterIndex: number;
|
|
15632
|
+
/** W_D */
|
|
15633
|
+
thirdRegisterIndex: number;
|
|
15634
|
+
};
|
|
15680
15635
|
|
|
15681
|
-
|
|
15682
|
-
|
|
15636
|
+
type TwoRegistersArgs = {
|
|
15637
|
+
type: ArgumentType.TWO_REGISTERS;
|
|
15638
|
+
noOfBytesToSkip: number;
|
|
15639
|
+
/** W_A */
|
|
15640
|
+
firstRegisterIndex: number;
|
|
15641
|
+
/** W_D */
|
|
15642
|
+
secondRegisterIndex: number;
|
|
15643
|
+
};
|
|
15683
15644
|
|
|
15684
|
-
|
|
15685
|
-
|
|
15686
|
-
|
|
15687
|
-
|
|
15688
|
-
|
|
15689
|
-
|
|
15645
|
+
type TwoRegistersOneImmediateArgs = {
|
|
15646
|
+
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15647
|
+
noOfBytesToSkip: number;
|
|
15648
|
+
/** W_A */
|
|
15649
|
+
firstRegisterIndex: number;
|
|
15650
|
+
/** W_B */
|
|
15651
|
+
secondRegisterIndex: number;
|
|
15652
|
+
/** V_X */
|
|
15653
|
+
immediateDecoder: ImmediateDecoder;
|
|
15654
|
+
};
|
|
15690
15655
|
|
|
15691
|
-
|
|
15692
|
-
|
|
15656
|
+
type OneRegisterOneImmediateArgs = {
|
|
15657
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
15658
|
+
noOfBytesToSkip: number;
|
|
15659
|
+
/** W_A */
|
|
15660
|
+
registerIndex: number;
|
|
15661
|
+
/** V_X */
|
|
15662
|
+
immediateDecoder: ImmediateDecoder;
|
|
15663
|
+
};
|
|
15693
15664
|
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
|
|
15699
|
-
|
|
15700
|
-
|
|
15701
|
-
|
|
15702
|
-
*/
|
|
15703
|
-
setWriteablePages(start: MemoryIndex, end: MemoryIndex, data: Uint8Array = new Uint8Array()) {
|
|
15704
|
-
this.ensureNotFinalized();
|
|
15705
|
-
check`${start < end} end has to be bigger than start`;
|
|
15706
|
-
check`${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15707
|
-
check`${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15708
|
-
check`${data.length <= end - start} the initial data is longer than address range`;
|
|
15665
|
+
type OneRegisterOneExtendedWidthImmediateArgs = {
|
|
15666
|
+
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
15667
|
+
noOfBytesToSkip: number;
|
|
15668
|
+
/** W_A */
|
|
15669
|
+
registerIndex: number;
|
|
15670
|
+
/** V_X */
|
|
15671
|
+
immediateDecoder: ExtendedWitdthImmediateDecoder;
|
|
15672
|
+
};
|
|
15709
15673
|
|
|
15710
|
-
|
|
15711
|
-
|
|
15674
|
+
type TwoRegistersTwoImmediatesArgs = {
|
|
15675
|
+
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
15676
|
+
noOfBytesToSkip: number;
|
|
15677
|
+
/** W_A */
|
|
15678
|
+
firstRegisterIndex: number;
|
|
15679
|
+
/** W_B */
|
|
15680
|
+
secondRegisterIndex: number;
|
|
15681
|
+
/** V_X */
|
|
15682
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15683
|
+
/** V_Y */
|
|
15684
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15685
|
+
};
|
|
15712
15686
|
|
|
15713
|
-
|
|
15687
|
+
type TwoImmediatesArgs = {
|
|
15688
|
+
type: ArgumentType.TWO_IMMEDIATES;
|
|
15689
|
+
noOfBytesToSkip: number;
|
|
15690
|
+
/** V_X */
|
|
15691
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15692
|
+
/** V_Y */
|
|
15693
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15694
|
+
};
|
|
15714
15695
|
|
|
15715
|
-
|
|
15716
|
-
|
|
15696
|
+
type TwoRegistersOneOffsetArgs = {
|
|
15697
|
+
type: ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15698
|
+
noOfBytesToSkip: number;
|
|
15699
|
+
/** W_A */
|
|
15700
|
+
firstRegisterIndex: number;
|
|
15701
|
+
/** W_B */
|
|
15702
|
+
secondRegisterIndex: number;
|
|
15703
|
+
nextPc: number;
|
|
15704
|
+
};
|
|
15717
15705
|
|
|
15718
|
-
|
|
15719
|
-
|
|
15720
|
-
|
|
15721
|
-
|
|
15722
|
-
|
|
15723
|
-
|
|
15706
|
+
type OneRegisterOneImmediateOneOffsetArgs = {
|
|
15707
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
15708
|
+
noOfBytesToSkip: number;
|
|
15709
|
+
/** W_A */
|
|
15710
|
+
registerIndex: number;
|
|
15711
|
+
/** V_X */
|
|
15712
|
+
immediateDecoder: ImmediateDecoder;
|
|
15713
|
+
/** V_Y */
|
|
15714
|
+
nextPc: number;
|
|
15715
|
+
};
|
|
15724
15716
|
|
|
15725
|
-
|
|
15717
|
+
type OneRegisterTwoImmediatesArgs = {
|
|
15718
|
+
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
15719
|
+
noOfBytesToSkip: number;
|
|
15720
|
+
/** W_A */
|
|
15721
|
+
registerIndex: number;
|
|
15722
|
+
/** V_X */
|
|
15723
|
+
firstImmediateDecoder: ImmediateDecoder;
|
|
15724
|
+
/** V_Y */
|
|
15725
|
+
secondImmediateDecoder: ImmediateDecoder;
|
|
15726
|
+
};
|
|
15727
|
+
|
|
15728
|
+
type OneOffsetArgs = {
|
|
15729
|
+
type: ArgumentType.ONE_OFFSET;
|
|
15730
|
+
noOfBytesToSkip: number;
|
|
15731
|
+
/** V_X */
|
|
15732
|
+
nextPc: number;
|
|
15733
|
+
};
|
|
15734
|
+
|
|
15735
|
+
type Args =
|
|
15736
|
+
| EmptyArgs
|
|
15737
|
+
| OneImmediateArgs
|
|
15738
|
+
| TwoRegistersArgs
|
|
15739
|
+
| ThreeRegistersArgs
|
|
15740
|
+
| TwoRegistersOneImmediateArgs
|
|
15741
|
+
| TwoRegistersTwoImmediatesArgs
|
|
15742
|
+
| OneRegisterOneImmediateOneOffsetArgs
|
|
15743
|
+
| TwoRegistersOneOffsetArgs
|
|
15744
|
+
| OneRegisterOneImmediateArgs
|
|
15745
|
+
| OneOffsetArgs
|
|
15746
|
+
| TwoImmediatesArgs
|
|
15747
|
+
| OneRegisterTwoImmediatesArgs
|
|
15748
|
+
| OneRegisterOneExtendedWidthImmediateArgs;
|
|
15749
|
+
|
|
15750
|
+
declare class ArgsDecoder {
|
|
15751
|
+
private nibblesDecoder = new NibblesDecoder();
|
|
15752
|
+
private offsetDecoder = new ImmediateDecoder();
|
|
15753
|
+
private code: Uint8Array = new Uint8Array();
|
|
15754
|
+
private mask: Mask = Mask.empty();
|
|
15755
|
+
|
|
15756
|
+
reset(code: Uint8Array, mask: Mask) {
|
|
15757
|
+
this.code = code;
|
|
15758
|
+
this.mask = mask;
|
|
15726
15759
|
}
|
|
15727
15760
|
|
|
15728
|
-
|
|
15729
|
-
|
|
15730
|
-
|
|
15731
|
-
*/
|
|
15732
|
-
setData(start: MemoryIndex, data: Uint8Array) {
|
|
15733
|
-
this.ensureNotFinalized();
|
|
15734
|
-
const pageOffset = start % PAGE_SIZE;
|
|
15735
|
-
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15736
|
-
check`${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15761
|
+
fillArgs<T extends Args>(pc: number, result: T): void {
|
|
15762
|
+
const nextInstructionDistance = 1 + this.mask.getNoOfBytesToNextInstruction(pc + 1);
|
|
15763
|
+
result.noOfBytesToSkip = nextInstructionDistance;
|
|
15737
15764
|
|
|
15738
|
-
|
|
15739
|
-
|
|
15765
|
+
switch (result.type) {
|
|
15766
|
+
case ArgumentType.NO_ARGUMENTS:
|
|
15767
|
+
break;
|
|
15768
|
+
|
|
15769
|
+
case ArgumentType.ONE_IMMEDIATE: {
|
|
15770
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
15771
|
+
const argsStartIndex = pc + 1;
|
|
15772
|
+
result.immediateDecoder.setBytes(this.code.subarray(argsStartIndex, argsStartIndex + immediateLength));
|
|
15773
|
+
break;
|
|
15774
|
+
}
|
|
15775
|
+
|
|
15776
|
+
case ArgumentType.THREE_REGISTERS: {
|
|
15777
|
+
const firstByte = this.code[pc + 1];
|
|
15778
|
+
const secondByte = this.code[pc + 2];
|
|
15779
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15780
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15781
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15782
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
15783
|
+
result.thirdRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15784
|
+
break;
|
|
15785
|
+
}
|
|
15786
|
+
|
|
15787
|
+
case ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE: {
|
|
15788
|
+
const firstByte = this.code[pc + 1];
|
|
15789
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15790
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15791
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15792
|
+
|
|
15793
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15794
|
+
const immediateStartIndex = pc + 2;
|
|
15795
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15796
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
15797
|
+
break;
|
|
15798
|
+
}
|
|
15799
|
+
|
|
15800
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET: {
|
|
15801
|
+
const firstByte = this.code[pc + 1];
|
|
15802
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15803
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15804
|
+
|
|
15805
|
+
const immediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
15806
|
+
const immediateStartIndex = pc + 2;
|
|
15807
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15808
|
+
result.immediateDecoder.setBytes(this.code.subarray(immediateStartIndex, immediateEndIndex));
|
|
15809
|
+
|
|
15810
|
+
const offsetLength = Math.min(
|
|
15811
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
15812
|
+
Math.max(0, nextInstructionDistance - 2 - immediateLength),
|
|
15813
|
+
);
|
|
15814
|
+
const offsetStartIndex = pc + 2 + immediateLength;
|
|
15815
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15816
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15817
|
+
|
|
15818
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
15819
|
+
break;
|
|
15820
|
+
}
|
|
15821
|
+
|
|
15822
|
+
case ArgumentType.TWO_REGISTERS_ONE_OFFSET: {
|
|
15823
|
+
const firstByte = this.code[pc + 1];
|
|
15824
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15825
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15826
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15827
|
+
|
|
15828
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15829
|
+
const offsetStartIndex = pc + 2;
|
|
15830
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15831
|
+
this.offsetDecoder.setBytes(this.code.subarray(offsetStartIndex, offsetEndIndex));
|
|
15832
|
+
|
|
15833
|
+
result.nextPc = pc + this.offsetDecoder.getSigned();
|
|
15834
|
+
break;
|
|
15835
|
+
}
|
|
15836
|
+
|
|
15837
|
+
case ArgumentType.TWO_REGISTERS: {
|
|
15838
|
+
const firstByte = this.code[pc + 1];
|
|
15839
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15840
|
+
result.firstRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15841
|
+
result.secondRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15842
|
+
break;
|
|
15843
|
+
}
|
|
15844
|
+
|
|
15845
|
+
case ArgumentType.ONE_OFFSET: {
|
|
15846
|
+
const offsetLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, nextInstructionDistance - 1);
|
|
15847
|
+
const offsetStartIndex = pc + 1;
|
|
15848
|
+
const offsetEndIndex = offsetStartIndex + offsetLength;
|
|
15849
|
+
const offsetBytes = this.code.subarray(offsetStartIndex, offsetEndIndex);
|
|
15850
|
+
this.offsetDecoder.setBytes(offsetBytes);
|
|
15851
|
+
const offsetValue = this.offsetDecoder.getSigned();
|
|
15852
|
+
result.nextPc = pc + offsetValue;
|
|
15853
|
+
break;
|
|
15854
|
+
}
|
|
15855
|
+
|
|
15856
|
+
case ArgumentType.ONE_REGISTER_ONE_IMMEDIATE: {
|
|
15857
|
+
const firstByte = this.code[pc + 1];
|
|
15858
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15859
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15860
|
+
|
|
15861
|
+
const immediateLength = Math.min(IMMEDIATE_AND_OFFSET_MAX_LENGTH, Math.max(0, nextInstructionDistance - 2));
|
|
15862
|
+
const immediateStartIndex = pc + 2;
|
|
15863
|
+
const immediateEndIndex = immediateStartIndex + immediateLength;
|
|
15864
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
15865
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
15866
|
+
break;
|
|
15867
|
+
}
|
|
15868
|
+
|
|
15869
|
+
case ArgumentType.TWO_IMMEDIATES: {
|
|
15870
|
+
const firstByte = this.code[pc + 1];
|
|
15871
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15872
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
15873
|
+
const firstImmediateStartIndex = pc + 2;
|
|
15874
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
15875
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
15876
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15877
|
+
|
|
15878
|
+
const secondImmediateLength = Math.min(
|
|
15879
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
15880
|
+
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
15881
|
+
);
|
|
15882
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
15883
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
15884
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
15885
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
15886
|
+
break;
|
|
15887
|
+
}
|
|
15888
|
+
|
|
15889
|
+
case ArgumentType.ONE_REGISTER_TWO_IMMEDIATES: {
|
|
15890
|
+
const firstByte = this.code[pc + 1];
|
|
15891
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15892
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15893
|
+
|
|
15894
|
+
const firstImmediateLength = this.nibblesDecoder.getHighNibbleAsLength();
|
|
15895
|
+
const firstImmediateStartIndex = pc + 2;
|
|
15896
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
15897
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
15898
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15899
|
+
|
|
15900
|
+
const secondImmediateLength = Math.min(
|
|
15901
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
15902
|
+
Math.max(0, nextInstructionDistance - 2 - firstImmediateLength),
|
|
15903
|
+
);
|
|
15904
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
15905
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
15906
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
15907
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
15908
|
+
break;
|
|
15909
|
+
}
|
|
15910
|
+
|
|
15911
|
+
case ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES: {
|
|
15912
|
+
const firstByte = this.code[pc + 1];
|
|
15913
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15914
|
+
result.firstRegisterIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15915
|
+
result.secondRegisterIndex = this.nibblesDecoder.getHighNibbleAsRegisterIndex();
|
|
15916
|
+
|
|
15917
|
+
const secondByte = this.code[pc + 2];
|
|
15918
|
+
this.nibblesDecoder.setByte(secondByte);
|
|
15919
|
+
const firstImmediateLength = this.nibblesDecoder.getLowNibbleAsLength();
|
|
15920
|
+
const firstImmediateStartIndex = pc + 3;
|
|
15921
|
+
const firstImmediateEndIndex = firstImmediateStartIndex + firstImmediateLength;
|
|
15922
|
+
const firstImmediateBytes = this.code.subarray(firstImmediateStartIndex, firstImmediateEndIndex);
|
|
15923
|
+
result.firstImmediateDecoder.setBytes(firstImmediateBytes);
|
|
15924
|
+
|
|
15925
|
+
const secondImmediateLength = Math.min(
|
|
15926
|
+
IMMEDIATE_AND_OFFSET_MAX_LENGTH,
|
|
15927
|
+
Math.max(0, nextInstructionDistance - 3 - firstImmediateLength),
|
|
15928
|
+
);
|
|
15929
|
+
const secondImmediateStartIndex = firstImmediateEndIndex;
|
|
15930
|
+
const secondImmediateEndIndex = secondImmediateStartIndex + secondImmediateLength;
|
|
15931
|
+
const secondImmediateBytes = this.code.subarray(secondImmediateStartIndex, secondImmediateEndIndex);
|
|
15932
|
+
result.secondImmediateDecoder.setBytes(secondImmediateBytes);
|
|
15933
|
+
break;
|
|
15934
|
+
}
|
|
15935
|
+
|
|
15936
|
+
case ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE: {
|
|
15937
|
+
const firstByte = this.code[pc + 1];
|
|
15938
|
+
this.nibblesDecoder.setByte(firstByte);
|
|
15939
|
+
result.registerIndex = this.nibblesDecoder.getLowNibbleAsRegisterIndex();
|
|
15940
|
+
|
|
15941
|
+
const immediateStartIndex = pc + 2;
|
|
15942
|
+
const immediateEndIndex = immediateStartIndex + 8;
|
|
15943
|
+
const immediateBytes = this.code.subarray(immediateStartIndex, immediateEndIndex);
|
|
15944
|
+
result.immediateDecoder.setBytes(immediateBytes);
|
|
15945
|
+
break;
|
|
15946
|
+
}
|
|
15947
|
+
}
|
|
15948
|
+
}
|
|
15949
|
+
}
|
|
15950
|
+
|
|
15951
|
+
declare const createResults = () => {
|
|
15952
|
+
const results = new Array(ARGUMENT_TYPE_LENGTH) as Results;
|
|
15953
|
+
|
|
15954
|
+
results[ArgumentType.NO_ARGUMENTS] = {
|
|
15955
|
+
type: ArgumentType.NO_ARGUMENTS,
|
|
15956
|
+
noOfBytesToSkip: 1,
|
|
15957
|
+
};
|
|
15958
|
+
|
|
15959
|
+
results[ArgumentType.ONE_IMMEDIATE] = {
|
|
15960
|
+
type: ArgumentType.ONE_IMMEDIATE,
|
|
15961
|
+
noOfBytesToSkip: 1,
|
|
15962
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
15963
|
+
};
|
|
15964
|
+
|
|
15965
|
+
results[ArgumentType.TWO_REGISTERS] = {
|
|
15966
|
+
type: ArgumentType.TWO_REGISTERS,
|
|
15967
|
+
noOfBytesToSkip: 1,
|
|
15968
|
+
firstRegisterIndex: 0,
|
|
15969
|
+
secondRegisterIndex: 0,
|
|
15970
|
+
};
|
|
15971
|
+
|
|
15972
|
+
results[ArgumentType.THREE_REGISTERS] = {
|
|
15973
|
+
type: ArgumentType.THREE_REGISTERS,
|
|
15974
|
+
noOfBytesToSkip: 1,
|
|
15975
|
+
firstRegisterIndex: 0,
|
|
15976
|
+
secondRegisterIndex: 0,
|
|
15977
|
+
thirdRegisterIndex: 0,
|
|
15978
|
+
};
|
|
15979
|
+
|
|
15980
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET] = {
|
|
15981
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET,
|
|
15982
|
+
noOfBytesToSkip: 1,
|
|
15983
|
+
registerIndex: 0,
|
|
15984
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
15985
|
+
nextPc: 0,
|
|
15986
|
+
};
|
|
15987
|
+
|
|
15988
|
+
results[ArgumentType.TWO_REGISTERS_ONE_OFFSET] = {
|
|
15989
|
+
type: ArgumentType.TWO_REGISTERS_ONE_OFFSET,
|
|
15990
|
+
noOfBytesToSkip: 1,
|
|
15991
|
+
firstRegisterIndex: 0,
|
|
15992
|
+
secondRegisterIndex: 0,
|
|
15993
|
+
nextPc: 0,
|
|
15994
|
+
};
|
|
15995
|
+
|
|
15996
|
+
results[ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE] = {
|
|
15997
|
+
type: ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE,
|
|
15998
|
+
noOfBytesToSkip: 1,
|
|
15999
|
+
firstRegisterIndex: 0,
|
|
16000
|
+
secondRegisterIndex: 0,
|
|
16001
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16002
|
+
};
|
|
16003
|
+
|
|
16004
|
+
results[ArgumentType.ONE_REGISTER_ONE_IMMEDIATE] = {
|
|
16005
|
+
type: ArgumentType.ONE_REGISTER_ONE_IMMEDIATE,
|
|
16006
|
+
noOfBytesToSkip: 1,
|
|
16007
|
+
registerIndex: 0,
|
|
16008
|
+
immediateDecoder: new ImmediateDecoder(),
|
|
16009
|
+
};
|
|
16010
|
+
|
|
16011
|
+
results[ArgumentType.ONE_REGISTER_TWO_IMMEDIATES] = {
|
|
16012
|
+
type: ArgumentType.ONE_REGISTER_TWO_IMMEDIATES,
|
|
16013
|
+
noOfBytesToSkip: 1,
|
|
16014
|
+
registerIndex: 0,
|
|
16015
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16016
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16017
|
+
};
|
|
16018
|
+
|
|
16019
|
+
results[ArgumentType.ONE_OFFSET] = {
|
|
16020
|
+
type: ArgumentType.ONE_OFFSET,
|
|
16021
|
+
noOfBytesToSkip: 1,
|
|
16022
|
+
nextPc: 0,
|
|
16023
|
+
};
|
|
16024
|
+
|
|
16025
|
+
results[ArgumentType.TWO_IMMEDIATES] = {
|
|
16026
|
+
type: ArgumentType.TWO_IMMEDIATES,
|
|
16027
|
+
noOfBytesToSkip: 1,
|
|
16028
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16029
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16030
|
+
};
|
|
16031
|
+
|
|
16032
|
+
results[ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES] = {
|
|
16033
|
+
type: ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES,
|
|
16034
|
+
noOfBytesToSkip: 1,
|
|
16035
|
+
firstImmediateDecoder: new ImmediateDecoder(),
|
|
16036
|
+
secondImmediateDecoder: new ImmediateDecoder(),
|
|
16037
|
+
firstRegisterIndex: 0,
|
|
16038
|
+
secondRegisterIndex: 0,
|
|
16039
|
+
};
|
|
16040
|
+
|
|
16041
|
+
results[ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE] = {
|
|
16042
|
+
type: ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE,
|
|
16043
|
+
noOfBytesToSkip: 9,
|
|
16044
|
+
registerIndex: 0,
|
|
16045
|
+
immediateDecoder: new ExtendedWitdthImmediateDecoder(),
|
|
16046
|
+
};
|
|
16047
|
+
|
|
16048
|
+
return results;
|
|
16049
|
+
};
|
|
16050
|
+
|
|
16051
|
+
declare enum Instruction {
|
|
16052
|
+
TRAP = 0,
|
|
16053
|
+
FALLTHROUGH = 1,
|
|
16054
|
+
ECALLI = 10,
|
|
16055
|
+
LOAD_IMM_64 = 20,
|
|
16056
|
+
STORE_IMM_U8 = 30,
|
|
16057
|
+
STORE_IMM_U16 = 31,
|
|
16058
|
+
STORE_IMM_U32 = 32,
|
|
16059
|
+
STORE_IMM_U64 = 33,
|
|
16060
|
+
JUMP = 40,
|
|
16061
|
+
JUMP_IND = 50,
|
|
16062
|
+
LOAD_IMM = 51,
|
|
16063
|
+
LOAD_U8 = 52,
|
|
16064
|
+
LOAD_I8 = 53,
|
|
16065
|
+
LOAD_U16 = 54,
|
|
16066
|
+
LOAD_I16 = 55,
|
|
16067
|
+
LOAD_U32 = 56,
|
|
16068
|
+
LOAD_I32 = 57,
|
|
16069
|
+
LOAD_U64 = 58,
|
|
16070
|
+
STORE_U8 = 59,
|
|
16071
|
+
STORE_U16 = 60,
|
|
16072
|
+
STORE_U32 = 61,
|
|
16073
|
+
STORE_U64 = 62,
|
|
16074
|
+
STORE_IMM_IND_U8 = 70,
|
|
16075
|
+
STORE_IMM_IND_U16 = 71,
|
|
16076
|
+
STORE_IMM_IND_U32 = 72,
|
|
16077
|
+
STORE_IMM_IND_U64 = 73,
|
|
16078
|
+
LOAD_IMM_JUMP = 80,
|
|
16079
|
+
BRANCH_EQ_IMM = 81,
|
|
16080
|
+
BRANCH_NE_IMM = 82,
|
|
16081
|
+
BRANCH_LT_U_IMM = 83,
|
|
16082
|
+
BRANCH_LE_U_IMM = 84,
|
|
16083
|
+
BRANCH_GE_U_IMM = 85,
|
|
16084
|
+
BRANCH_GT_U_IMM = 86,
|
|
16085
|
+
BRANCH_LT_S_IMM = 87,
|
|
16086
|
+
BRANCH_LE_S_IMM = 88,
|
|
16087
|
+
BRANCH_GE_S_IMM = 89,
|
|
16088
|
+
BRANCH_GT_S_IMM = 90,
|
|
16089
|
+
MOVE_REG = 100,
|
|
16090
|
+
SBRK = 101,
|
|
16091
|
+
COUNT_SET_BITS_64 = 102,
|
|
16092
|
+
COUNT_SET_BITS_32 = 103,
|
|
16093
|
+
LEADING_ZERO_BITS_64 = 104,
|
|
16094
|
+
LEADING_ZERO_BITS_32 = 105,
|
|
16095
|
+
TRAILING_ZERO_BITS_64 = 106,
|
|
16096
|
+
TRAILING_ZERO_BITS_32 = 107,
|
|
16097
|
+
SIGN_EXTEND_8 = 108,
|
|
16098
|
+
SIGN_EXTEND_16 = 109,
|
|
16099
|
+
ZERO_EXTEND_16 = 110,
|
|
16100
|
+
REVERSE_BYTES = 111,
|
|
16101
|
+
STORE_IND_U8 = 120,
|
|
16102
|
+
STORE_IND_U16 = 121,
|
|
16103
|
+
STORE_IND_U32 = 122,
|
|
16104
|
+
STORE_IND_U64 = 123,
|
|
16105
|
+
LOAD_IND_U8 = 124,
|
|
16106
|
+
LOAD_IND_I8 = 125,
|
|
16107
|
+
LOAD_IND_U16 = 126,
|
|
16108
|
+
LOAD_IND_I16 = 127,
|
|
16109
|
+
LOAD_IND_U32 = 128,
|
|
16110
|
+
LOAD_IND_I32 = 129,
|
|
16111
|
+
LOAD_IND_U64 = 130,
|
|
16112
|
+
ADD_IMM_32 = 131,
|
|
16113
|
+
AND_IMM = 132,
|
|
16114
|
+
XOR_IMM = 133,
|
|
16115
|
+
OR_IMM = 134,
|
|
16116
|
+
MUL_IMM_32 = 135,
|
|
16117
|
+
SET_LT_U_IMM = 136,
|
|
16118
|
+
SET_LT_S_IMM = 137,
|
|
16119
|
+
SHLO_L_IMM_32 = 138,
|
|
16120
|
+
SHLO_R_IMM_32 = 139,
|
|
16121
|
+
SHAR_R_IMM_32 = 140,
|
|
16122
|
+
NEG_ADD_IMM_32 = 141,
|
|
16123
|
+
SET_GT_U_IMM = 142,
|
|
16124
|
+
SET_GT_S_IMM = 143,
|
|
16125
|
+
SHLO_L_IMM_ALT_32 = 144,
|
|
16126
|
+
SHLO_R_IMM_ALT_32 = 145,
|
|
16127
|
+
SHAR_R_IMM_ALT_32 = 146,
|
|
16128
|
+
CMOV_IZ_IMM = 147,
|
|
16129
|
+
CMOV_NZ_IMM = 148,
|
|
16130
|
+
ADD_IMM_64 = 149,
|
|
16131
|
+
MUL_IMM_64 = 150,
|
|
16132
|
+
SHLO_L_IMM_64 = 151,
|
|
16133
|
+
SHLO_R_IMM_64 = 152,
|
|
16134
|
+
SHAR_R_IMM_64 = 153,
|
|
16135
|
+
NEG_ADD_IMM_64 = 154,
|
|
16136
|
+
SHLO_L_IMM_ALT_64 = 155,
|
|
16137
|
+
SHLO_R_IMM_ALT_64 = 156,
|
|
16138
|
+
SHAR_R_IMM_ALT_64 = 157,
|
|
16139
|
+
ROT_R_64_IMM = 158,
|
|
16140
|
+
ROT_R_64_IMM_ALT = 159,
|
|
16141
|
+
ROT_R_32_IMM = 160,
|
|
16142
|
+
ROT_R_32_IMM_ALT = 161,
|
|
16143
|
+
BRANCH_EQ = 170,
|
|
16144
|
+
BRANCH_NE = 171,
|
|
16145
|
+
BRANCH_LT_U = 172,
|
|
16146
|
+
BRANCH_LT_S = 173,
|
|
16147
|
+
BRANCH_GE_U = 174,
|
|
16148
|
+
BRANCH_GE_S = 175,
|
|
16149
|
+
LOAD_IMM_JUMP_IND = 180,
|
|
16150
|
+
ADD_32 = 190,
|
|
16151
|
+
SUB_32 = 191,
|
|
16152
|
+
MUL_32 = 192,
|
|
16153
|
+
DIV_U_32 = 193,
|
|
16154
|
+
DIV_S_32 = 194,
|
|
16155
|
+
REM_U_32 = 195,
|
|
16156
|
+
REM_S_32 = 196,
|
|
16157
|
+
SHLO_L_32 = 197,
|
|
16158
|
+
SHLO_R_32 = 198,
|
|
16159
|
+
SHAR_R_32 = 199,
|
|
16160
|
+
ADD_64 = 200,
|
|
16161
|
+
SUB_64 = 201,
|
|
16162
|
+
MUL_64 = 202,
|
|
16163
|
+
DIV_U_64 = 203,
|
|
16164
|
+
DIV_S_64 = 204,
|
|
16165
|
+
REM_U_64 = 205,
|
|
16166
|
+
REM_S_64 = 206,
|
|
16167
|
+
SHLO_L_64 = 207,
|
|
16168
|
+
SHLO_R_64 = 208,
|
|
16169
|
+
SHAR_R_64 = 209,
|
|
16170
|
+
AND = 210,
|
|
16171
|
+
XOR = 211,
|
|
16172
|
+
OR = 212,
|
|
16173
|
+
MUL_UPPER_S_S = 213,
|
|
16174
|
+
MUL_UPPER_U_U = 214,
|
|
16175
|
+
MUL_UPPER_S_U = 215,
|
|
16176
|
+
SET_LT_U = 216,
|
|
16177
|
+
SET_LT_S = 217,
|
|
16178
|
+
CMOV_IZ = 218,
|
|
16179
|
+
CMOV_NZ = 219,
|
|
16180
|
+
ROT_L_64 = 220,
|
|
16181
|
+
ROT_L_32 = 221,
|
|
16182
|
+
ROT_R_64 = 222,
|
|
16183
|
+
ROT_R_32 = 223,
|
|
16184
|
+
AND_INV = 224,
|
|
16185
|
+
OR_INV = 225,
|
|
16186
|
+
XNOR = 226,
|
|
16187
|
+
MAX = 227,
|
|
16188
|
+
MAX_U = 228,
|
|
16189
|
+
MIN = 229,
|
|
16190
|
+
MIN_U = 230,
|
|
16191
|
+
}
|
|
16192
|
+
|
|
16193
|
+
declare const instructionArgumentTypeMap = (() => {
|
|
16194
|
+
const instructionArgumentTypeMap = new Array<ArgumentType>(HIGHEST_INSTRUCTION_NUMBER + 1);
|
|
16195
|
+
|
|
16196
|
+
instructionArgumentTypeMap[Instruction.TRAP] = ArgumentType.NO_ARGUMENTS;
|
|
16197
|
+
instructionArgumentTypeMap[Instruction.FALLTHROUGH] = ArgumentType.NO_ARGUMENTS;
|
|
16198
|
+
|
|
16199
|
+
instructionArgumentTypeMap[Instruction.ECALLI] = ArgumentType.ONE_IMMEDIATE;
|
|
16200
|
+
|
|
16201
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_64] = ArgumentType.ONE_REGISTER_ONE_EXTENDED_WIDTH_IMMEDIATE;
|
|
16202
|
+
|
|
16203
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U8] = ArgumentType.TWO_IMMEDIATES;
|
|
16204
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U16] = ArgumentType.TWO_IMMEDIATES;
|
|
16205
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U32] = ArgumentType.TWO_IMMEDIATES;
|
|
16206
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_U64] = ArgumentType.TWO_IMMEDIATES;
|
|
16207
|
+
|
|
16208
|
+
instructionArgumentTypeMap[Instruction.JUMP] = ArgumentType.ONE_OFFSET;
|
|
16209
|
+
|
|
16210
|
+
instructionArgumentTypeMap[Instruction.JUMP_IND] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16211
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16212
|
+
instructionArgumentTypeMap[Instruction.LOAD_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16213
|
+
instructionArgumentTypeMap[Instruction.LOAD_I8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16214
|
+
instructionArgumentTypeMap[Instruction.LOAD_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16215
|
+
instructionArgumentTypeMap[Instruction.LOAD_I16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16216
|
+
instructionArgumentTypeMap[Instruction.LOAD_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16217
|
+
instructionArgumentTypeMap[Instruction.LOAD_I32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16218
|
+
instructionArgumentTypeMap[Instruction.LOAD_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16219
|
+
instructionArgumentTypeMap[Instruction.STORE_U8] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16220
|
+
instructionArgumentTypeMap[Instruction.STORE_U16] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16221
|
+
instructionArgumentTypeMap[Instruction.STORE_U32] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16222
|
+
instructionArgumentTypeMap[Instruction.STORE_U64] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE;
|
|
16223
|
+
|
|
16224
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U8] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16225
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U16] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16226
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U32] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16227
|
+
instructionArgumentTypeMap[Instruction.STORE_IMM_IND_U64] = ArgumentType.ONE_REGISTER_TWO_IMMEDIATES;
|
|
16228
|
+
|
|
16229
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16230
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16231
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16232
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16233
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16234
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16235
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_U_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16236
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16237
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16238
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16239
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GT_S_IMM] = ArgumentType.ONE_REGISTER_ONE_IMMEDIATE_ONE_OFFSET;
|
|
16240
|
+
|
|
16241
|
+
instructionArgumentTypeMap[Instruction.MOVE_REG] = ArgumentType.TWO_REGISTERS;
|
|
16242
|
+
instructionArgumentTypeMap[Instruction.SBRK] = ArgumentType.TWO_REGISTERS;
|
|
16243
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16244
|
+
instructionArgumentTypeMap[Instruction.COUNT_SET_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16245
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16246
|
+
instructionArgumentTypeMap[Instruction.LEADING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16247
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_64] = ArgumentType.TWO_REGISTERS;
|
|
16248
|
+
instructionArgumentTypeMap[Instruction.TRAILING_ZERO_BITS_32] = ArgumentType.TWO_REGISTERS;
|
|
16249
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_8] = ArgumentType.TWO_REGISTERS;
|
|
16250
|
+
instructionArgumentTypeMap[Instruction.SIGN_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
16251
|
+
instructionArgumentTypeMap[Instruction.ZERO_EXTEND_16] = ArgumentType.TWO_REGISTERS;
|
|
16252
|
+
instructionArgumentTypeMap[Instruction.REVERSE_BYTES] = ArgumentType.TWO_REGISTERS;
|
|
16253
|
+
|
|
16254
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16255
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16256
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16257
|
+
instructionArgumentTypeMap[Instruction.STORE_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16258
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16259
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I8] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16260
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16261
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I16] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16262
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16263
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_I32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16264
|
+
instructionArgumentTypeMap[Instruction.LOAD_IND_U64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16265
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16266
|
+
instructionArgumentTypeMap[Instruction.ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16267
|
+
instructionArgumentTypeMap[Instruction.AND_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16268
|
+
instructionArgumentTypeMap[Instruction.XOR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16269
|
+
instructionArgumentTypeMap[Instruction.OR_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16270
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16271
|
+
instructionArgumentTypeMap[Instruction.MUL_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16272
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16273
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16274
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16275
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16276
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16277
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16278
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16279
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16280
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16281
|
+
instructionArgumentTypeMap[Instruction.NEG_ADD_IMM_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16282
|
+
instructionArgumentTypeMap[Instruction.SET_GT_U_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16283
|
+
instructionArgumentTypeMap[Instruction.SET_GT_S_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16284
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16285
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16286
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_32] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16287
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16288
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16289
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_IMM_ALT_64] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16290
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16291
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16292
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16293
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16294
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
16295
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32_IMM_ALT] = ArgumentType.TWO_REGISTERS_ONE_IMMEDIATE;
|
|
15740
16296
|
|
|
15741
|
-
|
|
16297
|
+
instructionArgumentTypeMap[Instruction.BRANCH_EQ] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16298
|
+
instructionArgumentTypeMap[Instruction.BRANCH_NE] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16299
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16300
|
+
instructionArgumentTypeMap[Instruction.BRANCH_LT_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16301
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_U] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
16302
|
+
instructionArgumentTypeMap[Instruction.BRANCH_GE_S] = ArgumentType.TWO_REGISTERS_ONE_OFFSET;
|
|
15742
16303
|
|
|
15743
|
-
|
|
15744
|
-
const page = this.initialMemory.get(pageNumber);
|
|
16304
|
+
instructionArgumentTypeMap[Instruction.LOAD_IMM_JUMP_IND] = ArgumentType.TWO_REGISTERS_TWO_IMMEDIATES;
|
|
15745
16305
|
|
|
15746
|
-
|
|
15747
|
-
|
|
15748
|
-
|
|
16306
|
+
instructionArgumentTypeMap[Instruction.ADD_32] = ArgumentType.THREE_REGISTERS;
|
|
16307
|
+
instructionArgumentTypeMap[Instruction.ADD_64] = ArgumentType.THREE_REGISTERS;
|
|
16308
|
+
instructionArgumentTypeMap[Instruction.SUB_32] = ArgumentType.THREE_REGISTERS;
|
|
16309
|
+
instructionArgumentTypeMap[Instruction.SUB_64] = ArgumentType.THREE_REGISTERS;
|
|
16310
|
+
instructionArgumentTypeMap[Instruction.AND] = ArgumentType.THREE_REGISTERS;
|
|
16311
|
+
instructionArgumentTypeMap[Instruction.XOR] = ArgumentType.THREE_REGISTERS;
|
|
16312
|
+
instructionArgumentTypeMap[Instruction.OR] = ArgumentType.THREE_REGISTERS;
|
|
16313
|
+
instructionArgumentTypeMap[Instruction.MUL_32] = ArgumentType.THREE_REGISTERS;
|
|
16314
|
+
instructionArgumentTypeMap[Instruction.MUL_64] = ArgumentType.THREE_REGISTERS;
|
|
16315
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_S] = ArgumentType.THREE_REGISTERS;
|
|
16316
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_U_U] = ArgumentType.THREE_REGISTERS;
|
|
16317
|
+
instructionArgumentTypeMap[Instruction.MUL_UPPER_S_U] = ArgumentType.THREE_REGISTERS;
|
|
16318
|
+
instructionArgumentTypeMap[Instruction.DIV_U_32] = ArgumentType.THREE_REGISTERS;
|
|
16319
|
+
instructionArgumentTypeMap[Instruction.DIV_S_32] = ArgumentType.THREE_REGISTERS;
|
|
16320
|
+
instructionArgumentTypeMap[Instruction.REM_U_32] = ArgumentType.THREE_REGISTERS;
|
|
16321
|
+
instructionArgumentTypeMap[Instruction.REM_S_32] = ArgumentType.THREE_REGISTERS;
|
|
16322
|
+
instructionArgumentTypeMap[Instruction.DIV_U_64] = ArgumentType.THREE_REGISTERS;
|
|
16323
|
+
instructionArgumentTypeMap[Instruction.DIV_S_64] = ArgumentType.THREE_REGISTERS;
|
|
16324
|
+
instructionArgumentTypeMap[Instruction.REM_U_64] = ArgumentType.THREE_REGISTERS;
|
|
16325
|
+
instructionArgumentTypeMap[Instruction.REM_S_64] = ArgumentType.THREE_REGISTERS;
|
|
16326
|
+
instructionArgumentTypeMap[Instruction.SET_LT_U] = ArgumentType.THREE_REGISTERS;
|
|
16327
|
+
instructionArgumentTypeMap[Instruction.SET_LT_S] = ArgumentType.THREE_REGISTERS;
|
|
16328
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_32] = ArgumentType.THREE_REGISTERS;
|
|
16329
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16330
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16331
|
+
instructionArgumentTypeMap[Instruction.SHLO_L_64] = ArgumentType.THREE_REGISTERS;
|
|
16332
|
+
instructionArgumentTypeMap[Instruction.SHLO_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16333
|
+
instructionArgumentTypeMap[Instruction.SHAR_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16334
|
+
instructionArgumentTypeMap[Instruction.CMOV_IZ] = ArgumentType.THREE_REGISTERS;
|
|
16335
|
+
instructionArgumentTypeMap[Instruction.CMOV_NZ] = ArgumentType.THREE_REGISTERS;
|
|
16336
|
+
instructionArgumentTypeMap[Instruction.ROT_L_64] = ArgumentType.THREE_REGISTERS;
|
|
16337
|
+
instructionArgumentTypeMap[Instruction.ROT_L_32] = ArgumentType.THREE_REGISTERS;
|
|
16338
|
+
instructionArgumentTypeMap[Instruction.ROT_R_64] = ArgumentType.THREE_REGISTERS;
|
|
16339
|
+
instructionArgumentTypeMap[Instruction.ROT_R_32] = ArgumentType.THREE_REGISTERS;
|
|
16340
|
+
instructionArgumentTypeMap[Instruction.AND_INV] = ArgumentType.THREE_REGISTERS;
|
|
16341
|
+
instructionArgumentTypeMap[Instruction.OR_INV] = ArgumentType.THREE_REGISTERS;
|
|
16342
|
+
instructionArgumentTypeMap[Instruction.XNOR] = ArgumentType.THREE_REGISTERS;
|
|
16343
|
+
instructionArgumentTypeMap[Instruction.MAX] = ArgumentType.THREE_REGISTERS;
|
|
16344
|
+
instructionArgumentTypeMap[Instruction.MAX_U] = ArgumentType.THREE_REGISTERS;
|
|
16345
|
+
instructionArgumentTypeMap[Instruction.MIN] = ArgumentType.THREE_REGISTERS;
|
|
16346
|
+
instructionArgumentTypeMap[Instruction.MIN_U] = ArgumentType.THREE_REGISTERS;
|
|
15749
16347
|
|
|
15750
|
-
|
|
15751
|
-
|
|
16348
|
+
return instructionArgumentTypeMap;
|
|
16349
|
+
})();
|
|
15752
16350
|
|
|
15753
|
-
|
|
15754
|
-
|
|
16351
|
+
declare class BasicBlocks {
|
|
16352
|
+
private basicBlocks: Set<number> = new Set();
|
|
15755
16353
|
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15759
|
-
|
|
15760
|
-
`;
|
|
15761
|
-
this.ensureNotFinalized();
|
|
16354
|
+
reset(code: Uint8Array, mask: Mask) {
|
|
16355
|
+
this.basicBlocks.clear();
|
|
16356
|
+
this.basicBlocks.add(0);
|
|
16357
|
+
const codeLength = code.length;
|
|
15762
16358
|
|
|
15763
|
-
const
|
|
15764
|
-
|
|
15765
|
-
const initializedPageNumbers = Array.from(this.initialMemory.keys());
|
|
16359
|
+
const isBasicBlockTermination = (index: number) =>
|
|
16360
|
+
mask.isInstruction(index) && terminationInstructions[code[index]];
|
|
15766
16361
|
|
|
15767
|
-
for (
|
|
15768
|
-
if (
|
|
15769
|
-
|
|
16362
|
+
for (let i = 0; i < codeLength; i++) {
|
|
16363
|
+
if (mask.isInstruction(i) && isBasicBlockTermination(i)) {
|
|
16364
|
+
this.basicBlocks.add(i + 1 + mask.getNoOfBytesToNextInstruction(i + 1));
|
|
15770
16365
|
}
|
|
15771
16366
|
}
|
|
16367
|
+
}
|
|
15772
16368
|
|
|
15773
|
-
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
|
|
15777
|
-
});
|
|
16369
|
+
isBeginningOfBasicBlock(index: number) {
|
|
16370
|
+
return this.basicBlocks.has(index);
|
|
16371
|
+
}
|
|
16372
|
+
}
|
|
15778
16373
|
|
|
15779
|
-
|
|
15780
|
-
|
|
16374
|
+
declare enum Result {
|
|
16375
|
+
HALT = 0,
|
|
16376
|
+
PANIC = 1,
|
|
16377
|
+
FAULT_ACCESS = 2,
|
|
16378
|
+
FAULT = 3,
|
|
16379
|
+
HOST = 4,
|
|
16380
|
+
}
|
|
16381
|
+
|
|
16382
|
+
declare class InstructionResult {
|
|
16383
|
+
public nextPc = 0;
|
|
16384
|
+
public status: Result | null = null;
|
|
16385
|
+
/**
|
|
16386
|
+
* A numeric exit parameter of the PVM.
|
|
16387
|
+
*
|
|
16388
|
+
* In case of a `status === Result.FAULT` this will be the memory address
|
|
16389
|
+
* that triggered the fault.
|
|
16390
|
+
* In case of a `status === Result.HOST` this will be the host call index
|
|
16391
|
+
* that should be invoked.
|
|
16392
|
+
*
|
|
16393
|
+
* In any other circumstance the value should be `null`.
|
|
16394
|
+
*/
|
|
16395
|
+
public exitParam: number | null = null;
|
|
16396
|
+
|
|
16397
|
+
reset() {
|
|
16398
|
+
this.nextPc = 0;
|
|
16399
|
+
this.status = null;
|
|
16400
|
+
this.exitParam = null;
|
|
15781
16401
|
}
|
|
15782
16402
|
}
|
|
15783
16403
|
|
|
@@ -16762,7 +17382,7 @@ declare class StoreOps {
|
|
|
16762
17382
|
this.instructionResult.status = Result.FAULT_ACCESS;
|
|
16763
17383
|
} else {
|
|
16764
17384
|
this.instructionResult.status = Result.FAULT;
|
|
16765
|
-
this.instructionResult.exitParam = getStartPageIndex(storeResult.error.address);
|
|
17385
|
+
this.instructionResult.exitParam = getStartPageIndex(tryAsMemoryIndex(storeResult.error.address));
|
|
16766
17386
|
}
|
|
16767
17387
|
}
|
|
16768
17388
|
}
|
|
@@ -17563,34 +18183,20 @@ declare class ProgramDecoder {
|
|
|
17563
18183
|
}
|
|
17564
18184
|
}
|
|
17565
18185
|
|
|
17566
|
-
/**
|
|
17567
|
-
* Inner status codes for the PVM
|
|
17568
|
-
*
|
|
17569
|
-
* https://graypaper.fluffylabs.dev/#/85129da/2cae022cae02?v=0.6.3
|
|
17570
|
-
*/
|
|
17571
|
-
declare enum Status {
|
|
17572
|
-
OK = 255,
|
|
17573
|
-
HALT = 0,
|
|
17574
|
-
PANIC = 1,
|
|
17575
|
-
FAULT = 2,
|
|
17576
|
-
HOST = 3,
|
|
17577
|
-
OOG = 4,
|
|
17578
|
-
}
|
|
17579
|
-
|
|
17580
18186
|
type InterpreterOptions = {
|
|
17581
18187
|
useSbrkGas?: boolean;
|
|
17582
18188
|
};
|
|
17583
18189
|
|
|
17584
18190
|
declare const logger = Logger.new(import.meta.filename, "pvm");
|
|
17585
18191
|
|
|
17586
|
-
declare class Interpreter {
|
|
18192
|
+
declare class Interpreter implements IPvmInterpreter {
|
|
17587
18193
|
private readonly useSbrkGas: boolean;
|
|
17588
|
-
|
|
18194
|
+
readonly registers = new Registers();
|
|
18195
|
+
readonly memory = new Memory();
|
|
18196
|
+
gas = gasCounter(tryAsGas(0));
|
|
17589
18197
|
private code: Uint8Array = new Uint8Array();
|
|
17590
18198
|
private mask = Mask.empty();
|
|
17591
18199
|
private pc = 0;
|
|
17592
|
-
private gas = gasCounter(tryAsGas(0));
|
|
17593
|
-
private initialGas = gasCounter(tryAsGas(0));
|
|
17594
18200
|
private argsDecoder: ArgsDecoder;
|
|
17595
18201
|
private threeRegsDispatcher: ThreeRegsDispatcher;
|
|
17596
18202
|
private twoRegsOneImmDispatcher: TwoRegsOneImmDispatcher;
|
|
@@ -17600,7 +18206,6 @@ declare class Interpreter {
|
|
|
17600
18206
|
private oneOffsetDispatcher: OneOffsetDispatcher;
|
|
17601
18207
|
private oneRegOneImmDispatcher: OneRegOneImmDispatcher;
|
|
17602
18208
|
private instructionResult = new InstructionResult();
|
|
17603
|
-
private memory = new Memory();
|
|
17604
18209
|
private twoImmsDispatcher: TwoImmsDispatcher;
|
|
17605
18210
|
private oneRegTwoImmsDispatcher: OneRegTwoImmsDispatcher;
|
|
17606
18211
|
private noArgsDispatcher: NoArgsDispatcher;
|
|
@@ -17654,7 +18259,12 @@ declare class Interpreter {
|
|
|
17654
18259
|
this.oneRegOneExtImmDispatcher = new OneRegOneExtImmDispatcher(loadOps);
|
|
17655
18260
|
}
|
|
17656
18261
|
|
|
17657
|
-
|
|
18262
|
+
resetJam(program: Uint8Array, args: Uint8Array, pc: number, gas: Gas) {
|
|
18263
|
+
const p = Program.fromSpi(program, args, true);
|
|
18264
|
+
this.resetGeneric(p.code, pc, gas, p.registers, p.memory);
|
|
18265
|
+
}
|
|
18266
|
+
|
|
18267
|
+
resetGeneric(rawProgram: Uint8Array, pc: number, gas: Gas, maybeRegisters?: Registers, maybeMemory?: Memory) {
|
|
17658
18268
|
const programDecoder = new ProgramDecoder(rawProgram);
|
|
17659
18269
|
this.code = programDecoder.getCode();
|
|
17660
18270
|
this.mask = programDecoder.getMask();
|
|
@@ -17662,7 +18272,6 @@ declare class Interpreter {
|
|
|
17662
18272
|
|
|
17663
18273
|
this.pc = pc;
|
|
17664
18274
|
this.gas = gasCounter(gas);
|
|
17665
|
-
this.initialGas = gasCounter(gas);
|
|
17666
18275
|
this.status = Status.OK;
|
|
17667
18276
|
this.argsDecoder.reset(this.code, this.mask);
|
|
17668
18277
|
this.basicBlocks.reset(this.code, this.mask);
|
|
@@ -17804,10 +18413,6 @@ declare class Interpreter {
|
|
|
17804
18413
|
return this.status;
|
|
17805
18414
|
}
|
|
17806
18415
|
|
|
17807
|
-
getRegisters() {
|
|
17808
|
-
return this.registers;
|
|
17809
|
-
}
|
|
17810
|
-
|
|
17811
18416
|
getPC() {
|
|
17812
18417
|
return this.pc;
|
|
17813
18418
|
}
|
|
@@ -17816,258 +18421,91 @@ declare class Interpreter {
|
|
|
17816
18421
|
this.pc = nextPc;
|
|
17817
18422
|
}
|
|
17818
18423
|
|
|
17819
|
-
getGas(): Gas {
|
|
17820
|
-
return this.gas.get();
|
|
17821
|
-
}
|
|
17822
|
-
|
|
17823
|
-
getGasConsumed(): Gas {
|
|
17824
|
-
const gasConsumed = tryAsBigGas(this.initialGas.get()) - tryAsBigGas(this.gas.get());
|
|
17825
|
-
|
|
17826
|
-
if (gasConsumed < 0) {
|
|
17827
|
-
return this.initialGas.get();
|
|
17828
|
-
}
|
|
17829
|
-
|
|
17830
|
-
return tryAsBigGas(gasConsumed);
|
|
17831
|
-
}
|
|
17832
|
-
|
|
17833
|
-
getGasCounter(): GasCounter {
|
|
17834
|
-
return this.gas;
|
|
17835
|
-
}
|
|
17836
|
-
|
|
17837
18424
|
getStatus() {
|
|
17838
18425
|
return this.status;
|
|
17839
18426
|
}
|
|
17840
18427
|
|
|
17841
18428
|
getExitParam(): null | U32 {
|
|
17842
18429
|
const p = this.instructionResult.exitParam;
|
|
17843
|
-
return p !== null ? tryAsU32(p) : p;
|
|
17844
|
-
}
|
|
17845
|
-
|
|
17846
|
-
getMemory() {
|
|
17847
|
-
return this.memory;
|
|
17848
|
-
}
|
|
17849
|
-
|
|
17850
|
-
getMemoryPage(pageNumber: number): null | Uint8Array {
|
|
17851
|
-
return this.memory.getPageDump(tryAsPageNumber(pageNumber));
|
|
17852
|
-
}
|
|
17853
|
-
|
|
17854
|
-
calculateBlockGasCost(): Map<string, number> {
|
|
17855
|
-
const codeLength = this.code.length;
|
|
17856
|
-
const blocks: Map<string, number> = new Map();
|
|
17857
|
-
let currentBlock = "0";
|
|
17858
|
-
let gasCost = 0;
|
|
17859
|
-
const getNextIstructionIndex = (index: number) => index + 1 + this.mask.getNoOfBytesToNextInstruction(index + 1);
|
|
17860
|
-
|
|
17861
|
-
for (let index = 0; index < codeLength; index = getNextIstructionIndex(index)) {
|
|
17862
|
-
const instruction = this.code[index];
|
|
17863
|
-
if (this.basicBlocks.isBeginningOfBasicBlock(index)) {
|
|
17864
|
-
blocks.set(currentBlock, gasCost);
|
|
17865
|
-
currentBlock = index.toString();
|
|
17866
|
-
gasCost = 0;
|
|
17867
|
-
}
|
|
17868
|
-
|
|
17869
|
-
gasCost += instructionGasMap[instruction];
|
|
17870
|
-
}
|
|
17871
|
-
|
|
17872
|
-
blocks.set(currentBlock, gasCost);
|
|
17873
|
-
|
|
17874
|
-
return blocks;
|
|
17875
|
-
}
|
|
17876
|
-
}
|
|
17877
|
-
|
|
17878
|
-
type index$8_BigGas = BigGas;
|
|
17879
|
-
type index$8_Gas = Gas;
|
|
17880
|
-
type index$8_GasCounter = GasCounter;
|
|
17881
|
-
type index$8_Interpreter = Interpreter;
|
|
17882
|
-
declare const index$8_Interpreter: typeof Interpreter;
|
|
17883
|
-
type index$8_InterpreterOptions = InterpreterOptions;
|
|
17884
|
-
type index$8_Memory = Memory;
|
|
17885
|
-
declare const index$8_Memory: typeof Memory;
|
|
17886
|
-
type index$8_MemoryBuilder = MemoryBuilder;
|
|
17887
|
-
declare const index$8_MemoryBuilder: typeof MemoryBuilder;
|
|
17888
|
-
type index$8_MemoryIndex = MemoryIndex;
|
|
17889
|
-
type index$8_Registers = Registers;
|
|
17890
|
-
declare const index$8_Registers: typeof Registers;
|
|
17891
|
-
type index$8_SbrkIndex = SbrkIndex;
|
|
17892
|
-
type index$8_SmallGas = SmallGas;
|
|
17893
|
-
declare const index$8_gasCounter: typeof gasCounter;
|
|
17894
|
-
declare const index$8_logger: typeof logger;
|
|
17895
|
-
declare const index$8_tryAsBigGas: typeof tryAsBigGas;
|
|
17896
|
-
declare const index$8_tryAsGas: typeof tryAsGas;
|
|
17897
|
-
declare const index$8_tryAsMemoryIndex: typeof tryAsMemoryIndex;
|
|
17898
|
-
declare const index$8_tryAsSbrkIndex: typeof tryAsSbrkIndex;
|
|
17899
|
-
declare const index$8_tryAsSmallGas: typeof tryAsSmallGas;
|
|
17900
|
-
declare namespace index$8 {
|
|
17901
|
-
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 };
|
|
17902
|
-
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 };
|
|
17903
|
-
}
|
|
17904
|
-
|
|
17905
|
-
interface IHostCallMemory {
|
|
17906
|
-
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds>;
|
|
17907
|
-
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds>;
|
|
17908
|
-
}
|
|
17909
|
-
|
|
17910
|
-
declare class HostCallMemory implements IHostCallMemory {
|
|
17911
|
-
constructor(private readonly memory: Memory) {}
|
|
17912
|
-
|
|
17913
|
-
storeFrom(address: U64, bytes: Uint8Array): Result$2<OK, PageFault | OutOfBounds> {
|
|
17914
|
-
if (bytes.length === 0) {
|
|
17915
|
-
return Result.ok(OK);
|
|
17916
|
-
}
|
|
17917
|
-
|
|
17918
|
-
if (address + tryAsU64(bytes.length) > MEMORY_SIZE) {
|
|
17919
|
-
return Result.error(
|
|
17920
|
-
new OutOfBounds(),
|
|
17921
|
-
() => `Memory access out of bounds: address ${address} + length ${bytes.length} exceeds memory size`,
|
|
17922
|
-
);
|
|
17923
|
-
}
|
|
17924
|
-
|
|
17925
|
-
return this.memory.storeFrom(tryAsMemoryIndex(Number(address)), bytes);
|
|
17926
|
-
}
|
|
17927
|
-
|
|
17928
|
-
loadInto(result: Uint8Array, startAddress: U64): Result$2<OK, PageFault | OutOfBounds> {
|
|
17929
|
-
if (result.length === 0) {
|
|
17930
|
-
return Result.ok(OK);
|
|
17931
|
-
}
|
|
17932
|
-
|
|
17933
|
-
if (startAddress + tryAsU64(result.length) > MEMORY_SIZE) {
|
|
17934
|
-
return Result.error(
|
|
17935
|
-
new OutOfBounds(),
|
|
17936
|
-
() => `Memory access out of bounds: address ${startAddress} + length ${result.length} exceeds memory size`,
|
|
17937
|
-
);
|
|
17938
|
-
}
|
|
17939
|
-
|
|
17940
|
-
return this.memory.loadInto(result, tryAsMemoryIndex(Number(startAddress)));
|
|
17941
|
-
}
|
|
17942
|
-
}
|
|
17943
|
-
|
|
17944
|
-
interface IHostCallRegisters {
|
|
17945
|
-
get(registerIndex: number): U64;
|
|
17946
|
-
set(registerIndex: number, value: U64): void;
|
|
17947
|
-
}
|
|
17948
|
-
|
|
17949
|
-
declare class HostCallRegisters implements IHostCallRegisters {
|
|
17950
|
-
constructor(private readonly registers: Registers) {}
|
|
17951
|
-
|
|
17952
|
-
get(registerIndex: number): U64 {
|
|
17953
|
-
return tryAsU64(this.registers.getU64(registerIndex));
|
|
17954
|
-
}
|
|
17955
|
-
|
|
17956
|
-
set(registerIndex: number, value: U64) {
|
|
17957
|
-
this.registers.setU64(registerIndex, value);
|
|
17958
|
-
}
|
|
17959
|
-
}
|
|
17960
|
-
|
|
17961
|
-
/** Strictly-typed host call index. */
|
|
17962
|
-
type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
17963
|
-
/** Attempt to convert a number into `HostCallIndex`. */
|
|
17964
|
-
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
17965
|
-
|
|
17966
|
-
/**
|
|
17967
|
-
* Host-call exit reason.
|
|
17968
|
-
*
|
|
17969
|
-
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
17970
|
-
*/
|
|
17971
|
-
declare enum PvmExecution {
|
|
17972
|
-
Halt = 0,
|
|
17973
|
-
Panic = 1,
|
|
17974
|
-
OOG = 2, // out-of-gas
|
|
17975
|
-
}
|
|
17976
|
-
|
|
17977
|
-
/** A utility function to easily trace a bunch of registers. */
|
|
17978
|
-
declare function traceRegisters(...regs: number[]) {
|
|
17979
|
-
return regs.map(tryAsRegisterIndex);
|
|
17980
|
-
}
|
|
17981
|
-
|
|
17982
|
-
/** An interface for a host call implementation */
|
|
17983
|
-
interface HostCallHandler {
|
|
17984
|
-
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
17985
|
-
readonly index: HostCallIndex;
|
|
17986
|
-
|
|
17987
|
-
/**
|
|
17988
|
-
* The gas cost of invocation of that host call.
|
|
17989
|
-
*
|
|
17990
|
-
* NOTE: `((reg: IHostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
17991
|
-
*/
|
|
17992
|
-
readonly basicGasCost: SmallGas | ((reg: IHostCallRegisters) => Gas);
|
|
17993
|
-
|
|
17994
|
-
/** Currently executing service id. */
|
|
17995
|
-
readonly currentServiceId: U32;
|
|
17996
|
-
|
|
17997
|
-
/** Input&Output registers that we should add to tracing log. */
|
|
17998
|
-
readonly tracedRegisters: RegisterIndex[];
|
|
18430
|
+
return p !== null ? tryAsU32(p) : p;
|
|
18431
|
+
}
|
|
17999
18432
|
|
|
18000
|
-
|
|
18001
|
-
|
|
18002
|
-
|
|
18003
|
-
* NOTE the call is ALLOWED and expected to modify registers and memory.
|
|
18004
|
-
*/
|
|
18005
|
-
execute(gas: GasCounter, regs: IHostCallRegisters, memory: IHostCallMemory): Promise<undefined | PvmExecution>;
|
|
18006
|
-
}
|
|
18433
|
+
getMemoryPage(pageNumber: number): null | Uint8Array {
|
|
18434
|
+
return this.memory.getPageDump(tryAsPageNumber(pageNumber));
|
|
18435
|
+
}
|
|
18007
18436
|
|
|
18008
|
-
|
|
18009
|
-
|
|
18010
|
-
|
|
18011
|
-
|
|
18437
|
+
calculateBlockGasCost(): Map<string, number> {
|
|
18438
|
+
const codeLength = this.code.length;
|
|
18439
|
+
const blocks: Map<string, number> = new Map();
|
|
18440
|
+
let currentBlock = "0";
|
|
18441
|
+
let gasCost = 0;
|
|
18442
|
+
const getNextIstructionIndex = (index: number) => index + 1 + this.mask.getNoOfBytesToNextInstruction(index + 1);
|
|
18012
18443
|
|
|
18013
|
-
|
|
18014
|
-
|
|
18015
|
-
|
|
18016
|
-
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
this.missing = missing;
|
|
18444
|
+
for (let index = 0; index < codeLength; index = getNextIstructionIndex(index)) {
|
|
18445
|
+
const instruction = this.code[index];
|
|
18446
|
+
if (this.basicBlocks.isBeginningOfBasicBlock(index)) {
|
|
18447
|
+
blocks.set(currentBlock, gasCost);
|
|
18448
|
+
currentBlock = index.toString();
|
|
18449
|
+
gasCost = 0;
|
|
18450
|
+
}
|
|
18021
18451
|
|
|
18022
|
-
|
|
18023
|
-
check`${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
18024
|
-
this.hostCalls.set(handler.index, handler);
|
|
18452
|
+
gasCost += instructionGasMap[instruction];
|
|
18025
18453
|
}
|
|
18026
|
-
}
|
|
18027
18454
|
|
|
18028
|
-
|
|
18029
|
-
get(hostCallIndex: HostCallIndex): HostCallHandler {
|
|
18030
|
-
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
18031
|
-
}
|
|
18455
|
+
blocks.set(currentBlock, gasCost);
|
|
18032
18456
|
|
|
18033
|
-
|
|
18034
|
-
context: string,
|
|
18035
|
-
hostCallIndex: HostCallIndex,
|
|
18036
|
-
hostCallHandler: HostCallHandler,
|
|
18037
|
-
registers: IHostCallRegisters,
|
|
18038
|
-
gas: Gas,
|
|
18039
|
-
) {
|
|
18040
|
-
const { currentServiceId } = hostCallHandler;
|
|
18041
|
-
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
18042
|
-
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
18043
|
-
const registerValues = hostCallHandler.tracedRegisters
|
|
18044
|
-
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)] as const)
|
|
18045
|
-
.filter((v) => v[1] !== 0n)
|
|
18046
|
-
.map(([idx, value]) => {
|
|
18047
|
-
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
18048
|
-
})
|
|
18049
|
-
.join(", ");
|
|
18050
|
-
logger.insane`[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
18457
|
+
return blocks;
|
|
18051
18458
|
}
|
|
18052
18459
|
}
|
|
18053
18460
|
|
|
18054
|
-
type
|
|
18461
|
+
type index$6_Interpreter = Interpreter;
|
|
18462
|
+
declare const index$6_Interpreter: typeof Interpreter;
|
|
18463
|
+
type index$6_InterpreterOptions = InterpreterOptions;
|
|
18464
|
+
type index$6_Memory = Memory;
|
|
18465
|
+
declare const index$6_Memory: typeof Memory;
|
|
18466
|
+
type index$6_MemoryBuilder = MemoryBuilder;
|
|
18467
|
+
declare const index$6_MemoryBuilder: typeof MemoryBuilder;
|
|
18468
|
+
type index$6_MemoryIndex = MemoryIndex;
|
|
18469
|
+
type index$6_Registers = Registers;
|
|
18470
|
+
declare const index$6_Registers: typeof Registers;
|
|
18471
|
+
type index$6_SbrkIndex = SbrkIndex;
|
|
18472
|
+
declare const index$6_gasCounter: typeof gasCounter;
|
|
18473
|
+
declare const index$6_logger: typeof logger;
|
|
18474
|
+
declare const index$6_tryAsMemoryIndex: typeof tryAsMemoryIndex;
|
|
18475
|
+
declare const index$6_tryAsSbrkIndex: typeof tryAsSbrkIndex;
|
|
18476
|
+
declare namespace index$6 {
|
|
18477
|
+
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 };
|
|
18478
|
+
export type { index$6_InterpreterOptions as InterpreterOptions, index$6_MemoryIndex as MemoryIndex, index$6_SbrkIndex as SbrkIndex };
|
|
18479
|
+
}
|
|
18055
18480
|
|
|
18481
|
+
type ResolveFn = (pvm: IPvmInterpreter) => void;
|
|
18482
|
+
|
|
18483
|
+
// TODO [MaSo] Delete this & also make host calls independent from intepreters.
|
|
18056
18484
|
declare class InterpreterInstanceManager {
|
|
18057
|
-
private instances: Interpreter[] = [];
|
|
18058
18485
|
private waitingQueue: ResolveFn[] = [];
|
|
18059
18486
|
|
|
18060
|
-
constructor(
|
|
18061
|
-
|
|
18062
|
-
|
|
18063
|
-
|
|
18064
|
-
|
|
18065
|
-
|
|
18066
|
-
|
|
18487
|
+
private constructor(private readonly instances: IPvmInterpreter[]) {}
|
|
18488
|
+
|
|
18489
|
+
static async new(interpreter: PvmBackend): Promise<InterpreterInstanceManager> {
|
|
18490
|
+
const instances: IPvmInterpreter[] = [];
|
|
18491
|
+
switch (interpreter) {
|
|
18492
|
+
case PvmBackend.BuiltIn:
|
|
18493
|
+
instances.push(
|
|
18494
|
+
new Interpreter({
|
|
18495
|
+
useSbrkGas: false,
|
|
18496
|
+
}),
|
|
18497
|
+
);
|
|
18498
|
+
break;
|
|
18499
|
+
case PvmBackend.Ananas:
|
|
18500
|
+
instances.push(await AnanasInterpreter.new());
|
|
18501
|
+
break;
|
|
18502
|
+
default:
|
|
18503
|
+
assertNever(interpreter);
|
|
18067
18504
|
}
|
|
18505
|
+
return new InterpreterInstanceManager(instances);
|
|
18068
18506
|
}
|
|
18069
18507
|
|
|
18070
|
-
async getInstance(): Promise<
|
|
18508
|
+
async getInstance(): Promise<IPvmInterpreter> {
|
|
18071
18509
|
const instance = this.instances.pop();
|
|
18072
18510
|
if (instance !== undefined) {
|
|
18073
18511
|
return Promise.resolve(instance);
|
|
@@ -18077,7 +18515,7 @@ declare class InterpreterInstanceManager {
|
|
|
18077
18515
|
});
|
|
18078
18516
|
}
|
|
18079
18517
|
|
|
18080
|
-
releaseInstance(pvm:
|
|
18518
|
+
releaseInstance(pvm: IPvmInterpreter) {
|
|
18081
18519
|
const waiting = this.waitingQueue.shift();
|
|
18082
18520
|
if (waiting !== undefined) {
|
|
18083
18521
|
return waiting(pvm);
|
|
@@ -18120,21 +18558,22 @@ declare class HostCalls {
|
|
|
18120
18558
|
private hostCalls: HostCallsManager,
|
|
18121
18559
|
) {}
|
|
18122
18560
|
|
|
18123
|
-
private getReturnValue(status: Status, pvmInstance:
|
|
18124
|
-
const gasConsumed = pvmInstance.
|
|
18561
|
+
private getReturnValue(status: Status, pvmInstance: IPvmInterpreter): ReturnValue {
|
|
18562
|
+
const gasConsumed = pvmInstance.gas.used();
|
|
18125
18563
|
if (status === Status.OOG) {
|
|
18126
18564
|
return ReturnValue.fromStatus(gasConsumed, status);
|
|
18127
18565
|
}
|
|
18128
18566
|
|
|
18129
18567
|
if (status === Status.HALT) {
|
|
18130
|
-
const
|
|
18131
|
-
const
|
|
18132
|
-
const
|
|
18133
|
-
|
|
18568
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
18569
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
18570
|
+
const address = regs.get(7);
|
|
18571
|
+
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
18572
|
+
const length = Number(regs.get(8) & 0xffff_ffffn);
|
|
18573
|
+
|
|
18574
|
+
const result = safeAllocUint8Array(length);
|
|
18134
18575
|
|
|
18135
|
-
const
|
|
18136
|
-
const startAddress = tryAsMemoryIndex(maybeAddress);
|
|
18137
|
-
const loadResult = memory.loadInto(result, startAddress);
|
|
18576
|
+
const loadResult = memory.loadInto(result, address);
|
|
18138
18577
|
|
|
18139
18578
|
if (loadResult.isError) {
|
|
18140
18579
|
return ReturnValue.fromMemorySlice(gasConsumed, new Uint8Array());
|
|
@@ -18146,7 +18585,7 @@ declare class HostCalls {
|
|
|
18146
18585
|
return ReturnValue.fromStatus(gasConsumed, Status.PANIC);
|
|
18147
18586
|
}
|
|
18148
18587
|
|
|
18149
|
-
private async execute(pvmInstance:
|
|
18588
|
+
private async execute(pvmInstance: IPvmInterpreter) {
|
|
18150
18589
|
pvmInstance.runProgram();
|
|
18151
18590
|
for (;;) {
|
|
18152
18591
|
let status = pvmInstance.getStatus();
|
|
@@ -18158,9 +18597,9 @@ declare class HostCalls {
|
|
|
18158
18597
|
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
18159
18598
|
`;
|
|
18160
18599
|
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
18161
|
-
const gas = pvmInstance.
|
|
18162
|
-
const regs = new HostCallRegisters(pvmInstance.
|
|
18163
|
-
const memory = new HostCallMemory(pvmInstance.
|
|
18600
|
+
const gas = pvmInstance.gas;
|
|
18601
|
+
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
18602
|
+
const memory = new HostCallMemory(pvmInstance.memory);
|
|
18164
18603
|
const index = tryAsHostCallIndex(hostCallIndex);
|
|
18165
18604
|
|
|
18166
18605
|
const hostCall = this.hostCalls.get(index);
|
|
@@ -18173,7 +18612,7 @@ declare class HostCalls {
|
|
|
18173
18612
|
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
18174
18613
|
if (underflow) {
|
|
18175
18614
|
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
18176
|
-
return ReturnValue.fromStatus(
|
|
18615
|
+
return ReturnValue.fromStatus(gas.used(), Status.OOG);
|
|
18177
18616
|
}
|
|
18178
18617
|
this.hostCalls.traceHostCall(`${pcLog} Invoking`, index, hostCall, regs, gasBefore);
|
|
18179
18618
|
const result = await hostCall.execute(gas, regs, memory);
|
|
@@ -18184,6 +18623,7 @@ declare class HostCalls {
|
|
|
18184
18623
|
regs,
|
|
18185
18624
|
gas.get(),
|
|
18186
18625
|
);
|
|
18626
|
+
pvmInstance.registers.setAllEncoded(regs.getEncoded());
|
|
18187
18627
|
|
|
18188
18628
|
if (result === PvmExecution.Halt) {
|
|
18189
18629
|
status = Status.HALT;
|
|
@@ -18210,15 +18650,9 @@ declare class HostCalls {
|
|
|
18210
18650
|
}
|
|
18211
18651
|
}
|
|
18212
18652
|
|
|
18213
|
-
async runProgram(
|
|
18214
|
-
rawProgram: Uint8Array,
|
|
18215
|
-
initialPc: number,
|
|
18216
|
-
initialGas: Gas,
|
|
18217
|
-
maybeRegisters?: Registers,
|
|
18218
|
-
maybeMemory?: Memory,
|
|
18219
|
-
): Promise<ReturnValue> {
|
|
18653
|
+
async runProgram(program: Uint8Array, args: Uint8Array, initialPc: number, initialGas: Gas): Promise<ReturnValue> {
|
|
18220
18654
|
const pvmInstance = await this.pvmInstanceManager.getInstance();
|
|
18221
|
-
pvmInstance.
|
|
18655
|
+
pvmInstance.resetJam(program, args, initialPc, initialGas);
|
|
18222
18656
|
try {
|
|
18223
18657
|
return await this.execute(pvmInstance);
|
|
18224
18658
|
} finally {
|
|
@@ -18227,20 +18661,18 @@ declare class HostCalls {
|
|
|
18227
18661
|
}
|
|
18228
18662
|
}
|
|
18229
18663
|
|
|
18230
|
-
type index$
|
|
18231
|
-
type index$
|
|
18232
|
-
declare const index$
|
|
18233
|
-
type index$
|
|
18234
|
-
declare const index$
|
|
18235
|
-
type index$
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
declare const index$
|
|
18239
|
-
declare
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
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 };
|
|
18243
|
-
export type { index$7_HostCallHandler as HostCallHandler, index$7_IHostCallMemory as IHostCallMemory, index$7_IHostCallRegisters as IHostCallRegisters };
|
|
18664
|
+
type index$5_HostCallHandler = HostCallHandler;
|
|
18665
|
+
type index$5_HostCallMemory = HostCallMemory;
|
|
18666
|
+
declare const index$5_HostCallMemory: typeof HostCallMemory;
|
|
18667
|
+
type index$5_HostCallRegisters = HostCallRegisters;
|
|
18668
|
+
declare const index$5_HostCallRegisters: typeof HostCallRegisters;
|
|
18669
|
+
type index$5_PvmExecution = PvmExecution;
|
|
18670
|
+
declare const index$5_PvmExecution: typeof PvmExecution;
|
|
18671
|
+
declare const index$5_traceRegisters: typeof traceRegisters;
|
|
18672
|
+
declare const index$5_tryAsHostCallIndex: typeof tryAsHostCallIndex;
|
|
18673
|
+
declare namespace index$5 {
|
|
18674
|
+
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 };
|
|
18675
|
+
export type { index$5_HostCallHandler as HostCallHandler };
|
|
18244
18676
|
}
|
|
18245
18677
|
|
|
18246
18678
|
/**
|
|
@@ -18258,7 +18690,7 @@ type MachineId = Opaque<U64, "MachineId[u64]">;
|
|
|
18258
18690
|
declare const tryAsMachineId = (v: number | bigint): MachineId => asOpaqueType(tryAsU64(v));
|
|
18259
18691
|
|
|
18260
18692
|
declare class MachineInstance {
|
|
18261
|
-
async run(gas: BigGas, registers:
|
|
18693
|
+
async run(gas: BigGas, registers: HostCallRegisters): Promise<MachineResult> {
|
|
18262
18694
|
return {
|
|
18263
18695
|
result: {
|
|
18264
18696
|
status: Status.OK,
|
|
@@ -18286,7 +18718,7 @@ type MachineStatus =
|
|
|
18286
18718
|
type MachineResult = {
|
|
18287
18719
|
result: MachineStatus;
|
|
18288
18720
|
gas: BigGas;
|
|
18289
|
-
registers:
|
|
18721
|
+
registers: HostCallRegisters;
|
|
18290
18722
|
};
|
|
18291
18723
|
|
|
18292
18724
|
/** Types of possbile operations to request by Pages host call. */
|
|
@@ -18358,7 +18790,7 @@ interface RefineExternalities {
|
|
|
18358
18790
|
destinationStart: U64,
|
|
18359
18791
|
sourceStart: U64,
|
|
18360
18792
|
length: U64,
|
|
18361
|
-
destination:
|
|
18793
|
+
destination: HostCallMemory,
|
|
18362
18794
|
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18363
18795
|
|
|
18364
18796
|
/** Write a fragment of memory into `machineIndex` from given source memory. */
|
|
@@ -18367,7 +18799,7 @@ interface RefineExternalities {
|
|
|
18367
18799
|
sourceStart: U64,
|
|
18368
18800
|
destinationStart: U64,
|
|
18369
18801
|
length: U64,
|
|
18370
|
-
source:
|
|
18802
|
+
source: HostCallMemory,
|
|
18371
18803
|
): Promise<Result$2<OK, PeekPokeError>>;
|
|
18372
18804
|
|
|
18373
18805
|
/** Start an inner PVM instance with given entry point and starting code. */
|
|
@@ -18377,7 +18809,7 @@ interface RefineExternalities {
|
|
|
18377
18809
|
machineInvoke(
|
|
18378
18810
|
machineIndex: MachineId,
|
|
18379
18811
|
gas: BigGas,
|
|
18380
|
-
registers:
|
|
18812
|
+
registers: HostCallRegisters,
|
|
18381
18813
|
): Promise<Result$2<MachineResult, NoMachineError>>;
|
|
18382
18814
|
|
|
18383
18815
|
/**
|
|
@@ -18799,7 +19231,7 @@ declare const CURRENT_SERVICE_ID = tryAsServiceId(2 ** 32 - 1);
|
|
|
18799
19231
|
|
|
18800
19232
|
declare function getServiceIdOrCurrent(
|
|
18801
19233
|
regNumber: number,
|
|
18802
|
-
regs:
|
|
19234
|
+
regs: HostCallRegisters,
|
|
18803
19235
|
currentServiceId: ServiceId,
|
|
18804
19236
|
): ServiceId | null {
|
|
18805
19237
|
const regValue = regs.get(regNumber);
|
|
@@ -18830,270 +19262,75 @@ declare function clampU64ToU32(value: U64): U32 {
|
|
|
18830
19262
|
return value > MAX_U32_BIG_INT ? MAX_U32 : tryAsU32(Number(value));
|
|
18831
19263
|
}
|
|
18832
19264
|
|
|
18833
|
-
|
|
18834
|
-
|
|
18835
|
-
|
|
18836
|
-
|
|
18837
|
-
|
|
18838
|
-
|
|
18839
|
-
declare const index$
|
|
18840
|
-
|
|
18841
|
-
|
|
18842
|
-
|
|
18843
|
-
declare const index$
|
|
18844
|
-
|
|
18845
|
-
type index$
|
|
18846
|
-
declare const index$
|
|
18847
|
-
|
|
18848
|
-
type index$
|
|
18849
|
-
type index$
|
|
18850
|
-
declare const index$
|
|
18851
|
-
type index$
|
|
18852
|
-
|
|
18853
|
-
type index$
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
type index$
|
|
18858
|
-
|
|
18859
|
-
|
|
18860
|
-
|
|
18861
|
-
type index$
|
|
18862
|
-
declare const index$
|
|
18863
|
-
type index$
|
|
18864
|
-
|
|
18865
|
-
|
|
18866
|
-
|
|
18867
|
-
type index$
|
|
18868
|
-
|
|
18869
|
-
|
|
18870
|
-
type index$
|
|
18871
|
-
|
|
18872
|
-
declare const index$
|
|
18873
|
-
type index$
|
|
18874
|
-
type index$
|
|
18875
|
-
|
|
18876
|
-
|
|
18877
|
-
type index$
|
|
18878
|
-
|
|
18879
|
-
type index$
|
|
18880
|
-
type index$
|
|
18881
|
-
|
|
18882
|
-
|
|
18883
|
-
|
|
18884
|
-
|
|
18885
|
-
declare const index$
|
|
18886
|
-
|
|
18887
|
-
declare const index$
|
|
18888
|
-
declare const index$
|
|
18889
|
-
declare const index$
|
|
18890
|
-
declare const index$
|
|
18891
|
-
declare const index$
|
|
18892
|
-
declare const index$
|
|
18893
|
-
declare const index$
|
|
18894
|
-
declare
|
|
18895
|
-
|
|
18896
|
-
|
|
18897
|
-
|
|
18898
|
-
|
|
18899
|
-
declare const NO_OF_REGISTERS = 13;
|
|
18900
|
-
|
|
18901
|
-
declare class MemorySegment extends WithDebug {
|
|
18902
|
-
static from({ start, end, data }: Omit<MemorySegment, never>) {
|
|
18903
|
-
return new MemorySegment(start, end, data);
|
|
18904
|
-
}
|
|
18905
|
-
|
|
18906
|
-
constructor(
|
|
18907
|
-
public readonly start: number,
|
|
18908
|
-
public readonly end: number,
|
|
18909
|
-
public readonly data: Uint8Array | null,
|
|
18910
|
-
) {
|
|
18911
|
-
super();
|
|
18912
|
-
}
|
|
18913
|
-
}
|
|
18914
|
-
declare class SpiMemory extends WithDebug {
|
|
18915
|
-
constructor(
|
|
18916
|
-
public readonly readable: MemorySegment[],
|
|
18917
|
-
public readonly writeable: MemorySegment[],
|
|
18918
|
-
public readonly sbrkIndex: number,
|
|
18919
|
-
public readonly heapEnd: number,
|
|
18920
|
-
) {
|
|
18921
|
-
super();
|
|
18922
|
-
}
|
|
18923
|
-
}
|
|
18924
|
-
|
|
18925
|
-
declare class SpiProgram extends WithDebug {
|
|
18926
|
-
constructor(
|
|
18927
|
-
public readonly code: Uint8Array,
|
|
18928
|
-
public readonly memory: SpiMemory,
|
|
18929
|
-
public readonly registers: BigUint64Array,
|
|
18930
|
-
) {
|
|
18931
|
-
super();
|
|
18932
|
-
}
|
|
18933
|
-
}
|
|
18934
|
-
|
|
18935
|
-
/**
|
|
18936
|
-
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
18937
|
-
*
|
|
18938
|
-
* E_n - little endian encoding, n - length
|
|
18939
|
-
* o - initial read only data
|
|
18940
|
-
* w - initial heap
|
|
18941
|
-
* z - heap pages filled with zeros
|
|
18942
|
-
* s - stack size
|
|
18943
|
-
* c - program code
|
|
18944
|
-
*
|
|
18945
|
-
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
18946
|
-
*/
|
|
18947
|
-
declare function decodeStandardProgram(program: Uint8Array, args: Uint8Array) {
|
|
18948
|
-
const decoder = Decoder.fromBlob(program);
|
|
18949
|
-
const oLength = decoder.u24();
|
|
18950
|
-
const wLength = decoder.u24();
|
|
18951
|
-
check`${args.length <= DATA_LENGTH} Incorrect arguments length`;
|
|
18952
|
-
check`${oLength <= DATA_LENGTH} Incorrect readonly segment length`;
|
|
18953
|
-
const readOnlyLength = oLength;
|
|
18954
|
-
check`${wLength <= DATA_LENGTH} Incorrect heap segment length`;
|
|
18955
|
-
const heapLength = wLength;
|
|
18956
|
-
const noOfHeapZerosPages = decoder.u16();
|
|
18957
|
-
const stackSize = decoder.u24();
|
|
18958
|
-
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
18959
|
-
const initialHeap = decoder.bytes(heapLength).raw;
|
|
18960
|
-
const codeLength = decoder.u32();
|
|
18961
|
-
const code = decoder.bytes(codeLength).raw;
|
|
18962
|
-
decoder.finish();
|
|
18963
|
-
|
|
18964
|
-
const readonlyDataStart = SEGMENT_SIZE;
|
|
18965
|
-
const readonlyDataEnd = SEGMENT_SIZE + alignToPageSize(readOnlyLength);
|
|
18966
|
-
const heapDataStart = 2 * SEGMENT_SIZE + alignToSegmentSize(readOnlyLength);
|
|
18967
|
-
const heapDataEnd = heapDataStart + alignToPageSize(heapLength);
|
|
18968
|
-
const heapZerosEnd = heapDataStart + alignToPageSize(heapLength) + noOfHeapZerosPages * PAGE_SIZE;
|
|
18969
|
-
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
18970
|
-
const stackEnd = STACK_SEGMENT;
|
|
18971
|
-
const argsStart = ARGS_SEGMENT;
|
|
18972
|
-
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
18973
|
-
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
18974
|
-
|
|
18975
|
-
function nonEmpty(s: MemorySegment | false): s is MemorySegment {
|
|
18976
|
-
return s !== false;
|
|
18977
|
-
}
|
|
18978
|
-
|
|
18979
|
-
const readableMemory = [
|
|
18980
|
-
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
18981
|
-
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
18982
|
-
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
18983
|
-
].filter(nonEmpty);
|
|
18984
|
-
const writeableMemory = [
|
|
18985
|
-
heapLength > 0 && getMemorySegment(heapDataStart, heapDataEnd, initialHeap),
|
|
18986
|
-
heapDataEnd < heapZerosEnd && getMemorySegment(heapDataEnd, heapZerosEnd),
|
|
18987
|
-
stackStart < stackEnd && getMemorySegment(stackStart, stackEnd),
|
|
18988
|
-
].filter(nonEmpty);
|
|
18989
|
-
|
|
18990
|
-
return new SpiProgram(
|
|
18991
|
-
code,
|
|
18992
|
-
new SpiMemory(readableMemory, writeableMemory, heapZerosEnd, stackStart),
|
|
18993
|
-
getRegisters(args.length),
|
|
18994
|
-
);
|
|
18995
|
-
}
|
|
18996
|
-
|
|
18997
|
-
declare function getMemorySegment(start: number, end: number, data: Uint8Array | null = null) {
|
|
18998
|
-
return new MemorySegment(start, end, data);
|
|
18999
|
-
}
|
|
19000
|
-
|
|
19001
|
-
declare function getRegisters(argsLength: number) {
|
|
19002
|
-
const regs = new BigUint64Array(NO_OF_REGISTERS);
|
|
19003
|
-
|
|
19004
|
-
// GP reference: https://graypaper.fluffylabs.dev/#/579bd12/2c7c012cb101
|
|
19005
|
-
regs[0] = BigInt(LAST_PAGE);
|
|
19006
|
-
regs[1] = BigInt(STACK_SEGMENT);
|
|
19007
|
-
regs[7] = BigInt(ARGS_SEGMENT);
|
|
19008
|
-
regs[8] = BigInt(argsLength);
|
|
19009
|
-
|
|
19010
|
-
return regs;
|
|
19011
|
-
}
|
|
19012
|
-
|
|
19013
|
-
type index$5_MemorySegment = MemorySegment;
|
|
19014
|
-
declare const index$5_MemorySegment: typeof MemorySegment;
|
|
19015
|
-
declare const index$5_NO_OF_REGISTERS: typeof NO_OF_REGISTERS;
|
|
19016
|
-
type index$5_SpiMemory = SpiMemory;
|
|
19017
|
-
declare const index$5_SpiMemory: typeof SpiMemory;
|
|
19018
|
-
type index$5_SpiProgram = SpiProgram;
|
|
19019
|
-
declare const index$5_SpiProgram: typeof SpiProgram;
|
|
19020
|
-
declare const index$5_decodeStandardProgram: typeof decodeStandardProgram;
|
|
19021
|
-
declare const index$5_getMemorySegment: typeof getMemorySegment;
|
|
19022
|
-
declare const index$5_getRegisters: typeof getRegisters;
|
|
19023
|
-
declare namespace index$5 {
|
|
19024
|
-
export {
|
|
19025
|
-
index$5_MemorySegment as MemorySegment,
|
|
19026
|
-
index$5_NO_OF_REGISTERS as NO_OF_REGISTERS,
|
|
19027
|
-
index$5_SpiMemory as SpiMemory,
|
|
19028
|
-
index$5_SpiProgram as SpiProgram,
|
|
19029
|
-
index$5_decodeStandardProgram as decodeStandardProgram,
|
|
19030
|
-
index$5_getMemorySegment as getMemorySegment,
|
|
19031
|
-
index$5_getRegisters as getRegisters,
|
|
19032
|
-
};
|
|
19033
|
-
}
|
|
19034
|
-
|
|
19035
|
-
declare class Program {
|
|
19036
|
-
static fromSpi(blob: Uint8Array, args: Uint8Array, hasMetadata: boolean) {
|
|
19037
|
-
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
19038
|
-
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
19039
|
-
const regs = new Registers();
|
|
19040
|
-
regs.copyFrom(registers);
|
|
19041
|
-
const memoryBuilder = new MemoryBuilder();
|
|
19042
|
-
|
|
19043
|
-
for (const { start, end, data } of rawMemory.readable) {
|
|
19044
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
19045
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
19046
|
-
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
19047
|
-
}
|
|
19048
|
-
|
|
19049
|
-
for (const { start, end, data } of rawMemory.writeable) {
|
|
19050
|
-
const startIndex = tryAsMemoryIndex(start);
|
|
19051
|
-
const endIndex = tryAsMemoryIndex(end);
|
|
19052
|
-
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
19053
|
-
}
|
|
19054
|
-
|
|
19055
|
-
const heapStart = tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
19056
|
-
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
19057
|
-
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
19058
|
-
|
|
19059
|
-
return new Program(code, regs, memory, metadata);
|
|
19060
|
-
}
|
|
19061
|
-
|
|
19062
|
-
static fromGeneric(blob: Uint8Array, hasMetadata: boolean) {
|
|
19063
|
-
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
19064
|
-
const regs = new Registers();
|
|
19065
|
-
const memory = new Memory();
|
|
19066
|
-
return new Program(code, regs, memory, metadata);
|
|
19067
|
-
}
|
|
19068
|
-
|
|
19069
|
-
private constructor(
|
|
19070
|
-
public readonly code: Uint8Array,
|
|
19071
|
-
public readonly registers: Registers,
|
|
19072
|
-
public readonly memory: Memory,
|
|
19073
|
-
public metadata: Uint8Array = new Uint8Array(),
|
|
19074
|
-
) {}
|
|
19075
|
-
}
|
|
19076
|
-
|
|
19077
|
-
/**
|
|
19078
|
-
* A function that splits preimage into metadata and code.
|
|
19079
|
-
*
|
|
19080
|
-
* https://graypaper.fluffylabs.dev/#/cc517d7/109a01109a01?v=0.6.5
|
|
19081
|
-
*/
|
|
19082
|
-
declare function extractCodeAndMetadata(blobWithMetadata: Uint8Array) {
|
|
19083
|
-
const decoder = Decoder.fromBlob(blobWithMetadata);
|
|
19084
|
-
const metadata = decoder.bytesBlob().raw;
|
|
19085
|
-
const code = decoder.remainingBytes().raw;
|
|
19086
|
-
return { metadata, code };
|
|
19087
|
-
}
|
|
19088
|
-
|
|
19089
|
-
type index$4_Program = Program;
|
|
19090
|
-
declare const index$4_Program: typeof Program;
|
|
19091
|
-
declare const index$4_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
19265
|
+
declare function emptyRegistersBuffer(): Uint8Array {
|
|
19266
|
+
return safeAllocUint8Array(NO_OF_REGISTERS * REGISTER_BYTE_SIZE);
|
|
19267
|
+
}
|
|
19268
|
+
|
|
19269
|
+
type index$4_AccumulationStateUpdate = AccumulationStateUpdate;
|
|
19270
|
+
declare const index$4_AccumulationStateUpdate: typeof AccumulationStateUpdate;
|
|
19271
|
+
declare const index$4_CURRENT_SERVICE_ID: typeof CURRENT_SERVICE_ID;
|
|
19272
|
+
type index$4_EjectError = EjectError;
|
|
19273
|
+
declare const index$4_EjectError: typeof EjectError;
|
|
19274
|
+
type index$4_ForgetPreimageError = ForgetPreimageError;
|
|
19275
|
+
declare const index$4_ForgetPreimageError: typeof ForgetPreimageError;
|
|
19276
|
+
declare const index$4_HostCallResult: typeof HostCallResult;
|
|
19277
|
+
type index$4_InsufficientFundsError = InsufficientFundsError;
|
|
19278
|
+
declare const index$4_MAX_U32: typeof MAX_U32;
|
|
19279
|
+
declare const index$4_MAX_U32_BIG_INT: typeof MAX_U32_BIG_INT;
|
|
19280
|
+
type index$4_MachineId = MachineId;
|
|
19281
|
+
type index$4_MachineInstance = MachineInstance;
|
|
19282
|
+
declare const index$4_MachineInstance: typeof MachineInstance;
|
|
19283
|
+
type index$4_MachineResult = MachineResult;
|
|
19284
|
+
type index$4_MachineStatus = MachineStatus;
|
|
19285
|
+
type index$4_MemoryOperation = MemoryOperation;
|
|
19286
|
+
declare const index$4_MemoryOperation: typeof MemoryOperation;
|
|
19287
|
+
type index$4_NewServiceError = NewServiceError;
|
|
19288
|
+
declare const index$4_NewServiceError: typeof NewServiceError;
|
|
19289
|
+
type index$4_NoMachineError = NoMachineError;
|
|
19290
|
+
type index$4_PagesError = PagesError;
|
|
19291
|
+
declare const index$4_PagesError: typeof PagesError;
|
|
19292
|
+
type index$4_PartialState = PartialState;
|
|
19293
|
+
type index$4_PartiallyUpdatedState<T extends StateSlice = StateSlice> = PartiallyUpdatedState<T>;
|
|
19294
|
+
declare const index$4_PartiallyUpdatedState: typeof PartiallyUpdatedState;
|
|
19295
|
+
type index$4_PeekPokeError = PeekPokeError;
|
|
19296
|
+
declare const index$4_PeekPokeError: typeof PeekPokeError;
|
|
19297
|
+
type index$4_PendingTransfer = PendingTransfer;
|
|
19298
|
+
declare const index$4_PendingTransfer: typeof PendingTransfer;
|
|
19299
|
+
type index$4_PreimageStatus = PreimageStatus;
|
|
19300
|
+
type index$4_PreimageStatusKind = PreimageStatusKind;
|
|
19301
|
+
declare const index$4_PreimageStatusKind: typeof PreimageStatusKind;
|
|
19302
|
+
type index$4_ProgramCounter = ProgramCounter;
|
|
19303
|
+
type index$4_ProvidePreimageError = ProvidePreimageError;
|
|
19304
|
+
declare const index$4_ProvidePreimageError: typeof ProvidePreimageError;
|
|
19305
|
+
type index$4_RefineExternalities = RefineExternalities;
|
|
19306
|
+
type index$4_RequestPreimageError = RequestPreimageError;
|
|
19307
|
+
declare const index$4_RequestPreimageError: typeof RequestPreimageError;
|
|
19308
|
+
declare const index$4_SERVICE_ID_BYTES: typeof SERVICE_ID_BYTES;
|
|
19309
|
+
type index$4_SegmentExportError = SegmentExportError;
|
|
19310
|
+
type index$4_ServiceStateUpdate = ServiceStateUpdate;
|
|
19311
|
+
type index$4_StateSlice = StateSlice;
|
|
19312
|
+
type index$4_TRANSFER_MEMO_BYTES = TRANSFER_MEMO_BYTES;
|
|
19313
|
+
type index$4_TransferError = TransferError;
|
|
19314
|
+
declare const index$4_TransferError: typeof TransferError;
|
|
19315
|
+
type index$4_UnprivilegedError = UnprivilegedError;
|
|
19316
|
+
type index$4_UpdatePrivilegesError = UpdatePrivilegesError;
|
|
19317
|
+
declare const index$4_UpdatePrivilegesError: typeof UpdatePrivilegesError;
|
|
19318
|
+
type index$4_ZeroVoidError = ZeroVoidError;
|
|
19319
|
+
declare const index$4_ZeroVoidError: typeof ZeroVoidError;
|
|
19320
|
+
declare const index$4_clampU64ToU32: typeof clampU64ToU32;
|
|
19321
|
+
declare const index$4_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
19322
|
+
declare const index$4_emptyRegistersBuffer: typeof emptyRegistersBuffer;
|
|
19323
|
+
declare const index$4_getServiceId: typeof getServiceId;
|
|
19324
|
+
declare const index$4_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
19325
|
+
declare const index$4_preimageLenAsU32: typeof preimageLenAsU32;
|
|
19326
|
+
declare const index$4_slotsToPreimageStatus: typeof slotsToPreimageStatus;
|
|
19327
|
+
declare const index$4_toMemoryOperation: typeof toMemoryOperation;
|
|
19328
|
+
declare const index$4_tryAsMachineId: typeof tryAsMachineId;
|
|
19329
|
+
declare const index$4_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
19330
|
+
declare const index$4_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
19092
19331
|
declare namespace index$4 {
|
|
19093
|
-
export {
|
|
19094
|
-
|
|
19095
|
-
index$4_extractCodeAndMetadata as extractCodeAndMetadata,
|
|
19096
|
-
};
|
|
19332
|
+
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 };
|
|
19333
|
+
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 };
|
|
19097
19334
|
}
|
|
19098
19335
|
|
|
19099
19336
|
declare class DebuggerAdapter {
|
|
@@ -19109,11 +19346,11 @@ declare class DebuggerAdapter {
|
|
|
19109
19346
|
}
|
|
19110
19347
|
|
|
19111
19348
|
resetGeneric(rawProgram: Uint8Array, flatRegisters: Uint8Array, initialGas: bigint) {
|
|
19112
|
-
this.pvm.
|
|
19349
|
+
this.pvm.resetGeneric(rawProgram, 0, tryAsGas(initialGas), new Registers(flatRegisters));
|
|
19113
19350
|
}
|
|
19114
19351
|
|
|
19115
19352
|
reset(rawProgram: Uint8Array, pc: number, gas: bigint, maybeRegisters?: Registers, maybeMemory?: Memory) {
|
|
19116
|
-
this.pvm.
|
|
19353
|
+
this.pvm.resetGeneric(rawProgram, pc, tryAsGas(gas), maybeRegisters, maybeMemory);
|
|
19117
19354
|
}
|
|
19118
19355
|
|
|
19119
19356
|
getPageDump(pageNumber: number): null | Uint8Array {
|
|
@@ -19136,7 +19373,7 @@ declare class DebuggerAdapter {
|
|
|
19136
19373
|
}
|
|
19137
19374
|
|
|
19138
19375
|
setMemory(address: number, value: Uint8Array) {
|
|
19139
|
-
this.pvm.
|
|
19376
|
+
this.pvm.memory.storeFrom(tryAsMemoryIndex(address), value);
|
|
19140
19377
|
}
|
|
19141
19378
|
|
|
19142
19379
|
getExitArg(): number {
|
|
@@ -19163,11 +19400,11 @@ declare class DebuggerAdapter {
|
|
|
19163
19400
|
}
|
|
19164
19401
|
|
|
19165
19402
|
getRegisters(): BigUint64Array {
|
|
19166
|
-
return this.pvm.
|
|
19403
|
+
return this.pvm.registers.getAllU64();
|
|
19167
19404
|
}
|
|
19168
19405
|
|
|
19169
19406
|
setRegisters(registers: Uint8Array) {
|
|
19170
|
-
this.pvm.
|
|
19407
|
+
this.pvm.registers.copyFrom(new Registers(registers));
|
|
19171
19408
|
}
|
|
19172
19409
|
|
|
19173
19410
|
getProgramCounter(): number {
|
|
@@ -19179,11 +19416,11 @@ declare class DebuggerAdapter {
|
|
|
19179
19416
|
}
|
|
19180
19417
|
|
|
19181
19418
|
getGasLeft(): bigint {
|
|
19182
|
-
return BigInt(this.pvm.
|
|
19419
|
+
return BigInt(this.pvm.gas.get());
|
|
19183
19420
|
}
|
|
19184
19421
|
|
|
19185
19422
|
setGasLeft(gas: bigint) {
|
|
19186
|
-
this.pvm.
|
|
19423
|
+
this.pvm.gas.set(tryAsGas(gas));
|
|
19187
19424
|
}
|
|
19188
19425
|
}
|
|
19189
19426
|
|
|
@@ -19210,8 +19447,6 @@ declare const index$3_HostCallMemory: typeof HostCallMemory;
|
|
|
19210
19447
|
type index$3_HostCallRegisters = HostCallRegisters;
|
|
19211
19448
|
declare const index$3_HostCallRegisters: typeof HostCallRegisters;
|
|
19212
19449
|
declare const index$3_HostCallResult: typeof HostCallResult;
|
|
19213
|
-
type index$3_IHostCallMemory = IHostCallMemory;
|
|
19214
|
-
type index$3_IHostCallRegisters = IHostCallRegisters;
|
|
19215
19450
|
type index$3_ImmediateDecoder = ImmediateDecoder;
|
|
19216
19451
|
declare const index$3_ImmediateDecoder: typeof ImmediateDecoder;
|
|
19217
19452
|
type index$3_InsufficientFundsError = InsufficientFundsError;
|
|
@@ -19294,6 +19529,7 @@ declare const index$3_clampU64ToU32: typeof clampU64ToU32;
|
|
|
19294
19529
|
declare const index$3_createResults: typeof createResults;
|
|
19295
19530
|
declare const index$3_decodeStandardProgram: typeof decodeStandardProgram;
|
|
19296
19531
|
declare const index$3_deepCloneMapWithArray: typeof deepCloneMapWithArray;
|
|
19532
|
+
declare const index$3_emptyRegistersBuffer: typeof emptyRegistersBuffer;
|
|
19297
19533
|
declare const index$3_extractCodeAndMetadata: typeof extractCodeAndMetadata;
|
|
19298
19534
|
declare const index$3_getServiceId: typeof getServiceId;
|
|
19299
19535
|
declare const index$3_getServiceIdOrCurrent: typeof getServiceIdOrCurrent;
|
|
@@ -19312,8 +19548,8 @@ declare const index$3_tryAsMachineId: typeof tryAsMachineId;
|
|
|
19312
19548
|
declare const index$3_tryAsProgramCounter: typeof tryAsProgramCounter;
|
|
19313
19549
|
declare const index$3_writeServiceIdAsLeBytes: typeof writeServiceIdAsLeBytes;
|
|
19314
19550
|
declare namespace index$3 {
|
|
19315
|
-
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$
|
|
19316
|
-
export type { index$3_Args as Args, index$3_EnumMapping as EnumMapping, index$3_ErrorResult as ErrorResult, index$
|
|
19551
|
+
export { index$3_AccumulationStateUpdate as AccumulationStateUpdate, index$3_ArgsDecoder as ArgsDecoder, index$3_ArgumentType as ArgumentType, index$3_BasicBlocks as BasicBlocks, index$3_CURRENT_SERVICE_ID as CURRENT_SERVICE_ID, index$3_EjectError as EjectError, index$3_ExtendedWitdthImmediateDecoder as ExtendedWitdthImmediateDecoder, index$3_ForgetPreimageError as ForgetPreimageError, index$3_HostCallMemory as HostCallMemory, index$3_HostCallRegisters as HostCallRegisters, index$3_HostCallResult as HostCallResult, index$3_ImmediateDecoder as ImmediateDecoder, index$3_MAX_U32 as MAX_U32, index$3_MAX_U32_BIG_INT as MAX_U32_BIG_INT, index$3_MachineInstance as MachineInstance, index$3_Mask as Mask, index$3_MemoryOperation as MemoryOperation, index$3_MemorySegment as MemorySegment, NO_OF_REGISTERS$1 as NO_OF_REGISTERS, index$3_NewServiceError as NewServiceError, index$3_NibblesDecoder as NibblesDecoder, index$3_PagesError as PagesError, index$3_PartiallyUpdatedState as PartiallyUpdatedState, index$3_PeekPokeError as PeekPokeError, index$3_PendingTransfer as PendingTransfer, index$3_PreimageStatusKind as PreimageStatusKind, index$3_Program as Program, index$3_ProgramDecoder as ProgramDecoder, index$3_ProvidePreimageError as ProvidePreimageError, DebuggerAdapter as Pvm, index$3_Registers as Registers, index$3_RequestPreimageError as RequestPreimageError, Result$2 as Result, index$3_RichTaggedError as RichTaggedError, index$3_SERVICE_ID_BYTES as SERVICE_ID_BYTES, index$3_SpiMemory as SpiMemory, index$3_SpiProgram as SpiProgram, index$3_TransferError as TransferError, index$3_UpdatePrivilegesError as UpdatePrivilegesError, index$3_WithDebug as WithDebug, index$3_ZeroVoidError as ZeroVoidError, index$3___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$3_asOpaqueType as asOpaqueType, index$3_assertEmpty as assertEmpty, index$3_assertNever as assertNever, index$l as block, index$s as bytes, index$3_check as check, index$3_clampU64ToU32 as clampU64ToU32, index$3_createResults as createResults, index$3_decodeStandardProgram as decodeStandardProgram, index$3_deepCloneMapWithArray as deepCloneMapWithArray, index$3_emptyRegistersBuffer as emptyRegistersBuffer, index$3_extractCodeAndMetadata as extractCodeAndMetadata, index$3_getServiceId as getServiceId, index$3_getServiceIdOrCurrent as getServiceIdOrCurrent, index$p as hash, index$3_inspect as inspect, index$3_instructionArgumentTypeMap as instructionArgumentTypeMap, index$6 as interpreter, index$3_isBrowser as isBrowser, index$3_isTaggedError as isTaggedError, index$3_maybeTaggedErrorToString as maybeTaggedErrorToString, index$3_measure as measure, index$r as numbers, index$3_preimageLenAsU32 as preimageLenAsU32, index$3_resultToString as resultToString, index$3_seeThrough as seeThrough, index$3_slotsToPreimageStatus as slotsToPreimageStatus, index$3_toMemoryOperation as toMemoryOperation, index$3_tryAsMachineId as tryAsMachineId, index$3_tryAsProgramCounter as tryAsProgramCounter, index$3_writeServiceIdAsLeBytes as writeServiceIdAsLeBytes };
|
|
19552
|
+
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 };
|
|
19317
19553
|
}
|
|
19318
19554
|
|
|
19319
19555
|
declare const ENTROPY_BYTES = 32;
|
|
@@ -20205,4 +20441,4 @@ declare namespace index {
|
|
|
20205
20441
|
export type { index_PreimagesInput as PreimagesInput, index_PreimagesState as PreimagesState, index_PreimagesStateUpdate as PreimagesStateUpdate };
|
|
20206
20442
|
}
|
|
20207
20443
|
|
|
20208
|
-
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$
|
|
20444
|
+
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 };
|