@onda-lang/wasm-compiler 0.7.4 → 0.8.0
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/README.md +47 -0
- package/api.md +407 -0
- package/dist/backend/constants.js +1 -1
- package/dist/backend/index.js +991 -31
- package/dist/build.json +3 -3
- package/dist/frontend/README.md +8 -5
- package/dist/frontend/onda_compiler_web.d.ts +21 -12
- package/dist/frontend/onda_compiler_web.js +118 -10
- package/dist/frontend/onda_compiler_web_bg.wasm +0 -0
- package/dist/frontend/onda_compiler_web_bg.wasm.d.ts +10 -7
- package/dist/frontend/package.json +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -5
- package/src/index.d.ts +61 -1
- package/src/index.js +307 -24
- package/src/worker.js +31 -0
package/dist/backend/index.js
CHANGED
|
@@ -42,7 +42,23 @@ const MAX_MEMORY_PAGES = 65_536;
|
|
|
42
42
|
const WASM32_ADDRESS_SPACE_BYTES = MAX_MEMORY_PAGES * PAGE_BYTES;
|
|
43
43
|
const DEFAULT_OPTIMIZE_LEVEL = 4;
|
|
44
44
|
const ONDA_PROCESS_FULL_BLOCK = (1 << 0) | (1 << 1);
|
|
45
|
+
const DELEGATE_RECORD_HEADER_SIZE = 12;
|
|
46
|
+
const DELEGATE_BATCH_STORAGE_OFFSET = 0;
|
|
47
|
+
const DELEGATE_BATCH_CAPACITY_OFFSET = 4;
|
|
48
|
+
const DELEGATE_BATCH_USED_OFFSET = 8;
|
|
49
|
+
const DELEGATE_BATCH_RECORD_COUNT_OFFSET = 12;
|
|
50
|
+
const DELEGATE_BATCH_OVERFLOW_OFFSET = 16;
|
|
51
|
+
const PRINT_RECORD_HEADER_SIZE = 12;
|
|
52
|
+
const PRINT_BATCH_STORAGE_OFFSET = 0;
|
|
53
|
+
const PRINT_BATCH_CAPACITY_OFFSET = 4;
|
|
54
|
+
const PRINT_BATCH_USED_OFFSET = 8;
|
|
55
|
+
const PRINT_BATCH_RECORD_COUNT_OFFSET = 12;
|
|
56
|
+
const PRINT_BATCH_OVERFLOW_OFFSET = 16;
|
|
57
|
+
const EXECUTION_OUTPUT_DELEGATE_BATCH_OFFSET = 0;
|
|
58
|
+
const EXECUTION_OUTPUT_PRINT_BATCH_OFFSET = 4;
|
|
59
|
+
const EXECUTION_OUTPUT_SEQUENCE_OFFSET = 8;
|
|
45
60
|
const RUNTIME_FAILURE_GLOBAL = "$onda.runtime_failure";
|
|
61
|
+
const INIT_ALL_GLOBAL = "$onda.init_all";
|
|
46
62
|
const MATH_KERNEL_INTRINSICS = new Set([
|
|
47
63
|
"sin",
|
|
48
64
|
"cos",
|
|
@@ -63,6 +79,9 @@ const POINTER_GLOBALS = Object.freeze({
|
|
|
63
79
|
params: "$onda.params",
|
|
64
80
|
state: "$onda.state",
|
|
65
81
|
eventPayload: "$onda.event_payload",
|
|
82
|
+
delegateBatch: "$onda.delegate_batch",
|
|
83
|
+
printBatch: "$onda.print_batch",
|
|
84
|
+
outputSequence: "$onda.output_sequence",
|
|
66
85
|
buffers: "$onda.buffers",
|
|
67
86
|
bufferWrites: "$onda.buffer_writes",
|
|
68
87
|
bufferFrames: "$onda.buffer_frames",
|
|
@@ -819,6 +838,7 @@ class MirCompiler {
|
|
|
819
838
|
"params",
|
|
820
839
|
"buffers",
|
|
821
840
|
"events",
|
|
841
|
+
"delegates",
|
|
822
842
|
]) {
|
|
823
843
|
if (!Array.isArray(mir.interface[field])) {
|
|
824
844
|
this.fail(`MIR interface field '${field}' must be an array`);
|
|
@@ -983,6 +1003,12 @@ class MirCompiler {
|
|
|
983
1003
|
"control_mirror",
|
|
984
1004
|
]);
|
|
985
1005
|
for (const [stateId, slot] of this.mir.state.entries()) {
|
|
1006
|
+
if (typeof slot?.authored !== "boolean") {
|
|
1007
|
+
this.fail(`state slot ${stateId} has an invalid authored flag`);
|
|
1008
|
+
}
|
|
1009
|
+
if (slot?.pinned !== undefined && typeof slot.pinned !== "boolean") {
|
|
1010
|
+
this.fail(`state slot ${stateId} has an invalid pinned flag`);
|
|
1011
|
+
}
|
|
986
1012
|
if (!persistenceKinds.has(slot?.persistence)) {
|
|
987
1013
|
this.fail(
|
|
988
1014
|
`state slot ${stateId} has invalid persistence '${String(slot?.persistence)}'`,
|
|
@@ -1022,7 +1048,8 @@ class MirCompiler {
|
|
|
1022
1048
|
if (
|
|
1023
1049
|
!func?.attributes ||
|
|
1024
1050
|
!origins.has(func.attributes.origin) ||
|
|
1025
|
-
!inlineHints.has(func.attributes.inline)
|
|
1051
|
+
!inlineHints.has(func.attributes.inline) ||
|
|
1052
|
+
typeof func.attributes.runtime_context !== "boolean"
|
|
1026
1053
|
) {
|
|
1027
1054
|
this.fail(
|
|
1028
1055
|
`function ${functionId} has invalid schema-${SUPPORTED_MIR_SCHEMA_VERSION} attributes`,
|
|
@@ -1550,10 +1577,15 @@ class MirCompiler {
|
|
|
1550
1577
|
if (value.kind === "call" && Number.isInteger(value.data?.function)) {
|
|
1551
1578
|
callees[functionId].add(value.data.function);
|
|
1552
1579
|
}
|
|
1580
|
+
const fixedDelegatePayloadMayFail = value.kind === "publish_delegate"
|
|
1581
|
+
&& this.mir.interface.delegates[value.data?.delegate]?.params.some(
|
|
1582
|
+
(param) => this.type(param.ty).kind === "array",
|
|
1583
|
+
);
|
|
1553
1584
|
const bounds = value.data?.bounds;
|
|
1554
1585
|
if (
|
|
1555
1586
|
value.kind === "process_frame"
|
|
1556
1587
|
|| value.kind === "slice_copy"
|
|
1588
|
+
|| fixedDelegatePayloadMayFail
|
|
1557
1589
|
|| binaryMayFail(functionId, value)
|
|
1558
1590
|
|| (checkedBoundsKinds.has(value.kind) && bounds === "checked")
|
|
1559
1591
|
|| (dynamicBoundsKinds.has(value.kind) && bounds !== "unchecked")
|
|
@@ -1590,6 +1622,9 @@ class MirCompiler {
|
|
|
1590
1622
|
this.eventLayout = this.mir.interface.events.map((event) =>
|
|
1591
1623
|
this.layoutEventValues(event.params),
|
|
1592
1624
|
);
|
|
1625
|
+
this.delegateLayout = this.mir.interface.delegates.map((delegate) =>
|
|
1626
|
+
this.layoutEventValues(delegate.params),
|
|
1627
|
+
);
|
|
1593
1628
|
this.requireWasm32Extent(
|
|
1594
1629
|
this.stateLayout.byteLength,
|
|
1595
1630
|
"MIR physical state storage",
|
|
@@ -1604,6 +1639,12 @@ class MirCompiler {
|
|
|
1604
1639
|
`MIR event ${eventId} fixed payload storage`,
|
|
1605
1640
|
);
|
|
1606
1641
|
}
|
|
1642
|
+
for (const [delegateId, layout] of this.delegateLayout.entries()) {
|
|
1643
|
+
this.requireWasm32Extent(
|
|
1644
|
+
layout.minimumByteLength,
|
|
1645
|
+
`MIR delegate ${delegateId} fixed payload storage`,
|
|
1646
|
+
);
|
|
1647
|
+
}
|
|
1607
1648
|
|
|
1608
1649
|
for (let id = 0; id < this.mir.const_data.length; id += 1) {
|
|
1609
1650
|
const data = this.mir.const_data[id];
|
|
@@ -1818,6 +1859,12 @@ class MirCompiler {
|
|
|
1818
1859
|
true,
|
|
1819
1860
|
this.module.i32.const(0),
|
|
1820
1861
|
);
|
|
1862
|
+
this.module.addGlobal(
|
|
1863
|
+
INIT_ALL_GLOBAL,
|
|
1864
|
+
binaryen.i32,
|
|
1865
|
+
true,
|
|
1866
|
+
this.module.i32.const(0),
|
|
1867
|
+
);
|
|
1821
1868
|
}
|
|
1822
1869
|
|
|
1823
1870
|
addMathKernel() {
|
|
@@ -2072,7 +2119,7 @@ class MirCompiler {
|
|
|
2072
2119
|
index,
|
|
2073
2120
|
typeId,
|
|
2074
2121
|
kind: "buffer",
|
|
2075
|
-
components: ["i32", "i32", "i32", "i32", "f32"],
|
|
2122
|
+
components: ["i32", "i32", "i32", "i32", "f32", "i32"],
|
|
2076
2123
|
};
|
|
2077
2124
|
}
|
|
2078
2125
|
if (type.kind === "buffer_span") {
|
|
@@ -2084,7 +2131,7 @@ class MirCompiler {
|
|
|
2084
2131
|
index,
|
|
2085
2132
|
typeId,
|
|
2086
2133
|
kind: "buffer_span",
|
|
2087
|
-
components: ["i32", "i32", "i32", "i32", "i32"],
|
|
2134
|
+
components: ["i32", "i32", "i32", "i32", "i32", "i32"],
|
|
2088
2135
|
};
|
|
2089
2136
|
}
|
|
2090
2137
|
if (type.kind === "array") {
|
|
@@ -2113,9 +2160,9 @@ class MirCompiler {
|
|
|
2113
2160
|
}
|
|
2114
2161
|
if (layout.kind === "array") return;
|
|
2115
2162
|
const suffixes = layout.kind === "buffer"
|
|
2116
|
-
? ["read_address", "write_address", "frames", "channels", "sample_rate"]
|
|
2163
|
+
? ["read_address", "write_address", "frames", "channels", "sample_rate", "bound"]
|
|
2117
2164
|
: layout.kind === "buffer_span"
|
|
2118
|
-
? ["read_table", "write_table", "frames_table", "channels_table", "sample_rates_table"]
|
|
2165
|
+
? ["read_table", "write_table", "frames_table", "channels_table", "sample_rates_table", "bound_table"]
|
|
2119
2166
|
: ["read_address", "write_address", "length", "stride"];
|
|
2120
2167
|
for (const [offset, suffix] of suffixes.entries()) {
|
|
2121
2168
|
binaryen.Function.setLocalName(
|
|
@@ -2262,6 +2309,7 @@ class MirCompiler {
|
|
|
2262
2309
|
RUNTIME_FAILURE_GLOBAL,
|
|
2263
2310
|
this.module.i32.const(PROCESSOR_EXECUTION_RUNTIME_SAFETY_FAILURE),
|
|
2264
2311
|
),
|
|
2312
|
+
...this.resetDelegateBatch(),
|
|
2265
2313
|
this.returnFromCurrentFunction(context),
|
|
2266
2314
|
]);
|
|
2267
2315
|
}
|
|
@@ -2295,6 +2343,92 @@ class MirCompiler {
|
|
|
2295
2343
|
: this.module.i32.const(PROCESSOR_EXECUTION_OK);
|
|
2296
2344
|
}
|
|
2297
2345
|
|
|
2346
|
+
resetDelegateBatch() {
|
|
2347
|
+
const batch = () =>
|
|
2348
|
+
this.module.global.get(POINTER_GLOBALS.delegateBatch, binaryen.i32);
|
|
2349
|
+
const stores = [
|
|
2350
|
+
DELEGATE_BATCH_USED_OFFSET,
|
|
2351
|
+
DELEGATE_BATCH_RECORD_COUNT_OFFSET,
|
|
2352
|
+
DELEGATE_BATCH_OVERFLOW_OFFSET,
|
|
2353
|
+
].map((offset) =>
|
|
2354
|
+
this.module.i32.store(
|
|
2355
|
+
offset,
|
|
2356
|
+
4,
|
|
2357
|
+
batch(),
|
|
2358
|
+
this.module.i32.const(0),
|
|
2359
|
+
)
|
|
2360
|
+
);
|
|
2361
|
+
return [
|
|
2362
|
+
this.module.if(
|
|
2363
|
+
this.module.i32.ne(batch(), this.module.i32.const(0)),
|
|
2364
|
+
this.module.block(null, stores),
|
|
2365
|
+
),
|
|
2366
|
+
];
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
executionOutputBatch(outputLocal, fieldOffset) {
|
|
2370
|
+
const output = () => this.module.local.get(outputLocal, binaryen.i32);
|
|
2371
|
+
return this.module.if(
|
|
2372
|
+
this.module.i32.ne(output(), this.module.i32.const(0)),
|
|
2373
|
+
this.module.i32.load(fieldOffset, 4, output()),
|
|
2374
|
+
this.module.i32.const(0),
|
|
2375
|
+
);
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
executionOutputSequence(outputLocal) {
|
|
2379
|
+
const output = () => this.module.local.get(outputLocal, binaryen.i32);
|
|
2380
|
+
return this.module.if(
|
|
2381
|
+
this.module.i32.ne(output(), this.module.i32.const(0)),
|
|
2382
|
+
this.module.i32.add(
|
|
2383
|
+
output(),
|
|
2384
|
+
this.module.i32.const(EXECUTION_OUTPUT_SEQUENCE_OFFSET),
|
|
2385
|
+
),
|
|
2386
|
+
this.module.i32.const(0),
|
|
2387
|
+
);
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
advanceOutputSequence(sequenceLocal) {
|
|
2391
|
+
const pointer = () =>
|
|
2392
|
+
this.module.global.get(POINTER_GLOBALS.outputSequence, binaryen.i32);
|
|
2393
|
+
const sequence = () => this.module.local.get(sequenceLocal, binaryen.i32);
|
|
2394
|
+
return this.module.block(null, [
|
|
2395
|
+
this.module.local.set(
|
|
2396
|
+
sequenceLocal,
|
|
2397
|
+
this.module.i32.load(0, 4, pointer()),
|
|
2398
|
+
),
|
|
2399
|
+
this.module.i32.store(
|
|
2400
|
+
0,
|
|
2401
|
+
4,
|
|
2402
|
+
pointer(),
|
|
2403
|
+
this.module.select(
|
|
2404
|
+
this.module.i32.eq(sequence(), this.module.i32.const(-1)),
|
|
2405
|
+
sequence(),
|
|
2406
|
+
this.module.i32.add(sequence(), this.module.i32.const(1)),
|
|
2407
|
+
),
|
|
2408
|
+
),
|
|
2409
|
+
]);
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
fullInitClearRanges() {
|
|
2413
|
+
const ranges = [];
|
|
2414
|
+
let cursor = 0;
|
|
2415
|
+
for (const [stateId, slot] of this.mir.state.entries()) {
|
|
2416
|
+
if (slot.pinned !== true) continue;
|
|
2417
|
+
const layout = this.stateLayout[stateId];
|
|
2418
|
+
if (cursor < layout.offset) {
|
|
2419
|
+
ranges.push({ offset: cursor, size: layout.offset - cursor });
|
|
2420
|
+
}
|
|
2421
|
+
cursor = layout.offset + layout.size;
|
|
2422
|
+
}
|
|
2423
|
+
if (cursor < this.stateLayout.byteLength) {
|
|
2424
|
+
ranges.push({
|
|
2425
|
+
offset: cursor,
|
|
2426
|
+
size: this.stateLayout.byteLength - cursor,
|
|
2427
|
+
});
|
|
2428
|
+
}
|
|
2429
|
+
return ranges;
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2298
2432
|
addAbiWrappers() {
|
|
2299
2433
|
const initId = this.mir.entry_points.init;
|
|
2300
2434
|
const processId = this.mir.entry_points.process;
|
|
@@ -2307,6 +2441,21 @@ class MirCompiler {
|
|
|
2307
2441
|
binaryen.Features.BulkMemoryOpt |
|
|
2308
2442
|
(this.options.simd ? binaryen.Features.SIMD128 : 0),
|
|
2309
2443
|
);
|
|
2444
|
+
// Pinned declarations fully initialize their own slots on this path.
|
|
2445
|
+
// Clear only the complementary ranges, including layout padding, so large
|
|
2446
|
+
// pinned arrays are never written once here and again by their initializer.
|
|
2447
|
+
const fullInitClears = this.fullInitClearRanges().map(({ offset, size }) =>
|
|
2448
|
+
this.module.memory.fill(
|
|
2449
|
+
offset === 0
|
|
2450
|
+
? this.module.local.get(1, binaryen.i32)
|
|
2451
|
+
: this.module.i32.add(
|
|
2452
|
+
this.module.local.get(1, binaryen.i32),
|
|
2453
|
+
this.module.i32.const(offset),
|
|
2454
|
+
),
|
|
2455
|
+
this.module.i32.const(0),
|
|
2456
|
+
this.module.i32.const(size),
|
|
2457
|
+
)
|
|
2458
|
+
);
|
|
2310
2459
|
const initBody = this.module.block(null, [
|
|
2311
2460
|
...this.resetRuntimeFailure(initId),
|
|
2312
2461
|
this.module.global.set(
|
|
@@ -2317,25 +2466,76 @@ class MirCompiler {
|
|
|
2317
2466
|
POINTER_GLOBALS.state,
|
|
2318
2467
|
this.module.local.get(1, binaryen.i32),
|
|
2319
2468
|
),
|
|
2320
|
-
this.module.
|
|
2321
|
-
|
|
2322
|
-
this.module.
|
|
2323
|
-
this.module.i32.const(this.stateLayout.byteLength ?? 0),
|
|
2469
|
+
this.module.global.set(
|
|
2470
|
+
POINTER_GLOBALS.buffers,
|
|
2471
|
+
this.module.local.get(3, binaryen.i32),
|
|
2324
2472
|
),
|
|
2473
|
+
this.module.global.set(
|
|
2474
|
+
POINTER_GLOBALS.bufferWrites,
|
|
2475
|
+
this.module.local.get(3, binaryen.i32),
|
|
2476
|
+
),
|
|
2477
|
+
this.module.global.set(
|
|
2478
|
+
POINTER_GLOBALS.bufferFrames,
|
|
2479
|
+
this.module.local.get(4, binaryen.i32),
|
|
2480
|
+
),
|
|
2481
|
+
this.module.global.set(
|
|
2482
|
+
POINTER_GLOBALS.bufferChannels,
|
|
2483
|
+
this.module.local.get(5, binaryen.i32),
|
|
2484
|
+
),
|
|
2485
|
+
this.module.global.set(
|
|
2486
|
+
POINTER_GLOBALS.bufferSampleRates,
|
|
2487
|
+
this.module.local.get(6, binaryen.i32),
|
|
2488
|
+
),
|
|
2489
|
+
this.module.global.set(
|
|
2490
|
+
POINTER_GLOBALS.delegateBatch,
|
|
2491
|
+
this.executionOutputBatch(7, EXECUTION_OUTPUT_DELEGATE_BATCH_OFFSET),
|
|
2492
|
+
),
|
|
2493
|
+
this.module.global.set(
|
|
2494
|
+
POINTER_GLOBALS.printBatch,
|
|
2495
|
+
this.executionOutputBatch(7, EXECUTION_OUTPUT_PRINT_BATCH_OFFSET),
|
|
2496
|
+
),
|
|
2497
|
+
this.module.global.set(
|
|
2498
|
+
POINTER_GLOBALS.outputSequence,
|
|
2499
|
+
this.executionOutputSequence(7),
|
|
2500
|
+
),
|
|
2501
|
+
this.module.global.set(
|
|
2502
|
+
INIT_ALL_GLOBAL,
|
|
2503
|
+
this.module.i32.ne(
|
|
2504
|
+
this.module.local.get(2, binaryen.i32),
|
|
2505
|
+
this.module.i32.const(0),
|
|
2506
|
+
),
|
|
2507
|
+
),
|
|
2508
|
+
...(fullInitClears.length === 0
|
|
2509
|
+
? []
|
|
2510
|
+
: [
|
|
2511
|
+
this.module.if(
|
|
2512
|
+
this.module.global.get(INIT_ALL_GLOBAL, binaryen.i32),
|
|
2513
|
+
this.module.block(null, fullInitClears),
|
|
2514
|
+
),
|
|
2515
|
+
]),
|
|
2325
2516
|
this.module.call(this.functionNames[initId], [], binaryen.none),
|
|
2326
2517
|
this.executionStatus(initId),
|
|
2327
2518
|
], binaryen.i32);
|
|
2328
2519
|
this.module.addFunction(
|
|
2329
2520
|
"$onda.abi.init",
|
|
2330
|
-
binaryen.createType([
|
|
2521
|
+
binaryen.createType([
|
|
2522
|
+
binaryen.i32,
|
|
2523
|
+
binaryen.i32,
|
|
2524
|
+
binaryen.i32,
|
|
2525
|
+
binaryen.i32,
|
|
2526
|
+
binaryen.i32,
|
|
2527
|
+
binaryen.i32,
|
|
2528
|
+
binaryen.i32,
|
|
2529
|
+
binaryen.i32,
|
|
2530
|
+
]),
|
|
2331
2531
|
binaryen.i32,
|
|
2332
2532
|
[],
|
|
2333
2533
|
initBody,
|
|
2334
2534
|
);
|
|
2335
|
-
this.module.addFunctionExport("$onda.abi.init", "
|
|
2535
|
+
this.module.addFunctionExport("$onda.abi.init", "onda_processor_init");
|
|
2336
2536
|
|
|
2337
2537
|
const processParams = binaryen.createType(
|
|
2338
|
-
Array.from({ length:
|
|
2538
|
+
Array.from({ length: 12 }, () => binaryen.i32),
|
|
2339
2539
|
);
|
|
2340
2540
|
const startFrame = () => this.module.local.get(4, binaryen.i32);
|
|
2341
2541
|
const frames = () => this.module.local.get(5, binaryen.i32);
|
|
@@ -2369,6 +2569,18 @@ class MirCompiler {
|
|
|
2369
2569
|
),
|
|
2370
2570
|
);
|
|
2371
2571
|
const processBody = this.module.block(null, [
|
|
2572
|
+
this.module.global.set(
|
|
2573
|
+
POINTER_GLOBALS.delegateBatch,
|
|
2574
|
+
this.executionOutputBatch(11, EXECUTION_OUTPUT_DELEGATE_BATCH_OFFSET),
|
|
2575
|
+
),
|
|
2576
|
+
this.module.global.set(
|
|
2577
|
+
POINTER_GLOBALS.printBatch,
|
|
2578
|
+
this.executionOutputBatch(11, EXECUTION_OUTPUT_PRINT_BATCH_OFFSET),
|
|
2579
|
+
),
|
|
2580
|
+
this.module.global.set(
|
|
2581
|
+
POINTER_GLOBALS.outputSequence,
|
|
2582
|
+
this.executionOutputSequence(11),
|
|
2583
|
+
),
|
|
2372
2584
|
this.module.if(
|
|
2373
2585
|
invalidRange,
|
|
2374
2586
|
this.module.return(
|
|
@@ -2441,6 +2653,18 @@ class MirCompiler {
|
|
|
2441
2653
|
}
|
|
2442
2654
|
const wrapperName = `$onda.abi.event.${eventId}`;
|
|
2443
2655
|
const body = this.module.block(null, [
|
|
2656
|
+
this.module.global.set(
|
|
2657
|
+
POINTER_GLOBALS.delegateBatch,
|
|
2658
|
+
this.executionOutputBatch(7, EXECUTION_OUTPUT_DELEGATE_BATCH_OFFSET),
|
|
2659
|
+
),
|
|
2660
|
+
this.module.global.set(
|
|
2661
|
+
POINTER_GLOBALS.printBatch,
|
|
2662
|
+
this.executionOutputBatch(7, EXECUTION_OUTPUT_PRINT_BATCH_OFFSET),
|
|
2663
|
+
),
|
|
2664
|
+
this.module.global.set(
|
|
2665
|
+
POINTER_GLOBALS.outputSequence,
|
|
2666
|
+
this.executionOutputSequence(7),
|
|
2667
|
+
),
|
|
2444
2668
|
...this.resetRuntimeFailure(event.handler),
|
|
2445
2669
|
this.module.global.set(
|
|
2446
2670
|
POINTER_GLOBALS.eventPayload,
|
|
@@ -2479,7 +2703,7 @@ class MirCompiler {
|
|
|
2479
2703
|
], binaryen.i32);
|
|
2480
2704
|
this.module.addFunction(
|
|
2481
2705
|
wrapperName,
|
|
2482
|
-
binaryen.createType(Array.from({ length:
|
|
2706
|
+
binaryen.createType(Array.from({ length: 8 }, () => binaryen.i32)),
|
|
2483
2707
|
binaryen.i32,
|
|
2484
2708
|
[],
|
|
2485
2709
|
body,
|
|
@@ -2527,6 +2751,10 @@ class MirCompiler {
|
|
|
2527
2751
|
}
|
|
2528
2752
|
case "call":
|
|
2529
2753
|
return this.compileCall(data, context);
|
|
2754
|
+
case "publish_delegate":
|
|
2755
|
+
return this.compilePublishDelegate(data, context);
|
|
2756
|
+
case "publish_log":
|
|
2757
|
+
return this.compilePublishLog(data, context);
|
|
2530
2758
|
case "output_store":
|
|
2531
2759
|
return this.compileOutputStore(data, context);
|
|
2532
2760
|
case "control_output_store":
|
|
@@ -2792,6 +3020,561 @@ class MirCompiler {
|
|
|
2792
3020
|
]);
|
|
2793
3021
|
}
|
|
2794
3022
|
|
|
3023
|
+
compilePublishDelegate(data, context) {
|
|
3024
|
+
const delegate = this.mir.interface.delegates[data.delegate];
|
|
3025
|
+
const layout = this.delegateLayout[data.delegate];
|
|
3026
|
+
if (!delegate || !layout || data.args?.length !== delegate.params.length) {
|
|
3027
|
+
this.fail(`delegate id ${String(data.delegate)} has an invalid publication payload`);
|
|
3028
|
+
}
|
|
3029
|
+
if (context.function.attributes.runtime_context !== true) {
|
|
3030
|
+
this.fail(`function '${context.function.name}' publishes without runtime context`);
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
const payloadBytes = this.allocateGeneratedLocal(
|
|
3034
|
+
context,
|
|
3035
|
+
"i32",
|
|
3036
|
+
`delegate.${data.delegate}.payload_bytes`,
|
|
3037
|
+
);
|
|
3038
|
+
const oversized = this.allocateGeneratedLocal(
|
|
3039
|
+
context,
|
|
3040
|
+
"i32",
|
|
3041
|
+
`delegate.${data.delegate}.oversized`,
|
|
3042
|
+
);
|
|
3043
|
+
const record = this.allocateGeneratedLocal(
|
|
3044
|
+
context,
|
|
3045
|
+
"i32",
|
|
3046
|
+
`delegate.${data.delegate}.record`,
|
|
3047
|
+
);
|
|
3048
|
+
const cursor = this.allocateGeneratedLocal(
|
|
3049
|
+
context,
|
|
3050
|
+
"i32",
|
|
3051
|
+
`delegate.${data.delegate}.cursor`,
|
|
3052
|
+
);
|
|
3053
|
+
const counter = this.allocateGeneratedLocal(
|
|
3054
|
+
context,
|
|
3055
|
+
"i32",
|
|
3056
|
+
`delegate.${data.delegate}.copy_index`,
|
|
3057
|
+
);
|
|
3058
|
+
const payload = () => this.module.local.get(payloadBytes, binaryen.i32);
|
|
3059
|
+
const tooLarge = () => this.module.local.get(oversized, binaryen.i32);
|
|
3060
|
+
const batch = () =>
|
|
3061
|
+
this.module.global.get(POINTER_GLOBALS.delegateBatch, binaryen.i32);
|
|
3062
|
+
const validationStatements = [];
|
|
3063
|
+
const collectionStatements = [
|
|
3064
|
+
this.module.local.set(
|
|
3065
|
+
payloadBytes,
|
|
3066
|
+
this.module.i32.const(layout.minimumByteLength),
|
|
3067
|
+
),
|
|
3068
|
+
this.module.local.set(
|
|
3069
|
+
oversized,
|
|
3070
|
+
this.module.i32.const(
|
|
3071
|
+
layout.minimumByteLength > 0xffff_ffff - DELEGATE_RECORD_HEADER_SIZE
|
|
3072
|
+
? 1
|
|
3073
|
+
: 0,
|
|
3074
|
+
),
|
|
3075
|
+
),
|
|
3076
|
+
];
|
|
3077
|
+
|
|
3078
|
+
for (const [paramId, param] of delegate.params.entries()) {
|
|
3079
|
+
const type = this.type(param.ty);
|
|
3080
|
+
const argument = data.args[paramId];
|
|
3081
|
+
if (argument?.kind !== "value") {
|
|
3082
|
+
this.fail(`delegate '${delegate.name}' argument ${paramId} is not a value`);
|
|
3083
|
+
}
|
|
3084
|
+
if (type.kind !== "slice") continue;
|
|
3085
|
+
const element = type.data.element;
|
|
3086
|
+
const elementSize = this.scalarSize(element);
|
|
3087
|
+
const length = () => this.compileSliceValue(argument.data, context)[2];
|
|
3088
|
+
const delta = () =>
|
|
3089
|
+
this.module.i32.mul(length(), this.module.i32.const(elementSize));
|
|
3090
|
+
const next = () => this.module.i32.add(payload(), delta());
|
|
3091
|
+
collectionStatements.push(
|
|
3092
|
+
this.module.local.set(
|
|
3093
|
+
oversized,
|
|
3094
|
+
this.module.i32.or(
|
|
3095
|
+
tooLarge(),
|
|
3096
|
+
this.module.i32.or(
|
|
3097
|
+
this.module.i32.gt_u(
|
|
3098
|
+
length(),
|
|
3099
|
+
this.module.i32.const(Math.floor(0xffff_ffff / elementSize)),
|
|
3100
|
+
),
|
|
3101
|
+
this.module.i32.lt_u(next(), payload()),
|
|
3102
|
+
),
|
|
3103
|
+
),
|
|
3104
|
+
),
|
|
3105
|
+
this.module.local.set(payloadBytes, next()),
|
|
3106
|
+
);
|
|
3107
|
+
}
|
|
3108
|
+
for (const [paramId, param] of delegate.params.entries()) {
|
|
3109
|
+
const type = this.type(param.ty);
|
|
3110
|
+
if (type.kind !== "array") continue;
|
|
3111
|
+
const argument = data.args[paramId];
|
|
3112
|
+
const sliceLength = () => this.compileSliceValue(argument.data, context)[2];
|
|
3113
|
+
validationStatements.push(
|
|
3114
|
+
this.module.if(
|
|
3115
|
+
this.module.i32.ne(
|
|
3116
|
+
sliceLength(),
|
|
3117
|
+
this.module.i32.const(type.data.len),
|
|
3118
|
+
),
|
|
3119
|
+
this.raiseRuntimeFailure(context),
|
|
3120
|
+
),
|
|
3121
|
+
);
|
|
3122
|
+
}
|
|
3123
|
+
collectionStatements.push(
|
|
3124
|
+
this.module.local.set(
|
|
3125
|
+
oversized,
|
|
3126
|
+
this.module.i32.or(
|
|
3127
|
+
tooLarge(),
|
|
3128
|
+
this.module.i32.gt_u(
|
|
3129
|
+
payload(),
|
|
3130
|
+
this.module.i32.const(0xffff_ffff - DELEGATE_RECORD_HEADER_SIZE),
|
|
3131
|
+
),
|
|
3132
|
+
),
|
|
3133
|
+
),
|
|
3134
|
+
this.compileDelegateBatchAppend(
|
|
3135
|
+
data.delegate,
|
|
3136
|
+
delegate,
|
|
3137
|
+
data.args,
|
|
3138
|
+
payload,
|
|
3139
|
+
tooLarge,
|
|
3140
|
+
record,
|
|
3141
|
+
cursor,
|
|
3142
|
+
counter,
|
|
3143
|
+
context,
|
|
3144
|
+
),
|
|
3145
|
+
);
|
|
3146
|
+
return this.module.block(null, [
|
|
3147
|
+
...validationStatements,
|
|
3148
|
+
this.module.if(
|
|
3149
|
+
this.module.i32.ne(batch(), this.module.i32.const(0)),
|
|
3150
|
+
this.module.block(null, collectionStatements),
|
|
3151
|
+
),
|
|
3152
|
+
]);
|
|
3153
|
+
}
|
|
3154
|
+
|
|
3155
|
+
compilePublishLog(data, context) {
|
|
3156
|
+
const site = this.mir.log_sites?.[data.site];
|
|
3157
|
+
const args = data.arguments;
|
|
3158
|
+
if (!site || !Array.isArray(args) || args.length !== site.argument_types?.length) {
|
|
3159
|
+
this.fail(`log site id ${String(data.site)} has an invalid publication payload`);
|
|
3160
|
+
}
|
|
3161
|
+
if (context.function.attributes.runtime_context !== true) {
|
|
3162
|
+
this.fail(`function '${context.function.name}' prints without runtime context`);
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
const payloadSize = site.payload_size;
|
|
3166
|
+
const calculatedSize = site.argument_types.reduce(
|
|
3167
|
+
(size, scalar) => size + this.scalarSize(scalar),
|
|
3168
|
+
0,
|
|
3169
|
+
);
|
|
3170
|
+
if (!Number.isInteger(payloadSize) || payloadSize !== calculatedSize) {
|
|
3171
|
+
this.fail(`log site id ${data.site} has an invalid payload size`);
|
|
3172
|
+
}
|
|
3173
|
+
|
|
3174
|
+
const storageLocal = this.allocateGeneratedLocal(
|
|
3175
|
+
context,
|
|
3176
|
+
"i32",
|
|
3177
|
+
`log.${data.site}.storage`,
|
|
3178
|
+
);
|
|
3179
|
+
const capacityLocal = this.allocateGeneratedLocal(
|
|
3180
|
+
context,
|
|
3181
|
+
"i32",
|
|
3182
|
+
`log.${data.site}.capacity`,
|
|
3183
|
+
);
|
|
3184
|
+
const usedLocal = this.allocateGeneratedLocal(
|
|
3185
|
+
context,
|
|
3186
|
+
"i32",
|
|
3187
|
+
`log.${data.site}.used`,
|
|
3188
|
+
);
|
|
3189
|
+
const recordLocal = this.allocateGeneratedLocal(
|
|
3190
|
+
context,
|
|
3191
|
+
"i32",
|
|
3192
|
+
`log.${data.site}.record`,
|
|
3193
|
+
);
|
|
3194
|
+
const cursorLocal = this.allocateGeneratedLocal(
|
|
3195
|
+
context,
|
|
3196
|
+
"i32",
|
|
3197
|
+
`log.${data.site}.cursor`,
|
|
3198
|
+
);
|
|
3199
|
+
const sequenceLocal = this.allocateGeneratedLocal(
|
|
3200
|
+
context,
|
|
3201
|
+
"i32",
|
|
3202
|
+
`log.${data.site}.sequence`,
|
|
3203
|
+
);
|
|
3204
|
+
const batch = () =>
|
|
3205
|
+
this.module.global.get(POINTER_GLOBALS.printBatch, binaryen.i32);
|
|
3206
|
+
const field = (offset) =>
|
|
3207
|
+
this.module.i32.add(batch(), this.module.i32.const(offset));
|
|
3208
|
+
const local = (id) => this.module.local.get(id, binaryen.i32);
|
|
3209
|
+
const requiredSize = payloadSize + PRINT_RECORD_HEADER_SIZE;
|
|
3210
|
+
const overflowAddress = () => field(PRINT_BATCH_OVERFLOW_OFFSET);
|
|
3211
|
+
const overflow = () => this.module.i32.load(0, 4, overflowAddress());
|
|
3212
|
+
const drop = this.module.i32.store(
|
|
3213
|
+
0,
|
|
3214
|
+
4,
|
|
3215
|
+
overflowAddress(),
|
|
3216
|
+
this.module.select(
|
|
3217
|
+
this.module.i32.eq(overflow(), this.module.i32.const(-1)),
|
|
3218
|
+
overflow(),
|
|
3219
|
+
this.module.i32.add(overflow(), this.module.i32.const(1)),
|
|
3220
|
+
),
|
|
3221
|
+
);
|
|
3222
|
+
const fits = this.module.i32.and(
|
|
3223
|
+
this.module.i32.le_u(local(usedLocal), local(capacityLocal)),
|
|
3224
|
+
this.module.i32.le_u(
|
|
3225
|
+
this.module.i32.const(requiredSize),
|
|
3226
|
+
this.module.i32.sub(local(capacityLocal), local(usedLocal)),
|
|
3227
|
+
),
|
|
3228
|
+
);
|
|
3229
|
+
const record = () => local(recordLocal);
|
|
3230
|
+
const cursor = () => local(cursorLocal);
|
|
3231
|
+
const write = [
|
|
3232
|
+
this.module.local.set(
|
|
3233
|
+
recordLocal,
|
|
3234
|
+
this.module.i32.add(local(storageLocal), local(usedLocal)),
|
|
3235
|
+
),
|
|
3236
|
+
this.module.i32.store(0, 1, record(), this.module.i32.const(data.site)),
|
|
3237
|
+
this.module.i32.store(4, 1, record(), this.module.i32.const(payloadSize)),
|
|
3238
|
+
this.module.i32.store(8, 1, record(), local(sequenceLocal)),
|
|
3239
|
+
this.module.local.set(
|
|
3240
|
+
cursorLocal,
|
|
3241
|
+
this.module.i32.add(record(), this.module.i32.const(PRINT_RECORD_HEADER_SIZE)),
|
|
3242
|
+
),
|
|
3243
|
+
];
|
|
3244
|
+
for (const [index, scalar] of site.argument_types.entries()) {
|
|
3245
|
+
write.push(
|
|
3246
|
+
this.storePackedScalar(
|
|
3247
|
+
scalar,
|
|
3248
|
+
cursor(),
|
|
3249
|
+
this.compileValue(args[index], context),
|
|
3250
|
+
),
|
|
3251
|
+
this.module.local.set(
|
|
3252
|
+
cursorLocal,
|
|
3253
|
+
this.module.i32.add(cursor(), this.module.i32.const(this.scalarSize(scalar))),
|
|
3254
|
+
),
|
|
3255
|
+
);
|
|
3256
|
+
}
|
|
3257
|
+
const usedAddress = () => field(PRINT_BATCH_USED_OFFSET);
|
|
3258
|
+
const countAddress = () => field(PRINT_BATCH_RECORD_COUNT_OFFSET);
|
|
3259
|
+
write.push(
|
|
3260
|
+
this.module.i32.store(
|
|
3261
|
+
0,
|
|
3262
|
+
4,
|
|
3263
|
+
usedAddress(),
|
|
3264
|
+
this.module.i32.add(local(usedLocal), this.module.i32.const(requiredSize)),
|
|
3265
|
+
),
|
|
3266
|
+
this.module.i32.store(
|
|
3267
|
+
0,
|
|
3268
|
+
4,
|
|
3269
|
+
countAddress(),
|
|
3270
|
+
this.module.i32.add(
|
|
3271
|
+
this.module.i32.load(0, 4, countAddress()),
|
|
3272
|
+
this.module.i32.const(1),
|
|
3273
|
+
),
|
|
3274
|
+
),
|
|
3275
|
+
);
|
|
3276
|
+
return this.module.if(
|
|
3277
|
+
this.module.i32.ne(batch(), this.module.i32.const(0)),
|
|
3278
|
+
this.module.block(null, [
|
|
3279
|
+
this.advanceOutputSequence(sequenceLocal),
|
|
3280
|
+
this.module.local.set(
|
|
3281
|
+
storageLocal,
|
|
3282
|
+
this.module.i32.load(0, 4, field(PRINT_BATCH_STORAGE_OFFSET)),
|
|
3283
|
+
),
|
|
3284
|
+
this.module.if(
|
|
3285
|
+
this.module.i32.ne(local(storageLocal), this.module.i32.const(0)),
|
|
3286
|
+
this.module.block(null, [
|
|
3287
|
+
this.module.local.set(
|
|
3288
|
+
capacityLocal,
|
|
3289
|
+
this.module.i32.load(0, 4, field(PRINT_BATCH_CAPACITY_OFFSET)),
|
|
3290
|
+
),
|
|
3291
|
+
this.module.local.set(
|
|
3292
|
+
usedLocal,
|
|
3293
|
+
this.module.i32.load(0, 4, field(PRINT_BATCH_USED_OFFSET)),
|
|
3294
|
+
),
|
|
3295
|
+
this.module.if(fits, this.module.block(null, write), drop),
|
|
3296
|
+
]),
|
|
3297
|
+
),
|
|
3298
|
+
]),
|
|
3299
|
+
);
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
compileDelegateBatchAppend(
|
|
3303
|
+
delegateId,
|
|
3304
|
+
delegate,
|
|
3305
|
+
args,
|
|
3306
|
+
payload,
|
|
3307
|
+
tooLarge,
|
|
3308
|
+
recordLocal,
|
|
3309
|
+
cursorLocal,
|
|
3310
|
+
counterLocal,
|
|
3311
|
+
context,
|
|
3312
|
+
) {
|
|
3313
|
+
const batch = () =>
|
|
3314
|
+
this.module.global.get(POINTER_GLOBALS.delegateBatch, binaryen.i32);
|
|
3315
|
+
const field = (offset) =>
|
|
3316
|
+
this.module.i32.add(batch(), this.module.i32.const(offset));
|
|
3317
|
+
const storage = this.allocateGeneratedLocal(
|
|
3318
|
+
context,
|
|
3319
|
+
"i32",
|
|
3320
|
+
`delegate.${delegateId}.storage`,
|
|
3321
|
+
);
|
|
3322
|
+
const capacity = this.allocateGeneratedLocal(
|
|
3323
|
+
context,
|
|
3324
|
+
"i32",
|
|
3325
|
+
`delegate.${delegateId}.capacity`,
|
|
3326
|
+
);
|
|
3327
|
+
const used = this.allocateGeneratedLocal(
|
|
3328
|
+
context,
|
|
3329
|
+
"i32",
|
|
3330
|
+
`delegate.${delegateId}.used`,
|
|
3331
|
+
);
|
|
3332
|
+
const required = this.allocateGeneratedLocal(
|
|
3333
|
+
context,
|
|
3334
|
+
"i32",
|
|
3335
|
+
`delegate.${delegateId}.required`,
|
|
3336
|
+
);
|
|
3337
|
+
const sequence = this.allocateGeneratedLocal(
|
|
3338
|
+
context,
|
|
3339
|
+
"i32",
|
|
3340
|
+
`delegate.${delegateId}.sequence`,
|
|
3341
|
+
);
|
|
3342
|
+
const local = (id) => this.module.local.get(id, binaryen.i32);
|
|
3343
|
+
const write = this.compileDelegateRecord(
|
|
3344
|
+
delegateId,
|
|
3345
|
+
delegate,
|
|
3346
|
+
args,
|
|
3347
|
+
payload,
|
|
3348
|
+
() => local(storage),
|
|
3349
|
+
() => local(used),
|
|
3350
|
+
recordLocal,
|
|
3351
|
+
cursorLocal,
|
|
3352
|
+
counterLocal,
|
|
3353
|
+
sequence,
|
|
3354
|
+
context,
|
|
3355
|
+
);
|
|
3356
|
+
const overflowAddress = () => field(DELEGATE_BATCH_OVERFLOW_OFFSET);
|
|
3357
|
+
const overflow = () => this.module.i32.load(0, 4, overflowAddress());
|
|
3358
|
+
const drop = this.module.i32.store(
|
|
3359
|
+
0,
|
|
3360
|
+
4,
|
|
3361
|
+
overflowAddress(),
|
|
3362
|
+
this.module.select(
|
|
3363
|
+
this.module.i32.eq(overflow(), this.module.i32.const(-1)),
|
|
3364
|
+
overflow(),
|
|
3365
|
+
this.module.i32.add(overflow(), this.module.i32.const(1)),
|
|
3366
|
+
),
|
|
3367
|
+
);
|
|
3368
|
+
const fit = this.module.i32.and(
|
|
3369
|
+
this.module.i32.eq(tooLarge(), this.module.i32.const(0)),
|
|
3370
|
+
this.module.i32.and(
|
|
3371
|
+
this.module.i32.le_u(local(used), local(capacity)),
|
|
3372
|
+
this.module.i32.le_u(
|
|
3373
|
+
local(required),
|
|
3374
|
+
this.module.i32.sub(local(capacity), local(used)),
|
|
3375
|
+
),
|
|
3376
|
+
),
|
|
3377
|
+
);
|
|
3378
|
+
return this.module.block(null, [
|
|
3379
|
+
this.advanceOutputSequence(sequence),
|
|
3380
|
+
this.module.local.set(
|
|
3381
|
+
storage,
|
|
3382
|
+
this.module.i32.load(0, 4, field(DELEGATE_BATCH_STORAGE_OFFSET)),
|
|
3383
|
+
),
|
|
3384
|
+
this.module.if(
|
|
3385
|
+
this.module.i32.ne(local(storage), this.module.i32.const(0)),
|
|
3386
|
+
this.module.block(null, [
|
|
3387
|
+
this.module.local.set(
|
|
3388
|
+
capacity,
|
|
3389
|
+
this.module.i32.load(0, 4, field(DELEGATE_BATCH_CAPACITY_OFFSET)),
|
|
3390
|
+
),
|
|
3391
|
+
this.module.local.set(
|
|
3392
|
+
used,
|
|
3393
|
+
this.module.i32.load(0, 4, field(DELEGATE_BATCH_USED_OFFSET)),
|
|
3394
|
+
),
|
|
3395
|
+
this.module.local.set(
|
|
3396
|
+
required,
|
|
3397
|
+
this.module.i32.add(
|
|
3398
|
+
payload(),
|
|
3399
|
+
this.module.i32.const(DELEGATE_RECORD_HEADER_SIZE),
|
|
3400
|
+
),
|
|
3401
|
+
),
|
|
3402
|
+
this.module.if(fit, write, drop),
|
|
3403
|
+
]),
|
|
3404
|
+
),
|
|
3405
|
+
]);
|
|
3406
|
+
}
|
|
3407
|
+
|
|
3408
|
+
compileDelegateRecord(
|
|
3409
|
+
delegateId,
|
|
3410
|
+
delegate,
|
|
3411
|
+
args,
|
|
3412
|
+
payload,
|
|
3413
|
+
storage,
|
|
3414
|
+
used,
|
|
3415
|
+
recordLocal,
|
|
3416
|
+
cursorLocal,
|
|
3417
|
+
counterLocal,
|
|
3418
|
+
sequenceLocal,
|
|
3419
|
+
context,
|
|
3420
|
+
) {
|
|
3421
|
+
const batch = () =>
|
|
3422
|
+
this.module.global.get(POINTER_GLOBALS.delegateBatch, binaryen.i32);
|
|
3423
|
+
const record = () => this.module.local.get(recordLocal, binaryen.i32);
|
|
3424
|
+
const cursor = () => this.module.local.get(cursorLocal, binaryen.i32);
|
|
3425
|
+
const statements = [];
|
|
3426
|
+
statements.push(
|
|
3427
|
+
this.module.local.set(recordLocal, this.module.i32.add(storage(), used())),
|
|
3428
|
+
this.module.i32.store(0, 1, record(), this.module.i32.const(delegateId)),
|
|
3429
|
+
this.module.i32.store(4, 1, record(), payload()),
|
|
3430
|
+
this.module.i32.store(
|
|
3431
|
+
8,
|
|
3432
|
+
1,
|
|
3433
|
+
record(),
|
|
3434
|
+
this.module.local.get(sequenceLocal, binaryen.i32),
|
|
3435
|
+
),
|
|
3436
|
+
this.module.local.set(
|
|
3437
|
+
cursorLocal,
|
|
3438
|
+
this.module.i32.add(
|
|
3439
|
+
record(),
|
|
3440
|
+
this.module.i32.const(DELEGATE_RECORD_HEADER_SIZE),
|
|
3441
|
+
),
|
|
3442
|
+
),
|
|
3443
|
+
);
|
|
3444
|
+
for (const [paramId, param] of delegate.params.entries()) {
|
|
3445
|
+
const type = this.type(param.ty);
|
|
3446
|
+
const argument = args[paramId];
|
|
3447
|
+
if (type.kind === "scalar") {
|
|
3448
|
+
statements.push(
|
|
3449
|
+
this.storePackedScalar(
|
|
3450
|
+
type.data,
|
|
3451
|
+
cursor(),
|
|
3452
|
+
this.compileValue(argument.data, context),
|
|
3453
|
+
),
|
|
3454
|
+
this.module.local.set(
|
|
3455
|
+
cursorLocal,
|
|
3456
|
+
this.module.i32.add(
|
|
3457
|
+
cursor(),
|
|
3458
|
+
this.module.i32.const(this.scalarSize(type.data)),
|
|
3459
|
+
),
|
|
3460
|
+
),
|
|
3461
|
+
);
|
|
3462
|
+
continue;
|
|
3463
|
+
}
|
|
3464
|
+
const element = type.kind === "slice"
|
|
3465
|
+
? type.data.element
|
|
3466
|
+
: this.requireScalarType(
|
|
3467
|
+
type.data.element,
|
|
3468
|
+
`delegate '${delegate.name}' aggregate parameter ${paramId}`,
|
|
3469
|
+
);
|
|
3470
|
+
const slice = () => this.compileSliceValue(argument.data, context);
|
|
3471
|
+
const count = type.kind === "array"
|
|
3472
|
+
? () => this.module.i32.const(type.data.len)
|
|
3473
|
+
: () => slice()[2];
|
|
3474
|
+
if (type.kind === "slice") {
|
|
3475
|
+
statements.push(
|
|
3476
|
+
this.module.i32.store(0, 1, cursor(), count()),
|
|
3477
|
+
this.module.local.set(
|
|
3478
|
+
cursorLocal,
|
|
3479
|
+
this.module.i32.add(cursor(), this.module.i32.const(4)),
|
|
3480
|
+
),
|
|
3481
|
+
);
|
|
3482
|
+
}
|
|
3483
|
+
statements.push(
|
|
3484
|
+
this.compilePackedSliceCopy(
|
|
3485
|
+
slice,
|
|
3486
|
+
count,
|
|
3487
|
+
element,
|
|
3488
|
+
cursor,
|
|
3489
|
+
counterLocal,
|
|
3490
|
+
),
|
|
3491
|
+
this.module.local.set(
|
|
3492
|
+
cursorLocal,
|
|
3493
|
+
this.module.i32.add(
|
|
3494
|
+
cursor(),
|
|
3495
|
+
this.module.i32.mul(
|
|
3496
|
+
count(),
|
|
3497
|
+
this.module.i32.const(this.scalarSize(element)),
|
|
3498
|
+
),
|
|
3499
|
+
),
|
|
3500
|
+
),
|
|
3501
|
+
);
|
|
3502
|
+
}
|
|
3503
|
+
const usedAddress = () =>
|
|
3504
|
+
this.module.i32.add(
|
|
3505
|
+
batch(),
|
|
3506
|
+
this.module.i32.const(DELEGATE_BATCH_USED_OFFSET),
|
|
3507
|
+
);
|
|
3508
|
+
const countAddress = () =>
|
|
3509
|
+
this.module.i32.add(
|
|
3510
|
+
batch(),
|
|
3511
|
+
this.module.i32.const(DELEGATE_BATCH_RECORD_COUNT_OFFSET),
|
|
3512
|
+
);
|
|
3513
|
+
statements.push(
|
|
3514
|
+
this.module.i32.store(
|
|
3515
|
+
0,
|
|
3516
|
+
4,
|
|
3517
|
+
usedAddress(),
|
|
3518
|
+
this.module.i32.add(
|
|
3519
|
+
used(),
|
|
3520
|
+
this.module.i32.add(
|
|
3521
|
+
payload(),
|
|
3522
|
+
this.module.i32.const(DELEGATE_RECORD_HEADER_SIZE),
|
|
3523
|
+
),
|
|
3524
|
+
),
|
|
3525
|
+
),
|
|
3526
|
+
this.module.i32.store(
|
|
3527
|
+
0,
|
|
3528
|
+
4,
|
|
3529
|
+
countAddress(),
|
|
3530
|
+
this.module.i32.add(
|
|
3531
|
+
this.module.i32.load(0, 4, countAddress()),
|
|
3532
|
+
this.module.i32.const(1),
|
|
3533
|
+
),
|
|
3534
|
+
),
|
|
3535
|
+
);
|
|
3536
|
+
return this.module.block(null, statements);
|
|
3537
|
+
}
|
|
3538
|
+
|
|
3539
|
+
compilePackedSliceCopy(slice, count, scalar, destination, counterLocal) {
|
|
3540
|
+
const loopLabel = `$onda.delegate.copy.${this.nextLabel++}`;
|
|
3541
|
+
const counter = () => this.module.local.get(counterLocal, binaryen.i32);
|
|
3542
|
+
const sourceAddress = () =>
|
|
3543
|
+
this.module.i32.add(
|
|
3544
|
+
slice()[0],
|
|
3545
|
+
this.module.i32.mul(counter(), slice()[3]),
|
|
3546
|
+
);
|
|
3547
|
+
const destinationAddress = () =>
|
|
3548
|
+
this.module.i32.add(
|
|
3549
|
+
destination(),
|
|
3550
|
+
this.module.i32.mul(
|
|
3551
|
+
counter(),
|
|
3552
|
+
this.module.i32.const(this.scalarSize(scalar)),
|
|
3553
|
+
),
|
|
3554
|
+
);
|
|
3555
|
+
return this.module.block(null, [
|
|
3556
|
+
this.module.local.set(counterLocal, this.module.i32.const(0)),
|
|
3557
|
+
this.module.loop(
|
|
3558
|
+
loopLabel,
|
|
3559
|
+
this.module.if(
|
|
3560
|
+
this.module.i32.lt_u(counter(), count()),
|
|
3561
|
+
this.module.block(null, [
|
|
3562
|
+
this.storePackedScalar(
|
|
3563
|
+
scalar,
|
|
3564
|
+
destinationAddress(),
|
|
3565
|
+
this.loadScalar(scalar, sourceAddress()),
|
|
3566
|
+
),
|
|
3567
|
+
this.module.local.set(
|
|
3568
|
+
counterLocal,
|
|
3569
|
+
this.module.i32.add(counter(), this.module.i32.const(1)),
|
|
3570
|
+
),
|
|
3571
|
+
this.module.br(loopLabel),
|
|
3572
|
+
]),
|
|
3573
|
+
),
|
|
3574
|
+
),
|
|
3575
|
+
]);
|
|
3576
|
+
}
|
|
3577
|
+
|
|
2795
3578
|
compileOutputStore(data, context) {
|
|
2796
3579
|
this.requireProcessFrame(data.frame, context, "audio output store");
|
|
2797
3580
|
const port = this.outputLayout[data.output];
|
|
@@ -2925,6 +3708,11 @@ class MirCompiler {
|
|
|
2925
3708
|
);
|
|
2926
3709
|
case "intrinsic":
|
|
2927
3710
|
return this.compileIntrinsic(data, expectedScalar, context);
|
|
3711
|
+
case "init_all":
|
|
3712
|
+
if (context.function.kind?.kind !== "init") {
|
|
3713
|
+
this.fail("init_all is only valid in the init entry point");
|
|
3714
|
+
}
|
|
3715
|
+
return this.module.global.get(INIT_ALL_GLOBAL, binaryen.i32);
|
|
2928
3716
|
case "process_frame":
|
|
2929
3717
|
return this.compileProcessFrame(data, context);
|
|
2930
3718
|
case "input_load":
|
|
@@ -2954,6 +3742,10 @@ class MirCompiler {
|
|
|
2954
3742
|
);
|
|
2955
3743
|
case "buffer_param_sample_rate":
|
|
2956
3744
|
return this.loadBufferParamComponent(data, 4, "f32", context);
|
|
3745
|
+
case "buffer_is_bound":
|
|
3746
|
+
return this.compileBufferIsBound(data, context);
|
|
3747
|
+
case "buffer_param_is_bound":
|
|
3748
|
+
return this.loadBufferParamComponent(data, 5, "i32", context);
|
|
2957
3749
|
case "slice_len":
|
|
2958
3750
|
return this.compileSliceValue(data, context)[2];
|
|
2959
3751
|
case "slice_load":
|
|
@@ -3356,6 +4148,20 @@ class MirCompiler {
|
|
|
3356
4148
|
);
|
|
3357
4149
|
}
|
|
3358
4150
|
|
|
4151
|
+
compileBufferIsBound(bufferRef, context) {
|
|
4152
|
+
this.requireBufferRef(bufferRef);
|
|
4153
|
+
return this.withBufferRefIndex(
|
|
4154
|
+
bufferRef,
|
|
4155
|
+
context,
|
|
4156
|
+
binaryen.i32,
|
|
4157
|
+
(index, staticIndex) => this.bufferBoundFactory(
|
|
4158
|
+
index,
|
|
4159
|
+
staticIndex,
|
|
4160
|
+
context,
|
|
4161
|
+
)(),
|
|
4162
|
+
);
|
|
4163
|
+
}
|
|
4164
|
+
|
|
3359
4165
|
compileBufferChannels(bufferRef, context) {
|
|
3360
4166
|
const channels = this.bufferRefChannelMetadata(bufferRef);
|
|
3361
4167
|
if (channels.kind === "mono") return this.module.i32.const(1);
|
|
@@ -3543,6 +4349,9 @@ class MirCompiler {
|
|
|
3543
4349
|
return this.loadScalar(scalar, address);
|
|
3544
4350
|
};
|
|
3545
4351
|
const load = (index) => {
|
|
4352
|
+
if (offset === 5) {
|
|
4353
|
+
return this.module.i32.ne(rawLoad(index), this.module.i32.const(0));
|
|
4354
|
+
}
|
|
3546
4355
|
if (scalar !== "i32" || (offset !== 0 && offset !== 1)) {
|
|
3547
4356
|
return rawLoad(index);
|
|
3548
4357
|
}
|
|
@@ -3615,7 +4424,7 @@ class MirCompiler {
|
|
|
3615
4424
|
}
|
|
3616
4425
|
|
|
3617
4426
|
loadBufferParamValue(parameterId, context) {
|
|
3618
|
-
const components = ["i32", "i32", "i32", "i32", "f32"];
|
|
4427
|
+
const components = ["i32", "i32", "i32", "i32", "f32", "i32"];
|
|
3619
4428
|
if (parameterId?.kind !== "array_element") {
|
|
3620
4429
|
return components.map((scalar, offset) =>
|
|
3621
4430
|
this.loadBufferParamComponent(parameterId, offset, scalar, context),
|
|
@@ -3706,6 +4515,7 @@ class MirCompiler {
|
|
|
3706
4515
|
? this.module.i32.const(channels.count)
|
|
3707
4516
|
: component(POINTER_GLOBALS.bufferChannels, "i32"),
|
|
3708
4517
|
component(POINTER_GLOBALS.bufferSampleRates, "f32"),
|
|
4518
|
+
this.bufferBoundFactory(descriptorIndex, staticIndex, context)(),
|
|
3709
4519
|
];
|
|
3710
4520
|
if (initializeIndex !== null) {
|
|
3711
4521
|
values[0] = this.module.block(
|
|
@@ -3728,8 +4538,9 @@ class MirCompiler {
|
|
|
3728
4538
|
POINTER_GLOBALS.bufferFrames,
|
|
3729
4539
|
POINTER_GLOBALS.bufferChannels,
|
|
3730
4540
|
POINTER_GLOBALS.bufferSampleRates,
|
|
4541
|
+
POINTER_GLOBALS.buffers,
|
|
3731
4542
|
];
|
|
3732
|
-
const tableScalars = ["i32", "i32", "i32", "i32", "f32"];
|
|
4543
|
+
const tableScalars = ["i32", "i32", "i32", "i32", "f32", "i32"];
|
|
3733
4544
|
let tables;
|
|
3734
4545
|
let start;
|
|
3735
4546
|
if (spanRef.kind === "interface") {
|
|
@@ -3833,6 +4644,31 @@ class MirCompiler {
|
|
|
3833
4644
|
return () => this.module.local.get(local, this.wasmType(scalar));
|
|
3834
4645
|
}
|
|
3835
4646
|
|
|
4647
|
+
bufferBoundFactory(descriptorIndex, staticIndex, context) {
|
|
4648
|
+
const load = () => this.module.i32.ne(
|
|
4649
|
+
this.loadBufferTableValueAt(
|
|
4650
|
+
POINTER_GLOBALS.buffers,
|
|
4651
|
+
descriptorIndex(),
|
|
4652
|
+
"i32",
|
|
4653
|
+
),
|
|
4654
|
+
this.module.i32.const(0),
|
|
4655
|
+
);
|
|
4656
|
+
if (staticIndex === null) return load;
|
|
4657
|
+
|
|
4658
|
+
const key = `buffer_bound:${staticIndex}`;
|
|
4659
|
+
let local = context.bufferDescriptorCache.get(key);
|
|
4660
|
+
if (local === undefined) {
|
|
4661
|
+
local = this.allocateGeneratedLocal(
|
|
4662
|
+
context,
|
|
4663
|
+
"i32",
|
|
4664
|
+
`buffer.bound.${staticIndex}`,
|
|
4665
|
+
);
|
|
4666
|
+
context.bufferDescriptorCache.set(key, local);
|
|
4667
|
+
context.entryInitializers.push(this.module.local.set(local, load()));
|
|
4668
|
+
}
|
|
4669
|
+
return () => this.module.local.get(local, binaryen.i32);
|
|
4670
|
+
}
|
|
4671
|
+
|
|
3836
4672
|
bufferChannelsFactory(
|
|
3837
4673
|
bufferRef,
|
|
3838
4674
|
descriptorIndex,
|
|
@@ -5287,6 +6123,62 @@ class MirCompiler {
|
|
|
5287
6123
|
arg(0),
|
|
5288
6124
|
),
|
|
5289
6125
|
);
|
|
6126
|
+
case "range_wrap": { // Bounds are validator-required integer constants.
|
|
6127
|
+
const lowerLiteral = data.args[1]?.data;
|
|
6128
|
+
const upperLiteral = data.args[2]?.data;
|
|
6129
|
+
if (
|
|
6130
|
+
data.args[1]?.kind !== "constant"
|
|
6131
|
+
|| data.args[2]?.kind !== "constant"
|
|
6132
|
+
|| lowerLiteral?.type !== scalar
|
|
6133
|
+
|| upperLiteral?.type !== scalar
|
|
6134
|
+
) {
|
|
6135
|
+
this.fail("range_wrap requires constant bounds matching its integer operand");
|
|
6136
|
+
}
|
|
6137
|
+
const lower = scalar === "i64"
|
|
6138
|
+
? decodeI64Literal(lowerLiteral.value, this)
|
|
6139
|
+
: BigInt(lowerLiteral.value);
|
|
6140
|
+
const upper = scalar === "i64"
|
|
6141
|
+
? decodeI64Literal(upperLiteral.value, this)
|
|
6142
|
+
: BigInt(upperLiteral.value);
|
|
6143
|
+
const bits = scalar === "i64" ? 64n : 32n;
|
|
6144
|
+
const width = upper - lower + 1n;
|
|
6145
|
+
if (width === (1n << bits)) return arg(0);
|
|
6146
|
+
const encodedWidth = BigInt.asIntN(Number(bits), width);
|
|
6147
|
+
const widthValue = scalar === "i64"
|
|
6148
|
+
? this.module.i64.const(encodedWidth)
|
|
6149
|
+
: this.module.i32.const(Number(encodedWidth));
|
|
6150
|
+
const encodedSpan = BigInt.asIntN(Number(bits), width - 1n);
|
|
6151
|
+
const spanValue = scalar === "i64"
|
|
6152
|
+
? this.module.i64.const(encodedSpan)
|
|
6153
|
+
: this.module.i32.const(Number(encodedSpan));
|
|
6154
|
+
const one = scalar === "i64"
|
|
6155
|
+
? this.module.i64.const(1n)
|
|
6156
|
+
: this.module.i32.const(1);
|
|
6157
|
+
const distanceFromLower = lower === 0n
|
|
6158
|
+
? arg(0)
|
|
6159
|
+
: wasm.sub(arg(0), arg(1));
|
|
6160
|
+
return this.module.if(
|
|
6161
|
+
wasm.le_u(distanceFromLower, spanValue),
|
|
6162
|
+
arg(0),
|
|
6163
|
+
this.module.if(
|
|
6164
|
+
wasm.lt_s(arg(0), arg(1)),
|
|
6165
|
+
wasm.sub(
|
|
6166
|
+
arg(2),
|
|
6167
|
+
wasm.rem_u(
|
|
6168
|
+
wasm.sub(wasm.sub(arg(1), one), arg(0)),
|
|
6169
|
+
widthValue,
|
|
6170
|
+
),
|
|
6171
|
+
),
|
|
6172
|
+
wasm.add(
|
|
6173
|
+
arg(1),
|
|
6174
|
+
wasm.rem_u(
|
|
6175
|
+
wasm.sub(arg(0), wasm.add(arg(2), one)),
|
|
6176
|
+
widthValue,
|
|
6177
|
+
),
|
|
6178
|
+
),
|
|
6179
|
+
),
|
|
6180
|
+
);
|
|
6181
|
+
}
|
|
5290
6182
|
default:
|
|
5291
6183
|
this.fail(`intrinsic '${data.intrinsic}' requires f32 or f64 operands`);
|
|
5292
6184
|
}
|
|
@@ -5395,6 +6287,17 @@ class MirCompiler {
|
|
|
5395
6287
|
}
|
|
5396
6288
|
}
|
|
5397
6289
|
|
|
6290
|
+
storePackedScalar(scalar, address, value) {
|
|
6291
|
+
switch (scalar) {
|
|
6292
|
+
case "bool": return this.module.i32.store8(0, 1, address, value);
|
|
6293
|
+
case "i32": return this.module.i32.store(0, 1, address, value);
|
|
6294
|
+
case "i64": return this.module.i64.store(0, 1, address, value);
|
|
6295
|
+
case "f32": return this.module.f32.store(0, 1, address, value);
|
|
6296
|
+
case "f64": return this.module.f64.store(0, 1, address, value);
|
|
6297
|
+
default: this.fail(`unknown scalar type '${String(scalar)}'`);
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6300
|
+
|
|
5398
6301
|
type(typeId) {
|
|
5399
6302
|
const type = this.mir.types[typeId];
|
|
5400
6303
|
if (!type) this.fail(`type id ${typeId} is out of range`);
|
|
@@ -5632,7 +6535,7 @@ class MirCompiler {
|
|
|
5632
6535
|
const requiredExports = [
|
|
5633
6536
|
"memory",
|
|
5634
6537
|
"__heap_base",
|
|
5635
|
-
"
|
|
6538
|
+
"onda_processor_init",
|
|
5636
6539
|
"onda_process",
|
|
5637
6540
|
...eventExports,
|
|
5638
6541
|
];
|
|
@@ -5687,7 +6590,7 @@ class MirCompiler {
|
|
|
5687
6590
|
exports: {
|
|
5688
6591
|
memory: "memory",
|
|
5689
6592
|
heap_base: "__heap_base",
|
|
5690
|
-
init: "
|
|
6593
|
+
init: "onda_processor_init",
|
|
5691
6594
|
process: "onda_process",
|
|
5692
6595
|
events: eventExports,
|
|
5693
6596
|
},
|
|
@@ -5702,8 +6605,28 @@ class MirCompiler {
|
|
|
5702
6605
|
param_size_bytes: paramSize,
|
|
5703
6606
|
param_align_bytes: 16,
|
|
5704
6607
|
requires_full_blocks: false,
|
|
6608
|
+
delegate_record_header_size_bytes: DELEGATE_RECORD_HEADER_SIZE,
|
|
6609
|
+
print_record_header_size_bytes: PRINT_RECORD_HEADER_SIZE,
|
|
5705
6610
|
},
|
|
5706
6611
|
metadata: {
|
|
6612
|
+
source_files: (this.mir.source_files ?? []).map((file) => ({
|
|
6613
|
+
path: file.path,
|
|
6614
|
+
})),
|
|
6615
|
+
log_sites: (this.mir.log_sites ?? []).map((site, index) => ({
|
|
6616
|
+
index,
|
|
6617
|
+
label: site.label ?? null,
|
|
6618
|
+
source: {
|
|
6619
|
+
file: site.source.file ?? null,
|
|
6620
|
+
line: site.source.line,
|
|
6621
|
+
column: site.source.column,
|
|
6622
|
+
end_line: site.source.end_line,
|
|
6623
|
+
end_column: site.source.end_column,
|
|
6624
|
+
},
|
|
6625
|
+
lexical_owner: site.lexical_owner,
|
|
6626
|
+
declaration: site.declaration ?? null,
|
|
6627
|
+
argument_types: [...site.argument_types],
|
|
6628
|
+
payload_size_bytes: site.payload_size,
|
|
6629
|
+
})),
|
|
5707
6630
|
states: snapshot.entries,
|
|
5708
6631
|
inputs: this.portMetadata(this.mir.interface.inputs, this.inputLayout),
|
|
5709
6632
|
outputs: this.portMetadata(this.mir.interface.outputs, this.outputLayout),
|
|
@@ -5772,20 +6695,43 @@ class MirCompiler {
|
|
|
5772
6695
|
payload_size_bytes: this.eventLayout[eventId].byteLength,
|
|
5773
6696
|
payload_min_size_bytes: this.eventLayout[eventId].minimumByteLength,
|
|
5774
6697
|
has_dynamic_payload: this.eventLayout[eventId].dynamic,
|
|
5775
|
-
params: event.params.map((param, paramId) =>
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
this.
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
6698
|
+
params: event.params.map((param, paramId) => {
|
|
6699
|
+
const shape = this.storageShape(param.ty);
|
|
6700
|
+
return {
|
|
6701
|
+
name: param.name,
|
|
6702
|
+
type_repr: typeName(this.type(param.ty), this),
|
|
6703
|
+
scalar: shape.scalar,
|
|
6704
|
+
array_len: shape.length ?? 0,
|
|
6705
|
+
is_array: shape.isArray === true && shape.isSlice !== true,
|
|
6706
|
+
is_slice: shape.isSlice === true,
|
|
6707
|
+
byte_offset: this.eventLayout[eventId][paramId].offset,
|
|
6708
|
+
byte_size: this.eventLayout[eventId][paramId].size,
|
|
6709
|
+
element_size_bytes: this.scalarSize(shape.scalar),
|
|
6710
|
+
has_default: param.default !== null && param.default !== undefined,
|
|
6711
|
+
default_reprs: this.constantReprs(param.default),
|
|
6712
|
+
};
|
|
6713
|
+
}),
|
|
6714
|
+
})),
|
|
6715
|
+
delegates: this.mir.interface.delegates.map((delegate, delegateId) => ({
|
|
6716
|
+
index: delegateId,
|
|
6717
|
+
name: delegate.name,
|
|
6718
|
+
payload_size_bytes: this.delegateLayout[delegateId].byteLength,
|
|
6719
|
+
payload_min_size_bytes: this.delegateLayout[delegateId].minimumByteLength,
|
|
6720
|
+
has_dynamic_payload: this.delegateLayout[delegateId].dynamic,
|
|
6721
|
+
params: delegate.params.map((param, paramId) => {
|
|
6722
|
+
const shape = this.storageShape(param.ty);
|
|
6723
|
+
return {
|
|
6724
|
+
name: param.name,
|
|
6725
|
+
type_repr: typeName(this.type(param.ty), this),
|
|
6726
|
+
scalar: shape.scalar,
|
|
6727
|
+
array_len: shape.length ?? 0,
|
|
6728
|
+
is_array: shape.isArray === true && shape.isSlice !== true,
|
|
6729
|
+
is_slice: shape.isSlice === true,
|
|
6730
|
+
byte_offset: this.delegateLayout[delegateId][paramId].offset,
|
|
6731
|
+
byte_size: this.delegateLayout[delegateId][paramId].size,
|
|
6732
|
+
element_size_bytes: this.scalarSize(shape.scalar),
|
|
6733
|
+
};
|
|
6734
|
+
}),
|
|
5789
6735
|
})),
|
|
5790
6736
|
},
|
|
5791
6737
|
};
|
|
@@ -5802,6 +6748,7 @@ class MirCompiler {
|
|
|
5802
6748
|
const layout = this.stateLayout[id];
|
|
5803
6749
|
entries.push({
|
|
5804
6750
|
name: slot.name,
|
|
6751
|
+
authored: slot.authored,
|
|
5805
6752
|
type_repr: typeName(this.type(slot.ty), this),
|
|
5806
6753
|
scalar: shape.scalar,
|
|
5807
6754
|
array_len: shape.length,
|
|
@@ -5809,6 +6756,19 @@ class MirCompiler {
|
|
|
5809
6756
|
packed_snapshot_byte_offset: byteOffset,
|
|
5810
6757
|
physical_state_byte_offset: layout.offset,
|
|
5811
6758
|
byte_size: layout.size,
|
|
6759
|
+
integer_range: slot.integer_range === undefined || slot.integer_range === null
|
|
6760
|
+
? null
|
|
6761
|
+
: {
|
|
6762
|
+
min: {
|
|
6763
|
+
type: slot.integer_range.min.type,
|
|
6764
|
+
value: String(slot.integer_range.min.value),
|
|
6765
|
+
},
|
|
6766
|
+
max: {
|
|
6767
|
+
type: slot.integer_range.max.type,
|
|
6768
|
+
value: String(slot.integer_range.max.value),
|
|
6769
|
+
},
|
|
6770
|
+
mode: slot.integer_range.mode,
|
|
6771
|
+
},
|
|
5812
6772
|
});
|
|
5813
6773
|
byteOffset += layout.size;
|
|
5814
6774
|
}
|