@typeberry/jam 0.4.0-2473e55 → 0.4.0-248b604
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/bootstrap-generator.mjs +5 -1
- package/bootstrap-generator.mjs.map +1 -1
- package/bootstrap-importer.mjs +186 -106
- package/bootstrap-importer.mjs.map +1 -1
- package/bootstrap-network.mjs +5 -1
- package/bootstrap-network.mjs.map +1 -1
- package/index.js +186 -106
- package/index.js.map +1 -1
- package/package.json +1 -1
package/bootstrap-importer.mjs
CHANGED
|
@@ -3550,7 +3550,11 @@ var TestSuite;
|
|
|
3550
3550
|
})(TestSuite || (TestSuite = {}));
|
|
3551
3551
|
const ALL_VERSIONS_IN_ORDER = [compatibility_GpVersion.V0_6_7, compatibility_GpVersion.V0_7_0, compatibility_GpVersion.V0_7_1, compatibility_GpVersion.V0_7_2];
|
|
3552
3552
|
const DEFAULT_SUITE = TestSuite.W3F_DAVXY;
|
|
3553
|
-
|
|
3553
|
+
/**
|
|
3554
|
+
* Current version is set to track the jam-conformance testing.
|
|
3555
|
+
* Since we are currently at 0.7.1 not 0.7.2, we set our default version accordingly.
|
|
3556
|
+
*/
|
|
3557
|
+
const DEFAULT_VERSION = compatibility_GpVersion.V0_7_1;
|
|
3554
3558
|
const env = typeof process === "undefined" ? {} : process.env;
|
|
3555
3559
|
let CURRENT_VERSION = parseCurrentVersion(env.GP_VERSION) ?? DEFAULT_VERSION;
|
|
3556
3560
|
let CURRENT_SUITE = parseCurrentSuite(env.TEST_SUITE) ?? DEFAULT_SUITE;
|
|
@@ -14384,7 +14388,7 @@ const gas_tryAsSmallGas = (v) => opaque_asOpaqueType(numbers_tryAsU32(v));
|
|
|
14384
14388
|
/** Attempt to convert given number into U64 gas representation. */
|
|
14385
14389
|
const tryAsBigGas = (v) => opaque_asOpaqueType(numbers_tryAsU64(v));
|
|
14386
14390
|
/** Attempt to convert given number into gas. */
|
|
14387
|
-
const
|
|
14391
|
+
const gas_tryAsGas = (v) => typeof v === "number" && v < 2 ** 32 ? gas_tryAsSmallGas(v) : tryAsBigGas(v);
|
|
14388
14392
|
|
|
14389
14393
|
;// CONCATENATED MODULE: ./packages/core/pvm-interface/memory.ts
|
|
14390
14394
|
|
|
@@ -14667,7 +14671,7 @@ const tryAsRegisterIndex = (index) => {
|
|
|
14667
14671
|
debug_check `${index >= 0 && index < registers_NO_OF_REGISTERS} Incorrect register index: ${index}!`;
|
|
14668
14672
|
return opaque_asOpaqueType(index);
|
|
14669
14673
|
};
|
|
14670
|
-
class
|
|
14674
|
+
class registers_Registers {
|
|
14671
14675
|
bytes;
|
|
14672
14676
|
asSigned;
|
|
14673
14677
|
asUnsigned;
|
|
@@ -14686,7 +14690,7 @@ class Registers {
|
|
|
14686
14690
|
}
|
|
14687
14691
|
static fromBytes(bytes) {
|
|
14688
14692
|
debug_check `${bytes.length === registers_NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14689
|
-
return new
|
|
14693
|
+
return new registers_Registers(bytes);
|
|
14690
14694
|
}
|
|
14691
14695
|
getBytesAsLittleEndian(index, len) {
|
|
14692
14696
|
const offset = index << REGISTER_SIZE_SHIFT;
|
|
@@ -15000,49 +15004,10 @@ class NoopMissing {
|
|
|
15000
15004
|
}
|
|
15001
15005
|
}
|
|
15002
15006
|
|
|
15003
|
-
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/gas.ts
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
/** Create a new gas counter instance depending on the gas value. */
|
|
15007
|
-
function gasCounter(gas) {
|
|
15008
|
-
return new GasCounterU64(numbers_tryAsU64(gas));
|
|
15009
|
-
}
|
|
15010
|
-
class GasCounterU64 {
|
|
15011
|
-
gas;
|
|
15012
|
-
initialGas;
|
|
15013
|
-
constructor(gas) {
|
|
15014
|
-
this.gas = gas;
|
|
15015
|
-
this.initialGas = tryAsGas(gas);
|
|
15016
|
-
}
|
|
15017
|
-
set(g) {
|
|
15018
|
-
this.gas = numbers_tryAsU64(g);
|
|
15019
|
-
}
|
|
15020
|
-
get() {
|
|
15021
|
-
return tryAsGas(this.gas);
|
|
15022
|
-
}
|
|
15023
|
-
sub(g) {
|
|
15024
|
-
const result = this.gas - numbers_tryAsU64(g);
|
|
15025
|
-
if (result >= 0n) {
|
|
15026
|
-
this.gas = numbers_tryAsU64(result);
|
|
15027
|
-
return false;
|
|
15028
|
-
}
|
|
15029
|
-
this.gas = numbers_tryAsU64(0n);
|
|
15030
|
-
return true;
|
|
15031
|
-
}
|
|
15032
|
-
used() {
|
|
15033
|
-
const gasConsumed = numbers_tryAsU64(this.initialGas) - this.gas;
|
|
15034
|
-
// In we have less than zero left we assume that all gas has been consumed.
|
|
15035
|
-
if (gasConsumed < 0) {
|
|
15036
|
-
return this.initialGas;
|
|
15037
|
-
}
|
|
15038
|
-
return tryAsGas(gasConsumed);
|
|
15039
|
-
}
|
|
15040
|
-
}
|
|
15041
|
-
|
|
15042
15007
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/memory-index.ts
|
|
15043
15008
|
|
|
15044
15009
|
|
|
15045
|
-
const
|
|
15010
|
+
const memory_index_tryAsMemoryIndex = (index) => {
|
|
15046
15011
|
debug_check `${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15047
15012
|
return opaque_asOpaqueType(index);
|
|
15048
15013
|
};
|
|
@@ -15056,25 +15021,25 @@ const tryAsSbrkIndex = (index) => {
|
|
|
15056
15021
|
|
|
15057
15022
|
const memory_consts_PAGE_SIZE_SHIFT = 12;
|
|
15058
15023
|
// PAGE_SIZE has to be a power of 2
|
|
15059
|
-
const
|
|
15024
|
+
const memory_consts_PAGE_SIZE = 1 << memory_consts_PAGE_SIZE_SHIFT;
|
|
15060
15025
|
const MIN_ALLOCATION_SHIFT = (() => {
|
|
15061
15026
|
const MIN_ALLOCATION_SHIFT = 7;
|
|
15062
15027
|
debug_check `${MIN_ALLOCATION_SHIFT >= 0 && MIN_ALLOCATION_SHIFT < memory_consts_PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
15063
15028
|
return MIN_ALLOCATION_SHIFT;
|
|
15064
15029
|
})();
|
|
15065
|
-
const MIN_ALLOCATION_LENGTH =
|
|
15066
|
-
const LAST_PAGE_NUMBER = (MEMORY_SIZE -
|
|
15030
|
+
const MIN_ALLOCATION_LENGTH = memory_consts_PAGE_SIZE >> MIN_ALLOCATION_SHIFT;
|
|
15031
|
+
const LAST_PAGE_NUMBER = (MEMORY_SIZE - memory_consts_PAGE_SIZE) / memory_consts_PAGE_SIZE;
|
|
15067
15032
|
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
15068
15033
|
const RESERVED_NUMBER_OF_PAGES = 16;
|
|
15069
15034
|
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
15070
|
-
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE /
|
|
15035
|
+
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE / memory_consts_PAGE_SIZE;
|
|
15071
15036
|
|
|
15072
15037
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/pages/page-utils.ts
|
|
15073
15038
|
|
|
15074
15039
|
|
|
15075
15040
|
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
15076
15041
|
const tryAsPageIndex = (index) => {
|
|
15077
|
-
debug_check `${index >= 0 && index <
|
|
15042
|
+
debug_check `${index >= 0 && index < memory_consts_PAGE_SIZE}, Incorect page index: ${index}!`;
|
|
15078
15043
|
return opaque_asOpaqueType(index);
|
|
15079
15044
|
};
|
|
15080
15045
|
/** Ensure that given `index` represents an index of one of the pages. */
|
|
@@ -15102,17 +15067,17 @@ function getNextPageNumber(pageNumber) {
|
|
|
15102
15067
|
|
|
15103
15068
|
|
|
15104
15069
|
function alignToPageSize(length) {
|
|
15105
|
-
return
|
|
15070
|
+
return memory_consts_PAGE_SIZE * Math.ceil(length / memory_consts_PAGE_SIZE);
|
|
15106
15071
|
}
|
|
15107
15072
|
function getPageNumber(address) {
|
|
15108
15073
|
return tryAsPageNumber(address >>> memory_consts_PAGE_SIZE_SHIFT);
|
|
15109
15074
|
}
|
|
15110
15075
|
function getStartPageIndex(address) {
|
|
15111
|
-
return
|
|
15076
|
+
return memory_index_tryAsMemoryIndex((address >>> memory_consts_PAGE_SIZE_SHIFT) << memory_consts_PAGE_SIZE_SHIFT);
|
|
15112
15077
|
}
|
|
15113
15078
|
function getStartPageIndexFromPageNumber(pageNumber) {
|
|
15114
15079
|
// >>> 0 is needed to avoid changing sign of the number
|
|
15115
|
-
return
|
|
15080
|
+
return memory_index_tryAsMemoryIndex((pageNumber << memory_consts_PAGE_SIZE_SHIFT) >>> 0);
|
|
15116
15081
|
}
|
|
15117
15082
|
|
|
15118
15083
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/errors.ts
|
|
@@ -15134,7 +15099,7 @@ class PageFault {
|
|
|
15134
15099
|
return new PageFault(numbers_tryAsU32(startPageIndex), isAccessFault);
|
|
15135
15100
|
}
|
|
15136
15101
|
static fromMemoryIndex(maybeMemoryIndex, isAccessFault = false) {
|
|
15137
|
-
const memoryIndex =
|
|
15102
|
+
const memoryIndex = memory_index_tryAsMemoryIndex(maybeMemoryIndex % MEMORY_SIZE);
|
|
15138
15103
|
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
15139
15104
|
return new PageFault(numbers_tryAsU32(startPageIndex), isAccessFault);
|
|
15140
15105
|
}
|
|
@@ -15213,9 +15178,9 @@ class MemoryRange {
|
|
|
15213
15178
|
constructor(start, length) {
|
|
15214
15179
|
this.start = start;
|
|
15215
15180
|
this.length = length;
|
|
15216
|
-
this.end =
|
|
15181
|
+
this.end = memory_index_tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
15217
15182
|
if (length > 0) {
|
|
15218
|
-
this.lastIndex =
|
|
15183
|
+
this.lastIndex = memory_index_tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
15219
15184
|
}
|
|
15220
15185
|
}
|
|
15221
15186
|
/** Creates a memory range from given starting point and length */
|
|
@@ -15258,7 +15223,7 @@ class MemoryRange {
|
|
|
15258
15223
|
*
|
|
15259
15224
|
* it should be in `memory-consts` but it cannot be there because of circular dependency
|
|
15260
15225
|
*/
|
|
15261
|
-
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(
|
|
15226
|
+
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(memory_index_tryAsMemoryIndex(0), RESERVED_NUMBER_OF_PAGES * memory_consts_PAGE_SIZE);
|
|
15262
15227
|
|
|
15263
15228
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/page-range.ts
|
|
15264
15229
|
|
|
@@ -15296,7 +15261,7 @@ class PageRange {
|
|
|
15296
15261
|
// lastIndex is not null because we just ensured that the range is not empty
|
|
15297
15262
|
const pageWithLastIndex = getPageNumber(range.lastIndex ?? range.end);
|
|
15298
15263
|
const endPage = getNextPageNumber(pageWithLastIndex);
|
|
15299
|
-
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length >
|
|
15264
|
+
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length > memory_consts_PAGE_SIZE) {
|
|
15300
15265
|
// full range
|
|
15301
15266
|
return new PageRange(startPage, MAX_NUMBER_OF_PAGES);
|
|
15302
15267
|
}
|
|
@@ -15360,8 +15325,8 @@ class ReadablePage extends MemoryPage {
|
|
|
15360
15325
|
}
|
|
15361
15326
|
loadInto(result, startIndex, length) {
|
|
15362
15327
|
const endIndex = startIndex + length;
|
|
15363
|
-
if (endIndex >
|
|
15364
|
-
return Result.error(PageFault.fromMemoryIndex(this.start +
|
|
15328
|
+
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
15329
|
+
return Result.error(PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
15365
15330
|
}
|
|
15366
15331
|
const bytes = this.data.subarray(startIndex, endIndex);
|
|
15367
15332
|
// we zero the bytes, since data might not yet be initialized at `endIndex`.
|
|
@@ -15394,8 +15359,8 @@ class WriteablePage extends MemoryPage {
|
|
|
15394
15359
|
constructor(pageNumber, initialData) {
|
|
15395
15360
|
super(pageNumber);
|
|
15396
15361
|
const dataLength = initialData?.length ?? 0;
|
|
15397
|
-
const initialPageLength = Math.min(
|
|
15398
|
-
this.buffer = new ArrayBuffer(initialPageLength, { maxByteLength:
|
|
15362
|
+
const initialPageLength = Math.min(memory_consts_PAGE_SIZE, Math.max(dataLength, MIN_ALLOCATION_LENGTH));
|
|
15363
|
+
this.buffer = new ArrayBuffer(initialPageLength, { maxByteLength: memory_consts_PAGE_SIZE });
|
|
15399
15364
|
this.view = new Uint8Array(this.buffer);
|
|
15400
15365
|
if (initialData !== undefined) {
|
|
15401
15366
|
this.view.set(initialData);
|
|
@@ -15403,8 +15368,8 @@ class WriteablePage extends MemoryPage {
|
|
|
15403
15368
|
}
|
|
15404
15369
|
loadInto(result, startIndex, length) {
|
|
15405
15370
|
const endIndex = startIndex + length;
|
|
15406
|
-
if (endIndex >
|
|
15407
|
-
return Result.error(PageFault.fromMemoryIndex(this.start +
|
|
15371
|
+
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
15372
|
+
return Result.error(PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
15408
15373
|
}
|
|
15409
15374
|
const bytes = this.view.subarray(startIndex, endIndex);
|
|
15410
15375
|
// we zero the bytes, since the view might not yet be initialized at `endIndex`.
|
|
@@ -15413,16 +15378,16 @@ class WriteablePage extends MemoryPage {
|
|
|
15413
15378
|
return Result.ok(OK);
|
|
15414
15379
|
}
|
|
15415
15380
|
storeFrom(startIndex, bytes) {
|
|
15416
|
-
if (this.buffer.byteLength < startIndex + bytes.length && this.buffer.byteLength <
|
|
15417
|
-
const newLength = Math.min(
|
|
15381
|
+
if (this.buffer.byteLength < startIndex + bytes.length && this.buffer.byteLength < memory_consts_PAGE_SIZE) {
|
|
15382
|
+
const newLength = Math.min(memory_consts_PAGE_SIZE, Math.max(MIN_ALLOCATION_LENGTH, startIndex + bytes.length));
|
|
15418
15383
|
this.buffer.resize(newLength);
|
|
15419
15384
|
}
|
|
15420
15385
|
this.view.set(bytes, startIndex);
|
|
15421
15386
|
return Result.ok(OK);
|
|
15422
15387
|
}
|
|
15423
15388
|
setData(pageIndex, data) {
|
|
15424
|
-
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength <
|
|
15425
|
-
const newLength = Math.min(
|
|
15389
|
+
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength < memory_consts_PAGE_SIZE) {
|
|
15390
|
+
const newLength = Math.min(memory_consts_PAGE_SIZE, Math.max(MIN_ALLOCATION_LENGTH, pageIndex + data.length));
|
|
15426
15391
|
this.buffer.resize(newLength);
|
|
15427
15392
|
}
|
|
15428
15393
|
this.view.set(data, pageIndex);
|
|
@@ -15473,10 +15438,10 @@ class Memory {
|
|
|
15473
15438
|
this.memory = memory;
|
|
15474
15439
|
}
|
|
15475
15440
|
store(address, bytes) {
|
|
15476
|
-
return this.storeFrom(
|
|
15441
|
+
return this.storeFrom(memory_index_tryAsMemoryIndex(address), bytes);
|
|
15477
15442
|
}
|
|
15478
15443
|
read(address, output) {
|
|
15479
|
-
return this.loadInto(output,
|
|
15444
|
+
return this.loadInto(output, memory_index_tryAsMemoryIndex(address));
|
|
15480
15445
|
}
|
|
15481
15446
|
reset() {
|
|
15482
15447
|
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
@@ -15503,8 +15468,8 @@ class Memory {
|
|
|
15503
15468
|
let currentPosition = address;
|
|
15504
15469
|
let bytesLeft = bytes.length;
|
|
15505
15470
|
for (const page of pages) {
|
|
15506
|
-
const pageStartIndex = tryAsPageIndex(currentPosition %
|
|
15507
|
-
const bytesToWrite = Math.min(
|
|
15471
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % memory_consts_PAGE_SIZE);
|
|
15472
|
+
const bytesToWrite = Math.min(memory_consts_PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15508
15473
|
const sourceStartIndex = currentPosition - address;
|
|
15509
15474
|
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
15510
15475
|
page.storeFrom(pageStartIndex, source);
|
|
@@ -15553,8 +15518,8 @@ class Memory {
|
|
|
15553
15518
|
let currentPosition = startAddress;
|
|
15554
15519
|
let bytesLeft = result.length;
|
|
15555
15520
|
for (const page of pages) {
|
|
15556
|
-
const pageStartIndex = tryAsPageIndex(currentPosition %
|
|
15557
|
-
const bytesToRead = Math.min(
|
|
15521
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % memory_consts_PAGE_SIZE);
|
|
15522
|
+
const bytesToRead = Math.min(memory_consts_PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15558
15523
|
const destinationStartIndex = currentPosition - startAddress;
|
|
15559
15524
|
const destination = result.subarray(destinationStartIndex);
|
|
15560
15525
|
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
@@ -15581,7 +15546,7 @@ class Memory {
|
|
|
15581
15546
|
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize(newVirtualSbrkIndex));
|
|
15582
15547
|
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
15583
15548
|
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15584
|
-
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) /
|
|
15549
|
+
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / memory_consts_PAGE_SIZE;
|
|
15585
15550
|
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
15586
15551
|
for (const pageNumber of rangeToAllocate) {
|
|
15587
15552
|
const page = new WriteablePage(pageNumber);
|
|
@@ -15636,8 +15601,8 @@ class MemoryBuilder {
|
|
|
15636
15601
|
setReadablePages(start, end, data = new Uint8Array()) {
|
|
15637
15602
|
this.ensureNotFinalized();
|
|
15638
15603
|
debug_check `${start < end} end has to be bigger than start`;
|
|
15639
|
-
debug_check `${start %
|
|
15640
|
-
debug_check `${end %
|
|
15604
|
+
debug_check `${start % memory_consts_PAGE_SIZE === 0} start needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15605
|
+
debug_check `${end % memory_consts_PAGE_SIZE === 0} end needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15641
15606
|
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15642
15607
|
const length = end - start;
|
|
15643
15608
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15646,7 +15611,7 @@ class MemoryBuilder {
|
|
|
15646
15611
|
const noOfPages = pages.length;
|
|
15647
15612
|
for (let i = 0; i < noOfPages; i++) {
|
|
15648
15613
|
const pageNumber = pages[i];
|
|
15649
|
-
const dataChunk = data.subarray(i *
|
|
15614
|
+
const dataChunk = data.subarray(i * memory_consts_PAGE_SIZE, (i + 1) * memory_consts_PAGE_SIZE);
|
|
15650
15615
|
const page = new ReadablePage(pageNumber, dataChunk);
|
|
15651
15616
|
this.initialMemory.set(pageNumber, page);
|
|
15652
15617
|
}
|
|
@@ -15664,8 +15629,8 @@ class MemoryBuilder {
|
|
|
15664
15629
|
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
15665
15630
|
this.ensureNotFinalized();
|
|
15666
15631
|
debug_check `${start < end} end has to be bigger than start`;
|
|
15667
|
-
debug_check `${start %
|
|
15668
|
-
debug_check `${end %
|
|
15632
|
+
debug_check `${start % memory_consts_PAGE_SIZE === 0} start needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15633
|
+
debug_check `${end % memory_consts_PAGE_SIZE === 0} end needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15669
15634
|
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15670
15635
|
const length = end - start;
|
|
15671
15636
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15674,7 +15639,7 @@ class MemoryBuilder {
|
|
|
15674
15639
|
const noOfPages = pages.length;
|
|
15675
15640
|
for (let i = 0; i < noOfPages; i++) {
|
|
15676
15641
|
const pageNumber = pages[i];
|
|
15677
|
-
const dataChunk = data.subarray(i *
|
|
15642
|
+
const dataChunk = data.subarray(i * memory_consts_PAGE_SIZE, (i + 1) * memory_consts_PAGE_SIZE);
|
|
15678
15643
|
const page = new WriteablePage(pageNumber, dataChunk);
|
|
15679
15644
|
this.initialMemory.set(pageNumber, page);
|
|
15680
15645
|
}
|
|
@@ -15686,8 +15651,8 @@ class MemoryBuilder {
|
|
|
15686
15651
|
*/
|
|
15687
15652
|
setData(start, data) {
|
|
15688
15653
|
this.ensureNotFinalized();
|
|
15689
|
-
const pageOffset = start %
|
|
15690
|
-
const remainingSpaceOnPage =
|
|
15654
|
+
const pageOffset = start % memory_consts_PAGE_SIZE;
|
|
15655
|
+
const remainingSpaceOnPage = memory_consts_PAGE_SIZE - pageOffset;
|
|
15691
15656
|
debug_check `${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15692
15657
|
const length = data.length;
|
|
15693
15658
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15878,27 +15843,27 @@ class Program {
|
|
|
15878
15843
|
static fromSpi(blob, args, hasMetadata) {
|
|
15879
15844
|
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15880
15845
|
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
15881
|
-
const regs = new
|
|
15846
|
+
const regs = new registers_Registers();
|
|
15882
15847
|
regs.copyFrom(registers);
|
|
15883
15848
|
const memoryBuilder = new MemoryBuilder();
|
|
15884
15849
|
for (const { start, end, data } of rawMemory.readable) {
|
|
15885
|
-
const startIndex =
|
|
15886
|
-
const endIndex =
|
|
15850
|
+
const startIndex = memory_index_tryAsMemoryIndex(start);
|
|
15851
|
+
const endIndex = memory_index_tryAsMemoryIndex(end);
|
|
15887
15852
|
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15888
15853
|
}
|
|
15889
15854
|
for (const { start, end, data } of rawMemory.writeable) {
|
|
15890
|
-
const startIndex =
|
|
15891
|
-
const endIndex =
|
|
15855
|
+
const startIndex = memory_index_tryAsMemoryIndex(start);
|
|
15856
|
+
const endIndex = memory_index_tryAsMemoryIndex(end);
|
|
15892
15857
|
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15893
15858
|
}
|
|
15894
|
-
const heapStart =
|
|
15859
|
+
const heapStart = memory_index_tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
15895
15860
|
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
15896
15861
|
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
15897
15862
|
return new Program(code, regs, memory, metadata);
|
|
15898
15863
|
}
|
|
15899
15864
|
static fromGeneric(blob, hasMetadata) {
|
|
15900
15865
|
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15901
|
-
const regs = new
|
|
15866
|
+
const regs = new registers_Registers();
|
|
15902
15867
|
const memory = new Memory();
|
|
15903
15868
|
return new Program(code, regs, memory, metadata);
|
|
15904
15869
|
}
|
|
@@ -16913,6 +16878,45 @@ class BasicBlocks {
|
|
|
16913
16878
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/basic-blocks/index.ts
|
|
16914
16879
|
|
|
16915
16880
|
|
|
16881
|
+
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/gas.ts
|
|
16882
|
+
|
|
16883
|
+
|
|
16884
|
+
/** Create a new gas counter instance depending on the gas value. */
|
|
16885
|
+
function gasCounter(gas) {
|
|
16886
|
+
return new GasCounterU64(numbers_tryAsU64(gas));
|
|
16887
|
+
}
|
|
16888
|
+
class GasCounterU64 {
|
|
16889
|
+
gas;
|
|
16890
|
+
initialGas;
|
|
16891
|
+
constructor(gas) {
|
|
16892
|
+
this.gas = gas;
|
|
16893
|
+
this.initialGas = gas_tryAsGas(gas);
|
|
16894
|
+
}
|
|
16895
|
+
set(g) {
|
|
16896
|
+
this.gas = numbers_tryAsU64(g);
|
|
16897
|
+
}
|
|
16898
|
+
get() {
|
|
16899
|
+
return gas_tryAsGas(this.gas);
|
|
16900
|
+
}
|
|
16901
|
+
sub(g) {
|
|
16902
|
+
const result = this.gas - numbers_tryAsU64(g);
|
|
16903
|
+
if (result >= 0n) {
|
|
16904
|
+
this.gas = numbers_tryAsU64(result);
|
|
16905
|
+
return false;
|
|
16906
|
+
}
|
|
16907
|
+
this.gas = numbers_tryAsU64(0n);
|
|
16908
|
+
return true;
|
|
16909
|
+
}
|
|
16910
|
+
used() {
|
|
16911
|
+
const gasConsumed = numbers_tryAsU64(this.initialGas) - this.gas;
|
|
16912
|
+
// In we have less than zero left we assume that all gas has been consumed.
|
|
16913
|
+
if (gasConsumed < 0) {
|
|
16914
|
+
return this.initialGas;
|
|
16915
|
+
}
|
|
16916
|
+
return gas_tryAsGas(gasConsumed);
|
|
16917
|
+
}
|
|
16918
|
+
}
|
|
16919
|
+
|
|
16916
16920
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/instruction-gas-map.ts
|
|
16917
16921
|
|
|
16918
16922
|
|
|
@@ -17489,7 +17493,7 @@ class LoadOps {
|
|
|
17489
17493
|
}
|
|
17490
17494
|
loadNumber(address, registerIndex, numberLength) {
|
|
17491
17495
|
const registerBytes = this.regs.getBytesAsLittleEndian(registerIndex, REG_SIZE_BYTES);
|
|
17492
|
-
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength),
|
|
17496
|
+
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength), memory_index_tryAsMemoryIndex(address));
|
|
17493
17497
|
if (loadResult.isError) {
|
|
17494
17498
|
if (loadResult.error.isAccessFault) {
|
|
17495
17499
|
this.instructionResult.status = result_Result.FAULT_ACCESS;
|
|
@@ -17505,7 +17509,7 @@ class LoadOps {
|
|
|
17505
17509
|
loadSignedNumber(address, registerIndex, numberLength) {
|
|
17506
17510
|
// load all bytes from register to correctly handle the sign.
|
|
17507
17511
|
const registerBytes = this.regs.getBytesAsLittleEndian(registerIndex, REG_SIZE_BYTES);
|
|
17508
|
-
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength),
|
|
17512
|
+
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength), memory_index_tryAsMemoryIndex(address));
|
|
17509
17513
|
if (loadResult.isError) {
|
|
17510
17514
|
if (loadResult.error.isAccessFault) {
|
|
17511
17515
|
this.instructionResult.status = result_Result.FAULT_ACCESS;
|
|
@@ -17927,7 +17931,7 @@ class StoreOps {
|
|
|
17927
17931
|
this.store(address, secondImmediateDecoder.getExtendedBytesAsLittleEndian());
|
|
17928
17932
|
}
|
|
17929
17933
|
store(address, bytes) {
|
|
17930
|
-
const storeResult = this.memory.storeFrom(
|
|
17934
|
+
const storeResult = this.memory.storeFrom(memory_index_tryAsMemoryIndex(address), bytes);
|
|
17931
17935
|
if (storeResult.isOk) {
|
|
17932
17936
|
return;
|
|
17933
17937
|
}
|
|
@@ -17936,7 +17940,7 @@ class StoreOps {
|
|
|
17936
17940
|
}
|
|
17937
17941
|
else {
|
|
17938
17942
|
this.instructionResult.status = result_Result.FAULT;
|
|
17939
|
-
this.instructionResult.exitParam = getStartPageIndex(
|
|
17943
|
+
this.instructionResult.exitParam = getStartPageIndex(memory_index_tryAsMemoryIndex(storeResult.error.address));
|
|
17940
17944
|
}
|
|
17941
17945
|
}
|
|
17942
17946
|
}
|
|
@@ -18735,11 +18739,11 @@ class ProgramDecoder {
|
|
|
18735
18739
|
|
|
18736
18740
|
|
|
18737
18741
|
const interpreter_logger = Logger.new(import.meta.filename, "pvm");
|
|
18738
|
-
class
|
|
18742
|
+
class interpreter_Interpreter {
|
|
18739
18743
|
useSbrkGas;
|
|
18740
|
-
registers = new
|
|
18744
|
+
registers = new registers_Registers();
|
|
18741
18745
|
memory = new Memory();
|
|
18742
|
-
gas = gasCounter(
|
|
18746
|
+
gas = gasCounter(gas_tryAsGas(0));
|
|
18743
18747
|
code = new Uint8Array();
|
|
18744
18748
|
mask = Mask.empty();
|
|
18745
18749
|
pc = 0;
|
|
@@ -18873,8 +18877,8 @@ class Interpreter {
|
|
|
18873
18877
|
break;
|
|
18874
18878
|
case ArgumentType.TWO_REGISTERS:
|
|
18875
18879
|
if (this.useSbrkGas && currentInstruction === Instruction.SBRK) {
|
|
18876
|
-
const calculateSbrkCost = (length) => (alignToPageSize(length) /
|
|
18877
|
-
const underflow = this.gas.sub(
|
|
18880
|
+
const calculateSbrkCost = (length) => (alignToPageSize(length) / memory_consts_PAGE_SIZE) * 16;
|
|
18881
|
+
const underflow = this.gas.sub(gas_tryAsGas(calculateSbrkCost(this.registers.getLowerU32(argsResult.firstRegisterIndex))));
|
|
18878
18882
|
if (underflow) {
|
|
18879
18883
|
this.status = status_Status.OOG;
|
|
18880
18884
|
return this.status;
|
|
@@ -18969,12 +18973,88 @@ class Interpreter {
|
|
|
18969
18973
|
}
|
|
18970
18974
|
}
|
|
18971
18975
|
|
|
18976
|
+
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/debugger-adapter.ts
|
|
18977
|
+
|
|
18978
|
+
|
|
18979
|
+
|
|
18980
|
+
|
|
18981
|
+
|
|
18982
|
+
|
|
18983
|
+
class DebuggerAdapter {
|
|
18984
|
+
pvm;
|
|
18985
|
+
constructor(useSbrkGas = false) {
|
|
18986
|
+
this.pvm = new Interpreter({ useSbrkGas });
|
|
18987
|
+
}
|
|
18988
|
+
resetGeneric(rawProgram, flatRegisters, initialGas) {
|
|
18989
|
+
this.pvm.resetGeneric(rawProgram, 0, tryAsGas(initialGas), new Registers(flatRegisters));
|
|
18990
|
+
}
|
|
18991
|
+
reset(rawProgram, pc, gas, maybeRegisters, maybeMemory) {
|
|
18992
|
+
this.pvm.resetGeneric(rawProgram, pc, tryAsGas(gas), maybeRegisters, maybeMemory);
|
|
18993
|
+
}
|
|
18994
|
+
getPageDump(pageNumber) {
|
|
18995
|
+
const page = this.pvm.getMemoryPage(pageNumber);
|
|
18996
|
+
if (page === null) {
|
|
18997
|
+
// page wasn't allocated so we return an empty page
|
|
18998
|
+
return safeAllocUint8Array(PAGE_SIZE);
|
|
18999
|
+
}
|
|
19000
|
+
if (page.length === PAGE_SIZE) {
|
|
19001
|
+
// page was allocated and has a proper size so we can simply return it
|
|
19002
|
+
return page;
|
|
19003
|
+
}
|
|
19004
|
+
// page was allocated but it is shorter than PAGE_SIZE so we have to extend it
|
|
19005
|
+
const fullPage = safeAllocUint8Array(PAGE_SIZE);
|
|
19006
|
+
fullPage.set(page);
|
|
19007
|
+
return fullPage;
|
|
19008
|
+
}
|
|
19009
|
+
setMemory(address, value) {
|
|
19010
|
+
this.pvm.memory.storeFrom(tryAsMemoryIndex(address), value);
|
|
19011
|
+
}
|
|
19012
|
+
getExitArg() {
|
|
19013
|
+
return this.pvm.getExitParam() ?? 0;
|
|
19014
|
+
}
|
|
19015
|
+
getStatus() {
|
|
19016
|
+
return this.pvm.getStatus();
|
|
19017
|
+
}
|
|
19018
|
+
nextStep() {
|
|
19019
|
+
return this.pvm.nextStep() === Status.OK;
|
|
19020
|
+
}
|
|
19021
|
+
nSteps(steps) {
|
|
19022
|
+
check `${steps >>> 0 > 0} Expected a positive integer got ${steps}`;
|
|
19023
|
+
for (let i = 0; i < steps; i++) {
|
|
19024
|
+
const isOk = this.nextStep();
|
|
19025
|
+
if (!isOk) {
|
|
19026
|
+
return false;
|
|
19027
|
+
}
|
|
19028
|
+
}
|
|
19029
|
+
return true;
|
|
19030
|
+
}
|
|
19031
|
+
getRegisters() {
|
|
19032
|
+
return this.pvm.registers.getAllU64();
|
|
19033
|
+
}
|
|
19034
|
+
setRegisters(registers) {
|
|
19035
|
+
this.pvm.registers.copyFrom(new Registers(registers));
|
|
19036
|
+
}
|
|
19037
|
+
getProgramCounter() {
|
|
19038
|
+
return this.pvm.getPC();
|
|
19039
|
+
}
|
|
19040
|
+
setNextProgramCounter(nextPc) {
|
|
19041
|
+
this.pvm.setNextPC(nextPc);
|
|
19042
|
+
}
|
|
19043
|
+
getGasLeft() {
|
|
19044
|
+
return BigInt(this.pvm.gas.get());
|
|
19045
|
+
}
|
|
19046
|
+
setGasLeft(gas) {
|
|
19047
|
+
this.pvm.gas.set(tryAsGas(gas));
|
|
19048
|
+
}
|
|
19049
|
+
}
|
|
19050
|
+
|
|
18972
19051
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/index.ts
|
|
18973
19052
|
|
|
18974
19053
|
|
|
18975
19054
|
|
|
18976
19055
|
|
|
18977
19056
|
|
|
19057
|
+
|
|
18978
19058
|
;// CONCATENATED MODULE: ./node_modules/@fluffylabs/anan-as/build/debug-raw.js
|
|
18979
19059
|
async function instantiate(module, imports = {}) {
|
|
18980
19060
|
const adaptedImports = {
|
|
@@ -19428,12 +19508,12 @@ class AnanasMemory {
|
|
|
19428
19508
|
}
|
|
19429
19509
|
class AnanasGasCounter {
|
|
19430
19510
|
instance;
|
|
19431
|
-
initialGas =
|
|
19511
|
+
initialGas = gas_tryAsGas(0n);
|
|
19432
19512
|
constructor(instance) {
|
|
19433
19513
|
this.instance = instance;
|
|
19434
19514
|
}
|
|
19435
19515
|
get() {
|
|
19436
|
-
return
|
|
19516
|
+
return gas_tryAsGas(this.instance.getGasLeft());
|
|
19437
19517
|
}
|
|
19438
19518
|
set(g) {
|
|
19439
19519
|
this.instance.setGasLeft(BigInt(g));
|
|
@@ -19538,7 +19618,7 @@ class InterpreterInstanceManager {
|
|
|
19538
19618
|
const instances = [];
|
|
19539
19619
|
switch (interpreter) {
|
|
19540
19620
|
case PvmBackend.BuiltIn:
|
|
19541
|
-
instances.push(new
|
|
19621
|
+
instances.push(new interpreter_Interpreter({
|
|
19542
19622
|
useSbrkGas: false,
|
|
19543
19623
|
}));
|
|
19544
19624
|
break;
|
|
@@ -21994,7 +22074,7 @@ class Transfer {
|
|
|
21994
22074
|
*/
|
|
21995
22075
|
basicGasCost = compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2)
|
|
21996
22076
|
? gas_tryAsSmallGas(10)
|
|
21997
|
-
: (regs) =>
|
|
22077
|
+
: (regs) => gas_tryAsGas(10n + regs.get(TRANSFER_GAS_FEE_REG));
|
|
21998
22078
|
tracedRegisters = traceRegisters(transfer_IN_OUT_REG, AMOUNT_REG, TRANSFER_GAS_FEE_REG, MEMO_START_REG);
|
|
21999
22079
|
constructor(currentServiceId, partialState) {
|
|
22000
22080
|
this.currentServiceId = currentServiceId;
|
|
@@ -22022,7 +22102,7 @@ class Transfer {
|
|
|
22022
22102
|
if (transferResult.isOk) {
|
|
22023
22103
|
if (compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2)) {
|
|
22024
22104
|
// substracting value `t`
|
|
22025
|
-
const underflow = gas.sub(
|
|
22105
|
+
const underflow = gas.sub(gas_tryAsGas(transferGasFee));
|
|
22026
22106
|
if (underflow) {
|
|
22027
22107
|
return PvmExecution.OOG;
|
|
22028
22108
|
}
|
|
@@ -22767,7 +22847,7 @@ class Accumulate {
|
|
|
22767
22847
|
serviceId,
|
|
22768
22848
|
argsLength: numbers_tryAsU32(transfers.length + operands.length),
|
|
22769
22849
|
});
|
|
22770
|
-
const result = await executor.run(invocationArgs,
|
|
22850
|
+
const result = await executor.run(invocationArgs, gas_tryAsGas(gas));
|
|
22771
22851
|
const [newState, checkpoint] = partialState.getStateUpdates();
|
|
22772
22852
|
/**
|
|
22773
22853
|
* PVM invocation returned and error so we return the checkpoint
|
|
@@ -23171,7 +23251,7 @@ class DeferredTransfers {
|
|
|
23171
23251
|
partiallyUpdatedState.updateServiceInfo(serviceId, newInfo);
|
|
23172
23252
|
const partialState = new AccumulateExternalities(this.chainSpec, this.blake2b, partiallyUpdatedState, serviceId, serviceId, timeslot);
|
|
23173
23253
|
const fetchExternalities = FetchExternalities.createForOnTransfer({ entropy, transfers }, this.chainSpec);
|
|
23174
|
-
let consumedGas =
|
|
23254
|
+
let consumedGas = gas_tryAsGas(0);
|
|
23175
23255
|
const hasTransfers = transfers.length > 0;
|
|
23176
23256
|
const isCodeCorrect = code !== null && code.length <= W_C;
|
|
23177
23257
|
if (!hasTransfers || !isCodeCorrect) {
|
|
@@ -23189,7 +23269,7 @@ class DeferredTransfers {
|
|
|
23189
23269
|
const executor = await PvmExecutor.createOnTransferExecutor(serviceId, code, { partialState, fetchExternalities }, this.pvm);
|
|
23190
23270
|
const args = encoder_Encoder.encodeObject(deferred_transfers_ARGS_CODEC, { timeslot, serviceId, transfersLength: numbers_tryAsU32(transfers.length) }, this.chainSpec);
|
|
23191
23271
|
const gas = transfers.reduce((acc, item) => acc + item.gas, 0n);
|
|
23192
|
-
consumedGas = (await executor.run(args,
|
|
23272
|
+
consumedGas = (await executor.run(args, gas_tryAsGas(gas))).consumedGas;
|
|
23193
23273
|
}
|
|
23194
23274
|
transferStatistics.set(serviceId, { count: numbers_tryAsU32(transfers.length), gasUsed: tryAsServiceGas(consumedGas) });
|
|
23195
23275
|
const [updatedState] = partialState.getStateUpdates();
|