@scriptc/compiler 0.0.11 → 0.0.13
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/ambient/scriptc-node-fallback.d.ts +153 -24
- package/ambient/scriptc.d.ts +2 -2
- package/dist/backend/cc.d.ts +10 -2
- package/dist/backend/cc.js +12 -0
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-async.js +1 -1
- package/dist/backend/emission/emit-exprs.js +235 -64
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-island.js +1 -1
- package/dist/backend/emission/emit-shapes.js +1 -1
- package/dist/backend/emission/emit-walkers.d.ts +14 -14
- package/dist/backend/emission/emit-walkers.js +44 -44
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +3 -3
- package/dist/backend/emission/emitter.js +8 -8
- package/dist/backend/emission/may-throw.js +1 -1
- package/dist/backend/llvm/dyn.d.ts +10 -10
- package/dist/backend/llvm/dyn.js +26 -26
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +140 -49
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +1 -1
- package/dist/backend/llvm/walkers.js +2 -2
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +1 -1
- package/dist/diagnostics/diagnostic.js +4 -3
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/crypto-tables.d.ts +7 -0
- package/dist/frontend/lowering/crypto-tables.js +139 -0
- package/dist/frontend/lowering/crypto-tables.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.js +5 -5
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +12 -12
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +45 -27
- package/dist/frontend/lowering/lower-builtins.js +203 -70
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +4 -4
- package/dist/frontend/lowering/lower-calls.js +74 -66
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +41 -7
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +5 -5
- package/dist/frontend/lowering/lower-containers.js +19 -19
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.js +2 -2
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +7 -7
- package/dist/frontend/lowering/lower-exprs.js +227 -119
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +5 -5
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +12 -3
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +17 -17
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +11 -1
- package/dist/frontend/lowering/lower-namespaces.js +41 -6
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +21 -0
- package/dist/frontend/lowering/lower-server.js +278 -23
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
- package/dist/frontend/lowering/lower-stmts.js +195 -34
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +67 -23
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +31 -13
- package/dist/frontend/lowering/lowerer.js +99 -45
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +6 -0
- package/dist/frontend/lowering/surfaces.js +78 -2
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/program.js +1 -1
- package/dist/frontend/shared.js +7 -7
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +2 -2
- package/dist/frontend/types.js +27 -15
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.js +44 -8
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +208 -106
- package/dist/ir/nodes.js +100 -22
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +96 -38
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/int-infer.js +13 -0
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/profile.d.ts +8 -6
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar-validate.js +1 -1
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +1 -1
- package/dist/library/sidecar.js +20 -7
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +289 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals } from "../../ir/nodes.js";
|
|
1
|
+
import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, islandPromisePayloadTag, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals } from "../../ir/nodes.js";
|
|
2
2
|
import { boxAccess, BYTES_NUM_KIND_C, BYTES_NUM_VAR_C, bytesElemKindC, cDecl, cFnPtrCast, cNumberLiteral, cStringLiteral, cType, DV_GET_KIND_C, DV_SET_KIND_C, elemAccess, mapKeyAccess, mapKeyKindC, mapValKindC, retainCallC, vAdapters } from "./emit-types.js";
|
|
3
3
|
import { mangleClassNew, mangleClassRetain, mangleClassStruct, mangleField, mangleFnClosure, mangleFunction, mangleGlobal, mangleLocal, mangleRecordNew, mangleRecordStruct, mangleVtStruct } from "../mangle.js";
|
|
4
4
|
import { OVERFLOW_MEMBER } from "./emit-shapes.js";
|
|
@@ -190,7 +190,7 @@ export function emitExpr(E, e) {
|
|
|
190
190
|
return E.emitExpr(e.result);
|
|
191
191
|
}
|
|
192
192
|
case "dynDestrCheck": {
|
|
193
|
-
// RequireObjectCoercible with V8's destructuring TypeError.
|
|
193
|
+
// RequireObjectCoercible with V8's destructuring TypeError. dyn
|
|
194
194
|
// values check in the runtime helper and pass through unchanged
|
|
195
195
|
// (same temp, same ownership); island values check in the engine
|
|
196
196
|
// (a fresh +1 cell for the same value comes back).
|
|
@@ -207,7 +207,7 @@ export function emitExpr(E, e) {
|
|
|
207
207
|
}
|
|
208
208
|
case "dynIterN": {
|
|
209
209
|
// GetIterator + first-N steps as a fresh array (V8's exact
|
|
210
|
-
// not-iterable TypeError on non-iterables): the
|
|
210
|
+
// not-iterable TypeError on non-iterables): the dyn helper for
|
|
211
211
|
// dyn operands, the engine's real iterator protocol for island
|
|
212
212
|
// ones.
|
|
213
213
|
const v = E.emitExpr(e.value);
|
|
@@ -301,11 +301,11 @@ export function emitExpr(E, e) {
|
|
|
301
301
|
E.currentFrame().push({ name, type: e.type });
|
|
302
302
|
return { name, type: e.type };
|
|
303
303
|
}
|
|
304
|
-
// A dyn (
|
|
304
|
+
// A dyn (dyn) receiver — the `rawName?.match(re)` step: the nullish
|
|
305
305
|
// test reads the node's kind tag; the unit path is the undefined
|
|
306
|
-
//
|
|
306
|
+
// dyn singleton (dyn results) or nothing (void bodies), the body
|
|
307
307
|
// runs over the bound receiver otherwise (the validated dynamic
|
|
308
|
-
// dispatch, its result converted back into the
|
|
308
|
+
// dispatch, its result converted back into the checked-dynamic tree by the
|
|
309
309
|
// frontend's dynFrom wrap).
|
|
310
310
|
if (e.receiver.type.kind === "dyn") {
|
|
311
311
|
const r = E.emitExpr(e.receiver);
|
|
@@ -381,7 +381,7 @@ export function emitExpr(E, e) {
|
|
|
381
381
|
return { name: "", type: e.type };
|
|
382
382
|
}
|
|
383
383
|
// A dyn-typed chain (`pricing?.[key]` over an unknown-valued index
|
|
384
|
-
// signature): the unit path is the undefined
|
|
384
|
+
// signature): the unit path is the undefined dyn value — dyn
|
|
385
385
|
// represents undefined directly, no union wrapper exists.
|
|
386
386
|
if (e.type.kind === "dyn") {
|
|
387
387
|
const name = `sc_t${E.tempCounter++}`;
|
|
@@ -441,14 +441,25 @@ export function emitExpr(E, e) {
|
|
|
441
441
|
E.line(`${cDecl(e.type, name)};`);
|
|
442
442
|
E.line(`if (${E.unionTruthyHelper(e.left.type.unionId)}(${l.name})) {`);
|
|
443
443
|
E.indent++;
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
444
|
+
if (e.retag !== undefined) {
|
|
445
|
+
// The helper CONSUMES the left box (callees own their params), so
|
|
446
|
+
// no release on this side — the falsy side still owns and frees it.
|
|
447
|
+
// An unwind here produces the NULL dummy and never reaches the
|
|
448
|
+
// frame push below, so the slot needs no early registration.
|
|
449
|
+
E.line(`${name} = ${E.callTargetC(e.retag)}(${l.name});`);
|
|
450
|
+
if (E.mayThrow.has(e.retag))
|
|
451
|
+
E.emitPendingCheck();
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
const arm = e.type;
|
|
455
|
+
const read = arm.kind === "f64"
|
|
456
|
+
? `scr_union_get_f64(${l.name})`
|
|
457
|
+
: arm.kind === "bool"
|
|
458
|
+
? `scr_union_get_bool(${l.name})`
|
|
459
|
+
: retainCallC(arm, `(${cType(arm).trim()})scr_union_peek(${l.name})`);
|
|
460
|
+
E.line(`${name} = ${read};`);
|
|
461
|
+
E.releaseValue(l.name, e.left.type);
|
|
462
|
+
}
|
|
452
463
|
E.indent--;
|
|
453
464
|
E.line(`} else {`);
|
|
454
465
|
E.indent++;
|
|
@@ -578,7 +589,7 @@ export function emitExpr(E, e) {
|
|
|
578
589
|
return E.newTemp(e.type, `scr_caught_to_string(${v.name})`);
|
|
579
590
|
}
|
|
580
591
|
if (v.type.kind === "dyn") {
|
|
581
|
-
// String(unknown): dispatch over the
|
|
592
|
+
// String(unknown): dispatch over the dyn kind (dynToStrHelper —
|
|
582
593
|
// Node's String() incl. arrays-join and "[object Object]").
|
|
583
594
|
return E.newTemp(e.type, `${E.dynToStrHelper()}(${v.name})`);
|
|
584
595
|
}
|
|
@@ -1597,10 +1608,10 @@ export function emitExpr(E, e) {
|
|
|
1597
1608
|
return E.newTemp(e.type, `scr_map_keys_js_order(${obj.name}->${OVERFLOW_MEMBER})`);
|
|
1598
1609
|
}
|
|
1599
1610
|
case "dynFrom": {
|
|
1600
|
-
// Static value → fresh
|
|
1611
|
+
// Static value → fresh dyn tree (+1) through the interned per-type
|
|
1601
1612
|
// converter; the operand stays borrowed (frame-released as usual).
|
|
1602
1613
|
// Bare unit literals (an `undefined`/`null` stored under an
|
|
1603
|
-
// `unknown` index signature) are the
|
|
1614
|
+
// `unknown` index signature) are the dyn unit values directly.
|
|
1604
1615
|
if (e.value.kind === "unitLit") {
|
|
1605
1616
|
return E.newTemp(e.type, e.value.unit === "undefined"
|
|
1606
1617
|
? "scr_dyn_retain(scr_dyn_undefined())"
|
|
@@ -1608,7 +1619,7 @@ export function emitExpr(E, e) {
|
|
|
1608
1619
|
}
|
|
1609
1620
|
const v = E.emitExpr(e.value);
|
|
1610
1621
|
if (v.type.kind === "func") {
|
|
1611
|
-
// A closure boxes as the
|
|
1622
|
+
// A closure boxes as the checked-dynamic tree's function kind: retained closure +
|
|
1612
1623
|
// the per-signature call thunk + the interned signature key. The
|
|
1613
1624
|
// best-effort name rides along for inspect/error rendering (NULL
|
|
1614
1625
|
// when the lowering had none).
|
|
@@ -1620,8 +1631,8 @@ export function emitExpr(E, e) {
|
|
|
1620
1631
|
return E.newTemp(e.type, `${E.toDynHelper(v.type)}(${v.name})`);
|
|
1621
1632
|
}
|
|
1622
1633
|
case "dynFromJsval": {
|
|
1623
|
-
// Island value →
|
|
1624
|
-
// retains the cell in; engine scalars normalize to native
|
|
1634
|
+
// Island value → dyn: the by-reference wrap (scr_dyn_from_jsval
|
|
1635
|
+
// retains the cell in; engine scalars normalize to native dyn
|
|
1625
1636
|
// kinds at wrap time). Operand borrowed, result +1, never throws.
|
|
1626
1637
|
const v = E.emitExpr(e.value);
|
|
1627
1638
|
return E.newTemp(e.type, `scr_dyn_from_jsval(${v.name})`);
|
|
@@ -1635,11 +1646,11 @@ export function emitExpr(E, e) {
|
|
|
1635
1646
|
const callee = E.emitExpr(e.callee);
|
|
1636
1647
|
const what = cStringLiteral(Buffer.from(e.calleeName, "utf8"));
|
|
1637
1648
|
if (e.spreads !== undefined && e.spreads.length > 0) {
|
|
1638
|
-
// The RUNTIME-ARITY form (`f(...args)`): one fresh
|
|
1649
|
+
// The RUNTIME-ARITY form (`f(...args)`): one fresh dyn array
|
|
1639
1650
|
// collects the arguments left-to-right — plain args move in
|
|
1640
1651
|
// (push takes ownership), spread args FLATTEN (push_spread
|
|
1641
1652
|
// retains elements in and throws V8's spread-call TypeError for
|
|
1642
|
-
// non-iterable
|
|
1653
|
+
// non-iterable dyn kinds, checked per spread — JS's
|
|
1643
1654
|
// ArgumentListEvaluation order) — then apply calls through the
|
|
1644
1655
|
// array's elements (borrowed, exactly scr_dyn_call).
|
|
1645
1656
|
const spreadAt = new Map(e.spreads.map((s) => [s.arg, s.what]));
|
|
@@ -1685,7 +1696,7 @@ export function emitExpr(E, e) {
|
|
|
1685
1696
|
return E.fallibleTemp(e.type, `scr_dyn_invoke(${recv.name}, ${method}, ${argsExpr}, ${args.length}, ${what})`);
|
|
1686
1697
|
}
|
|
1687
1698
|
case "dynArrLit": {
|
|
1688
|
-
// A
|
|
1699
|
+
// A dyn array built element-by-element: ownership of each dyn
|
|
1689
1700
|
// element MOVES into the array (scr_dyn_arr_push's contract).
|
|
1690
1701
|
const arr = E.newTemp(e.type, "scr_dyn_new_arr()");
|
|
1691
1702
|
for (const el of e.elems) {
|
|
@@ -1696,7 +1707,7 @@ export function emitExpr(E, e) {
|
|
|
1696
1707
|
return arr;
|
|
1697
1708
|
}
|
|
1698
1709
|
case "dynObjLit": {
|
|
1699
|
-
// A
|
|
1710
|
+
// A dyn object built member-by-member: key then value, source
|
|
1700
1711
|
// order (JS's literal evaluation). scr_dyn_key_set BORROWS all
|
|
1701
1712
|
// three (the member retains the value in), so key/value temps
|
|
1702
1713
|
// release with the frame as usual; the receiver is a fresh OBJ,
|
|
@@ -1890,7 +1901,7 @@ export function emitExpr(E, e) {
|
|
|
1890
1901
|
return E.newTemp(e.type, `${u.name}->tag ${e.negated ? "!=" : "=="} ${e.tag}`);
|
|
1891
1902
|
}
|
|
1892
1903
|
case "dynKeyGet": {
|
|
1893
|
-
// Keyed read on the
|
|
1904
|
+
// Keyed read on the checked-dynamic tree through the one interned helper — the
|
|
1894
1905
|
// non-optional form throws JS's TypeError on an undefined/null
|
|
1895
1906
|
// receiver, and HANDLE receivers can throw the loud unmodeled-
|
|
1896
1907
|
// property ladder on EITHER form, so both ride a fallible temp;
|
|
@@ -1927,7 +1938,7 @@ export function emitExpr(E, e) {
|
|
|
1927
1938
|
const r = E.emitExpr(e.right);
|
|
1928
1939
|
const [d, s, st] = e.left.type.kind === "dyn" ? [l, r, e.right.type] : [r, l, e.left.type];
|
|
1929
1940
|
const test = st.kind === "dyn"
|
|
1930
|
-
? // dyn vs dyn: whole-
|
|
1941
|
+
? // dyn vs dyn: whole-dyn strict equality (scalars by value,
|
|
1931
1942
|
// units by kind, reference kinds by node identity).
|
|
1932
1943
|
`scr_dyn_strict_eq(${l.name}, ${r.name})`
|
|
1933
1944
|
: st.kind === "string"
|
|
@@ -1938,7 +1949,7 @@ export function emitExpr(E, e) {
|
|
|
1938
1949
|
return E.newTemp(e.type, e.negated ? `!${test}` : test);
|
|
1939
1950
|
}
|
|
1940
1951
|
case "dynTest": {
|
|
1941
|
-
// A pure kind compare on the
|
|
1952
|
+
// A pure kind compare on the dyn node — borrowed; only the truthy
|
|
1942
1953
|
// form also reads a scalar payload. ISLAND-held nodes (the jsval
|
|
1943
1954
|
// kind — engine objects/arrays/functions only, scalars normalize
|
|
1944
1955
|
// at wrap time) route the tests that depend on the engine's
|
|
@@ -1954,20 +1965,20 @@ export function emitExpr(E, e) {
|
|
|
1954
1965
|
// engine's own typeof.
|
|
1955
1966
|
`(${d.name}->kind == SCR_DYN_OBJ || ${d.name}->kind == SCR_DYN_ARR || ${d.name}->kind == SCR_DYN_BYTES || ${d.name}->kind == SCR_DYN_HANDLE || ${d.name}->kind == SCR_DYN_PROMISE || ${d.name}->kind == SCR_DYN_NULL || scr_dyn_isl_typeof_is(${d.name}, "object"))`
|
|
1956
1967
|
: e.test === "truthy"
|
|
1957
|
-
? // ToBoolean over the
|
|
1968
|
+
? // ToBoolean over the checked-dynamic tree: bool by value; number falsy for
|
|
1958
1969
|
// 0, -0 (== 0 in C), and NaN (self-inequality); string
|
|
1959
1970
|
// falsy when empty; obj/arr/bytes/func/handle always true;
|
|
1960
1971
|
// JSVAL through the runtime's routed arm (the bigint 0n
|
|
1961
1972
|
// edge); the remaining kinds (undefined, null) always false.
|
|
1962
1973
|
`(${d.name}->kind == SCR_DYN_BOOL ? ${d.name}->v.b : ${d.name}->kind == SCR_DYN_NUM ? (${d.name}->v.num == ${d.name}->v.num && ${d.name}->v.num != 0) : ${d.name}->kind == SCR_DYN_STR ? ${d.name}->v.str->len != 0 : ${d.name}->kind == SCR_DYN_JSVAL ? scr_dyn_truthy(${d.name}) : (${d.name}->kind == SCR_DYN_OBJ || ${d.name}->kind == SCR_DYN_ARR || ${d.name}->kind == SCR_DYN_BYTES || ${d.name}->kind == SCR_DYN_FUNC || ${d.name}->kind == SCR_DYN_HANDLE || ${d.name}->kind == SCR_DYN_PROMISE))`
|
|
1963
1974
|
: e.test === "error"
|
|
1964
|
-
? // `u instanceof Error`: the
|
|
1975
|
+
? // `u instanceof Error`: the checked-dynamic tree's error encoding — an
|
|
1965
1976
|
// object carrying the reserved "%error" marker key
|
|
1966
1977
|
// (built by caughtToDyn for Error payloads) — or a real
|
|
1967
1978
|
// engine Error held by reference.
|
|
1968
1979
|
`((${d.name}->kind == SCR_DYN_OBJ && scr_dyn_obj_get(${d.name}, "%error", 6) != NULL) || scr_dyn_isl_is_error(${d.name}))`
|
|
1969
1980
|
: e.test === "array"
|
|
1970
|
-
? // Array.isArray: the
|
|
1981
|
+
? // Array.isArray: the checked-dynamic tree's array kind, or the engine's
|
|
1971
1982
|
// own answer for an engine-held value.
|
|
1972
1983
|
`(${d.name}->kind == SCR_DYN_ARR || scr_dyn_isl_is_array(${d.name}))`
|
|
1973
1984
|
: e.test === "function"
|
|
@@ -2030,7 +2041,7 @@ export function emitExpr(E, e) {
|
|
|
2030
2041
|
throw new Error(`emitter bug: caughtNarrow to ${e.type.kind}`);
|
|
2031
2042
|
}
|
|
2032
2043
|
case "caughtToDyn": {
|
|
2033
|
-
// The caught snapshot converting to a dyn
|
|
2044
|
+
// The caught snapshot converting to a dyn value (an unknown
|
|
2034
2045
|
// slot) — the interned runtime-kind dispatch. Box borrowed; the
|
|
2035
2046
|
// result is a fresh tree (+1). Never throws.
|
|
2036
2047
|
const c = E.emitExpr(e.value);
|
|
@@ -2091,7 +2102,7 @@ export function emitExpr(E, e) {
|
|
|
2091
2102
|
const rc = vAdapters(t);
|
|
2092
2103
|
if (t.kind === "dyn") {
|
|
2093
2104
|
// The thrown-dyn representation (REF + dyn adapters): catch
|
|
2094
|
-
// bindings and the unhandled dispatch see the
|
|
2105
|
+
// bindings and the unhandled dispatch see the dyn value
|
|
2095
2106
|
// itself — identity preserved.
|
|
2096
2107
|
E.line(`scr_throw_ref(${reason.name}, &${rc.retain}, &${rc.release}, NULL);${E.srcComment(e.loc)}`);
|
|
2097
2108
|
}
|
|
@@ -2230,25 +2241,37 @@ export function emitExpr(E, e) {
|
|
|
2230
2241
|
// abandons (releases are NULL-tolerant).
|
|
2231
2242
|
return finish(`(scr_jsval_cast_fail(${arg(0)}, ${arg(1)}), NULL)`);
|
|
2232
2243
|
case "json.parse":
|
|
2233
|
-
// Borrows the text; returns +1 on a fresh
|
|
2244
|
+
// Borrows the text; returns +1 on a fresh dyn, or throws a
|
|
2234
2245
|
// catchable SyntaxError-shaped string (may-throw seed set).
|
|
2235
2246
|
return finish(`scr_json_parse(${arg(0)})`);
|
|
2236
2247
|
case "dyn.defineProps":
|
|
2237
|
-
// Object.defineProperties over
|
|
2248
|
+
// Object.defineProperties over dyn values: both borrowed,
|
|
2238
2249
|
// result the target (+1); throws catchably (may-throw seed).
|
|
2239
2250
|
return finish(`scr_dyn_define_props(${arg(0)}, ${arg(1)})`);
|
|
2251
|
+
case "dyn.hasKey":
|
|
2252
|
+
// `k in v` with a runtime key: the dyn presence answer (both
|
|
2253
|
+
// borrowed, no allocation, never throws).
|
|
2254
|
+
return finish(`scr_dyn_has_key(${arg(0)}, ${arg(1)})`);
|
|
2240
2255
|
case "dyn.keySet":
|
|
2241
2256
|
// Keyed write on a dyn receiver: all three borrowed (the
|
|
2242
2257
|
// member retains the value in); throws Node's TypeErrors on
|
|
2243
2258
|
// non-object receivers (may-throw seed set).
|
|
2244
2259
|
return finish(`scr_dyn_key_set(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
2245
2260
|
case "dyn.iterPack":
|
|
2246
|
-
// Destructuring pack over a dyn source: both borrowed,
|
|
2247
|
-
// array +1; throws V8's
|
|
2248
|
-
// non-iterable
|
|
2261
|
+
// Destructuring/for-of pack over a dyn source: both borrowed,
|
|
2262
|
+
// fresh array +1; throws V8's not-iterable TypeError on
|
|
2263
|
+
// non-iterable dyn kinds and drains wrapped engine values
|
|
2264
|
+
// through the engine's protocol (may-throw seed set).
|
|
2249
2265
|
return finish(`scr_dyn_iter_pack(${arg(0)}, ${arg(1)})`);
|
|
2266
|
+
case "dyn.arrLen":
|
|
2267
|
+
// The for-of pack's length (borrowed; never throws).
|
|
2268
|
+
return finish(`scr_dyn_arr_len(${arg(0)})`);
|
|
2269
|
+
case "dyn.arrAt":
|
|
2270
|
+
// The for-of pack's element at index (+1; never throws — the
|
|
2271
|
+
// undefined singleton past the end).
|
|
2272
|
+
return finish(`scr_dyn_arr_at(${arg(0)}, ${arg(1)})`);
|
|
2250
2273
|
case "dyn.typeof":
|
|
2251
|
-
// Bare typeof on a dyn value: the
|
|
2274
|
+
// Bare typeof on a dyn value: the dyn kind's JS answer (+1).
|
|
2252
2275
|
return finish(`scr_dyn_typeof(${arg(0)})`);
|
|
2253
2276
|
case "dyn.toString":
|
|
2254
2277
|
// Receiver-kind-dispatched toString (+1); throws Node's
|
|
@@ -2531,7 +2554,7 @@ export function emitExpr(E, e) {
|
|
|
2531
2554
|
// borrows, +1 result, never throws.
|
|
2532
2555
|
case "regexp.escape":
|
|
2533
2556
|
return finish(`scr_regexp_escape(${arg(0)})`);
|
|
2534
|
-
// The WHATWG base64 globals (scr_string.c):
|
|
2557
|
+
// The WHATWG base64 globals (scr_string.c): dyn arg borrowed
|
|
2535
2558
|
// (WebIDL ToString in the runtime), +1 string result; malformed
|
|
2536
2559
|
// input throws the catchable DOMException InvalidCharacterError
|
|
2537
2560
|
// (may-throw seed set). The zero-argument form always throws
|
|
@@ -3161,6 +3184,25 @@ export function emitExpr(E, e) {
|
|
|
3161
3184
|
case "net.sockDestroy":
|
|
3162
3185
|
E.line(`scr_net_sock_destroy(${arg(0)});${E.srcComment(e.loc)}`);
|
|
3163
3186
|
return { name: "", type: e.type };
|
|
3187
|
+
case "net.sockPause":
|
|
3188
|
+
return finish(`scr_net_sock_pause(${arg(0)})`);
|
|
3189
|
+
case "net.sockResume":
|
|
3190
|
+
return finish(`scr_net_sock_resume(${arg(0)})`);
|
|
3191
|
+
case "net.sockSetNoDelay":
|
|
3192
|
+
return finish(`scr_net_sock_set_nodelay(${arg(0)}, ${arg(1)})`);
|
|
3193
|
+
case "net.sockDestroySoon":
|
|
3194
|
+
E.line(`scr_net_sock_destroy_soon(${arg(0)});${E.srcComment(e.loc)}`);
|
|
3195
|
+
return { name: "", type: e.type };
|
|
3196
|
+
case "net.sockBytesWritten":
|
|
3197
|
+
return finish(`scr_net_sock_bytes_written(${arg(0)})`);
|
|
3198
|
+
case "net.sockReadable":
|
|
3199
|
+
return finish(`scr_net_sock_readable(${arg(0)})`);
|
|
3200
|
+
case "net.sockOnFinish": {
|
|
3201
|
+
const cb = args[1];
|
|
3202
|
+
E.moveTemp(cb);
|
|
3203
|
+
E.line(`scr_net_sock_on_finish(${arg(0)}, ${cb.name});${E.srcComment(e.loc)}`);
|
|
3204
|
+
return { name: "", type: e.type };
|
|
3205
|
+
}
|
|
3164
3206
|
case "net.sockPipe":
|
|
3165
3207
|
E.line(`scr_net_sock_pipe(${arg(0)}, ${arg(1)});${E.srcComment(e.loc)}`);
|
|
3166
3208
|
return { name: "", type: e.type };
|
|
@@ -3172,7 +3214,8 @@ export function emitExpr(E, e) {
|
|
|
3172
3214
|
E.moveTemp(cb);
|
|
3173
3215
|
const adapter = cbT.params.length === 0 ? "scr_net_data_thunk0"
|
|
3174
3216
|
: cbT.params[0].kind === "dyn" ? "scr_net_data_thunk_dyn"
|
|
3175
|
-
: "
|
|
3217
|
+
: cbT.params[0].kind === "string" ? "scr_net_data_thunk_str"
|
|
3218
|
+
: "scr_net_data_thunk_bytes";
|
|
3176
3219
|
E.line(`scr_net_sock_on_data(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${E.srcComment(e.loc)}`);
|
|
3177
3220
|
return { name: "", type: e.type };
|
|
3178
3221
|
}
|
|
@@ -3398,7 +3441,8 @@ export function emitExpr(E, e) {
|
|
|
3398
3441
|
E.moveTemp(cb);
|
|
3399
3442
|
const adapter = cbT.params.length === 0 ? "scr_net_data_thunk0"
|
|
3400
3443
|
: cbT.params[0].kind === "dyn" ? "scr_net_data_thunk_dyn"
|
|
3401
|
-
: "
|
|
3444
|
+
: cbT.params[0].kind === "string" ? "scr_net_data_thunk_str"
|
|
3445
|
+
: "scr_net_data_thunk_bytes";
|
|
3402
3446
|
E.line(`scr_http_req_on_data(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${E.srcComment(e.loc)}`);
|
|
3403
3447
|
return { name: "", type: e.type };
|
|
3404
3448
|
}
|
|
@@ -3718,6 +3762,25 @@ export function emitExpr(E, e) {
|
|
|
3718
3762
|
}
|
|
3719
3763
|
return finish(`scr_http_request(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${cbExpr}, ${adapter})`);
|
|
3720
3764
|
}
|
|
3765
|
+
case "http.agentNew":
|
|
3766
|
+
E.usesTimers = true; // queued dials hold the loop open
|
|
3767
|
+
return finish(`scr_http_agent_new(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)})`);
|
|
3768
|
+
case "http.requestAgent":
|
|
3769
|
+
case "http.requestAgentCb": {
|
|
3770
|
+
E.usesTimers = true;
|
|
3771
|
+
let cbExpr = "NULL";
|
|
3772
|
+
let adapter = "NULL";
|
|
3773
|
+
if (e.fn === "http.requestAgentCb") {
|
|
3774
|
+
const cbT = e.args[8].type;
|
|
3775
|
+
if (cbT.kind !== "func")
|
|
3776
|
+
throw new Error("emitter bug: http.requestAgentCb callback not a func");
|
|
3777
|
+
const cb = args[8];
|
|
3778
|
+
E.moveTemp(cb);
|
|
3779
|
+
cbExpr = cb.name;
|
|
3780
|
+
adapter = cbT.params.length === 0 ? "&scr_http_resp_thunk0" : "&scr_http_resp_thunk_res";
|
|
3781
|
+
}
|
|
3782
|
+
return finish(`scr_http_request_agent(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${cbExpr}, ${adapter})`);
|
|
3783
|
+
}
|
|
3721
3784
|
case "http.requestUrl":
|
|
3722
3785
|
case "http.requestUrlCb": {
|
|
3723
3786
|
E.usesTimers = true; // an in-flight request holds the loop open
|
|
@@ -3884,6 +3947,42 @@ export function emitExpr(E, e) {
|
|
|
3884
3947
|
// 'stream'/'session' listeners, exactly the h2c surface.
|
|
3885
3948
|
E.usesTimers = true;
|
|
3886
3949
|
return finish(`scr_http2_create_secure_server((const char *)${arg(0)}->data, ${arg(0)}->len, (const char *)${arg(1)}->data, ${arg(1)}->len)`);
|
|
3950
|
+
case "http2.createSecureServerReq":
|
|
3951
|
+
case "http2.createSecureServerH2Req": {
|
|
3952
|
+
// createSecureServer(options, handler): the eager COMPAT
|
|
3953
|
+
// handler is the first 'request' listener on either flavor
|
|
3954
|
+
// (the createServerReq adapter family).
|
|
3955
|
+
E.usesTimers = true;
|
|
3956
|
+
const cbT = e.args[2].type;
|
|
3957
|
+
if (cbT.kind !== "func")
|
|
3958
|
+
throw new Error(`emitter bug: ${e.fn} handler not a func`);
|
|
3959
|
+
const cb = args[2];
|
|
3960
|
+
E.moveTemp(cb);
|
|
3961
|
+
const adapter = cbT.params.length === 2 ? "scr_http_handler_thunk2"
|
|
3962
|
+
: cbT.params.length === 1 ? "scr_http_handler_thunk1"
|
|
3963
|
+
: "scr_http_handler_thunk0";
|
|
3964
|
+
const certKey = `(const char *)${arg(0)}->data, ${arg(0)}->len, (const char *)${arg(1)}->data, ${arg(1)}->len`;
|
|
3965
|
+
return finish(fn === "http2.createSecureServerReq"
|
|
3966
|
+
? `scr_https_create_server(${certKey}, ${cb.name}, &${adapter})`
|
|
3967
|
+
: `scr_http2_create_secure_server_req(${certKey}, ${cb.name}, &${adapter})`);
|
|
3968
|
+
}
|
|
3969
|
+
case "http2.createSecureServerDyn":
|
|
3970
|
+
// The runtime options record: allowHTTP1/cert/key read at
|
|
3971
|
+
// runtime (may-throw — the divergence-66 walk).
|
|
3972
|
+
E.usesTimers = true;
|
|
3973
|
+
return finish(`scr_http2_create_secure_server_dyn(${arg(0)}, NULL, NULL)`);
|
|
3974
|
+
case "http2.createSecureServerDynCb": {
|
|
3975
|
+
E.usesTimers = true;
|
|
3976
|
+
const cbT = e.args[1].type;
|
|
3977
|
+
if (cbT.kind !== "func")
|
|
3978
|
+
throw new Error("emitter bug: createSecureServerDynCb handler not a func");
|
|
3979
|
+
const cb = args[1];
|
|
3980
|
+
E.moveTemp(cb);
|
|
3981
|
+
const adapter = cbT.params.length === 2 ? "scr_http_handler_thunk2"
|
|
3982
|
+
: cbT.params.length === 1 ? "scr_http_handler_thunk1"
|
|
3983
|
+
: "scr_http_handler_thunk0";
|
|
3984
|
+
return finish(`scr_http2_create_secure_server_dyn(${arg(0)}, ${cb.name}, &${adapter})`);
|
|
3985
|
+
}
|
|
3887
3986
|
case "http2.createSecureServerSni": {
|
|
3888
3987
|
// The SNI form: the runtime parses each connection's
|
|
3889
3988
|
// ClientHello for server_name BEFORE the handshake, calls the
|
|
@@ -3934,6 +4033,15 @@ export function emitExpr(E, e) {
|
|
|
3934
4033
|
case "tls.caCertsChk":
|
|
3935
4034
|
// Always throws (validation error or the trailing fence).
|
|
3936
4035
|
return finish(`(scr_tls_ca_certs_chk(${arg(0)}, ${arg(1)}), ${isRefCounted(e.type) ? `(${cType(e.type).trim()})NULL` : "0"})`);
|
|
4036
|
+
// The CA-store introspection unit (scr_tls_ca.c): cached
|
|
4037
|
+
// per-type PEM string arrays (+1 retained answers), and the
|
|
4038
|
+
// default-set replacement. get/set are may-throw seeds.
|
|
4039
|
+
case "tlsca.get":
|
|
4040
|
+
return finish(`scr_tls_ca_get(${arg(0)})`);
|
|
4041
|
+
case "tlsca.root":
|
|
4042
|
+
return finish(`scr_tls_ca_root()`);
|
|
4043
|
+
case "tlsca.set":
|
|
4044
|
+
return finish(`scr_tls_ca_set_default(${arg(0)})`);
|
|
3937
4045
|
case "http.serverOnRequest": {
|
|
3938
4046
|
const cbT = e.args[1].type;
|
|
3939
4047
|
if (cbT.kind !== "func")
|
|
@@ -4166,7 +4274,8 @@ export function emitExpr(E, e) {
|
|
|
4166
4274
|
E.moveTemp(cb);
|
|
4167
4275
|
const adapter = cbT.params.length === 0 ? "scr_net_data_thunk0"
|
|
4168
4276
|
: cbT.params[0].kind === "dyn" ? "scr_net_data_thunk_dyn"
|
|
4169
|
-
: "
|
|
4277
|
+
: cbT.params[0].kind === "string" ? "scr_net_data_thunk_str"
|
|
4278
|
+
: "scr_net_data_thunk_bytes";
|
|
4170
4279
|
E.line(`scr_http2_stream_on_data(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${E.srcComment(e.loc)}`);
|
|
4171
4280
|
return { name: "", type: e.type };
|
|
4172
4281
|
}
|
|
@@ -4232,6 +4341,22 @@ export function emitExpr(E, e) {
|
|
|
4232
4341
|
}
|
|
4233
4342
|
return finish(`scr_https_request(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, (const char *)${arg(8)}->data, ${arg(8)}->len, ${cbExpr}, ${adapter})`);
|
|
4234
4343
|
}
|
|
4344
|
+
case "https.requestAgent":
|
|
4345
|
+
case "https.requestAgentCb": {
|
|
4346
|
+
E.usesTimers = true; // an in-flight request holds the loop open
|
|
4347
|
+
let cbExpr = "NULL";
|
|
4348
|
+
let adapter = "NULL";
|
|
4349
|
+
if (e.fn === "https.requestAgentCb") {
|
|
4350
|
+
const cbT = e.args[10].type;
|
|
4351
|
+
if (cbT.kind !== "func")
|
|
4352
|
+
throw new Error("emitter bug: https.requestAgentCb callback not a func");
|
|
4353
|
+
const cb = args[10];
|
|
4354
|
+
E.moveTemp(cb);
|
|
4355
|
+
cbExpr = cb.name;
|
|
4356
|
+
adapter = cbT.params.length === 0 ? "&scr_http_resp_thunk0" : "&scr_http_resp_thunk_res";
|
|
4357
|
+
}
|
|
4358
|
+
return finish(`scr_https_request_agent(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, (const char *)${arg(8)}->data, ${arg(8)}->len, ${arg(9)}, ${cbExpr}, ${adapter})`);
|
|
4359
|
+
}
|
|
4235
4360
|
case "https.requestFn":
|
|
4236
4361
|
case "https.requestFnCb": {
|
|
4237
4362
|
// The requestFn binding's runtime dial: arg 0 picks the client
|
|
@@ -4501,7 +4626,16 @@ export function emitExpr(E, e) {
|
|
|
4501
4626
|
case "process.onUnhandledRejection":
|
|
4502
4627
|
// The report at loop end dispatches the listeners.
|
|
4503
4628
|
E.usesTimers = true;
|
|
4504
|
-
return finish(`scr_process_on_unhandled_rejection(${arg(0)})`);
|
|
4629
|
+
return finish(`scr_process_on_unhandled_rejection(${arg(0)}, ${arg(1)})`);
|
|
4630
|
+
case "process.offUnhandledRejection":
|
|
4631
|
+
return finish(`scr_process_off_unhandled_rejection(${arg(0)})`);
|
|
4632
|
+
case "process.onRejectionHandled":
|
|
4633
|
+
// Fires (if ever) during the loop-end report's listener
|
|
4634
|
+
// dispatch — the loop must be live for the report to run.
|
|
4635
|
+
E.usesTimers = true;
|
|
4636
|
+
return finish(`scr_process_on_rejection_handled(${arg(0)}, ${arg(1)})`);
|
|
4637
|
+
case "process.offRejectionHandled":
|
|
4638
|
+
return finish(`scr_process_off_rejection_handled(${arg(0)})`);
|
|
4505
4639
|
case "fsp.readFile":
|
|
4506
4640
|
return finish(`scr_fsp_read_file(${arg(0)})`);
|
|
4507
4641
|
case "fsp.writeFile":
|
|
@@ -4797,7 +4931,7 @@ export function emitExpr(E, e) {
|
|
|
4797
4931
|
// Borrowed receiver; +1 "name: message" (Node's toString rules).
|
|
4798
4932
|
return finish(`scr_error_to_string(${arg(0)})`);
|
|
4799
4933
|
case "error.newDom":
|
|
4800
|
-
// new DOMException(message?, nameOrOptions?) — both
|
|
4934
|
+
// new DOMException(message?, nameOrOptions?) — both dyn args
|
|
4801
4935
|
// borrowed (WebIDL resolution runs in the runtime); +1
|
|
4802
4936
|
// %DOMException. Never throws.
|
|
4803
4937
|
return finish(`scr_domex_new(${arg(0)}, ${arg(1)})`);
|
|
@@ -4808,7 +4942,7 @@ export function emitExpr(E, e) {
|
|
|
4808
4942
|
// `'cause' in e` — the options form's own-property record.
|
|
4809
4943
|
return finish(`scr_domex_has_cause(${arg(0)})`);
|
|
4810
4944
|
case "error.domCause":
|
|
4811
|
-
// +1 cause
|
|
4945
|
+
// +1 cause dyn value (the dyn undefined when absent).
|
|
4812
4946
|
return finish(`scr_domex_cause(${arg(0)})`);
|
|
4813
4947
|
case "error.domClone":
|
|
4814
4948
|
// WebIDL serialization: name/message copy, code re-derives.
|
|
@@ -4818,7 +4952,7 @@ export function emitExpr(E, e) {
|
|
|
4818
4952
|
case "dyn.objKeys":
|
|
4819
4953
|
return finish(`scr_dyn_obj_keys(${arg(0)})`);
|
|
4820
4954
|
case "dyn.assign":
|
|
4821
|
-
// Object.assign over
|
|
4955
|
+
// Object.assign over dyn values: own members copy, the target
|
|
4822
4956
|
// returns (+1); non-object receivers throw like Node.
|
|
4823
4957
|
return finish(`scr_dyn_assign(${arg(0)}, ${arg(1)})`);
|
|
4824
4958
|
case "dyn.packPush":
|
|
@@ -4843,7 +4977,7 @@ export function emitExpr(E, e) {
|
|
|
4843
4977
|
// (+1). Never throws.
|
|
4844
4978
|
return finish(`scr_dyn_new_obj_null_proto()`);
|
|
4845
4979
|
case "dyn.hasOwn":
|
|
4846
|
-
// Object.hasOwn over a
|
|
4980
|
+
// Object.hasOwn over a dyn receiver (throws on nullish, like
|
|
4847
4981
|
// Node's ToObject).
|
|
4848
4982
|
return finish(`scr_dyn_has_own(${arg(0)}, ${arg(1)})`);
|
|
4849
4983
|
case "dyn.objValues":
|
|
@@ -4851,11 +4985,11 @@ export function emitExpr(E, e) {
|
|
|
4851
4985
|
case "dyn.objEntries":
|
|
4852
4986
|
return finish(`scr_dyn_obj_entries(${arg(0)})`);
|
|
4853
4987
|
case "dyn.errInstanceof":
|
|
4854
|
-
// The from_error cache resolves the
|
|
4988
|
+
// The from_error cache resolves the dyn value to its runtime
|
|
4855
4989
|
// error; the class's stamped interval answers. Never throws.
|
|
4856
4990
|
return finish(`scr_dyn_err_instanceof(${arg(0)}, ${arg(1)})`);
|
|
4857
4991
|
case "dyn.structuredClone":
|
|
4858
|
-
// Deep
|
|
4992
|
+
// Deep dyn clone (+1); option/DataClone/cycle errors throw
|
|
4859
4993
|
// (may-throw seed set). Both args borrowed.
|
|
4860
4994
|
return finish(`scr_structured_clone(${arg(0)}, ${arg(1)})`);
|
|
4861
4995
|
case "dyn.cloneMissing":
|
|
@@ -5410,7 +5544,7 @@ export function emitExpr(E, e) {
|
|
|
5410
5544
|
return finish(`scr_assert_eq_sym(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
|
|
5411
5545
|
case "assert.eqDyn":
|
|
5412
5546
|
// The quartet over checked-dynamic operands: SameValue /
|
|
5413
|
-
//
|
|
5547
|
+
// dyn-walk deep equality, assertion_error.js messages.
|
|
5414
5548
|
return finish(`scr_assert_eq_dyn(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
|
|
5415
5549
|
case "assert.deepResult":
|
|
5416
5550
|
return finish(`scr_assert_deep_result(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
|
|
@@ -5675,14 +5809,14 @@ export function emitExpr(E, e) {
|
|
|
5675
5809
|
}
|
|
5676
5810
|
case "jsonStringify": {
|
|
5677
5811
|
// Type-directed serialization: the STATIC type picks an emitted
|
|
5678
|
-
// serializer (interned per type) — no
|
|
5812
|
+
// serializer (interned per type) — no dyn, no runtime dispatch. The
|
|
5679
5813
|
// value temp is BORROWED (released with this statement's frame);
|
|
5680
5814
|
// the result string is owned (+1). Throws only over CYCLE-CAPABLE
|
|
5681
5815
|
// types (recursive records — the circular-structure TypeError) and
|
|
5682
5816
|
// dyn roots; everything else keeps the throw-free path.
|
|
5683
5817
|
const v = E.emitExpr(e.value);
|
|
5684
|
-
// A dyn root: the runtime's
|
|
5685
|
-
// serializer IS JSON.stringify over the
|
|
5818
|
+
// A dyn root: the runtime's dyn walker (scr_dyn_format_j — the %j
|
|
5819
|
+
// serializer IS JSON.stringify over the checked-dynamic tree: number/string/bool/
|
|
5686
5820
|
// null/array/object exact, dropped members omitted, a dropped ROOT
|
|
5687
5821
|
// becomes the text "undefined", a runtime handle inside the tree
|
|
5688
5822
|
// throws) — fallible, so the pending-exception check runs.
|
|
@@ -5714,7 +5848,7 @@ export function emitExpr(E, e) {
|
|
|
5714
5848
|
return E.newTemp(e.type, `${E.jsonIndentHelper()}(${compact.name}, ${cStringLiteral(bytes)}, ${bytes.length})`);
|
|
5715
5849
|
}
|
|
5716
5850
|
case "dynCheck": {
|
|
5717
|
-
// The dynamic boundary: validate the
|
|
5851
|
+
// The dynamic boundary: validate the checked-dynamic tree against the target type
|
|
5718
5852
|
// and BUILD the typed value (+1) — or throw a catchable
|
|
5719
5853
|
// TypeError-shaped, path-annotated string. The dyn temp is BORROWED;
|
|
5720
5854
|
// the result joins the frame BEFORE the pending check so an unwind
|
|
@@ -5866,7 +6000,7 @@ export function emitExpr(E, e) {
|
|
|
5866
6000
|
return { name: "", type: e.type };
|
|
5867
6001
|
}
|
|
5868
6002
|
case "dyn":
|
|
5869
|
-
// The
|
|
6003
|
+
// The checked-dynamic tree-crossing await: void fulfillments (a boxed
|
|
5870
6004
|
// promise<void> that skipped its adapter) answer the
|
|
5871
6005
|
// undefined VALUE, never NULL.
|
|
5872
6006
|
read = `scr_await_dyn(${pr.name})`;
|
|
@@ -6071,7 +6205,7 @@ export function emitExpr(E, e) {
|
|
|
6071
6205
|
case "string":
|
|
6072
6206
|
return E.newTemp(e.type, `scr_jsval_from_str(${v.name})`);
|
|
6073
6207
|
case "dyn":
|
|
6074
|
-
// A CHECKED-DYNAMIC (
|
|
6208
|
+
// A CHECKED-DYNAMIC (dyn) value entering the island: deep
|
|
6075
6209
|
// copy, data kinds only — boxed functions/handles/promises
|
|
6076
6210
|
// throw the catchable TypeError in the runtime.
|
|
6077
6211
|
return E.fallibleTemp(e.type, `scr_jsval_from_dyn(${v.name})`);
|
|
@@ -6082,6 +6216,20 @@ export function emitExpr(E, e) {
|
|
|
6082
6216
|
case "url":
|
|
6083
6217
|
// A URL crossing IN: an engine URL instance built from href.
|
|
6084
6218
|
return E.fallibleTemp(e.type, `scr_jsval_from_url(${v.name})`);
|
|
6219
|
+
case "promise": {
|
|
6220
|
+
// A STATIC promise crossing IN: a real engine thenable
|
|
6221
|
+
// settled when the scriptc promise settles (the async-
|
|
6222
|
+
// callback return bridge). from_promise takes ownership of a
|
|
6223
|
+
// +1 — retain past the borrowed frame temp.
|
|
6224
|
+
const tag = islandPromisePayloadTag(e.value.type.inner);
|
|
6225
|
+
if (!tag)
|
|
6226
|
+
throw new Error("emitter bug: jsMarshal of a promise outside the bridge payload domain");
|
|
6227
|
+
const tagC = {
|
|
6228
|
+
void: "SCR_ISLP_VOID", f64: "SCR_ISLP_F64", bool: "SCR_ISLP_BOOL",
|
|
6229
|
+
string: "SCR_ISLP_STR", jsval: "SCR_ISLP_JSVAL", jsvalArr: "SCR_ISLP_JSVAL_ARR",
|
|
6230
|
+
}[tag];
|
|
6231
|
+
return E.fallibleTemp(e.type, `scr_jsval_from_promise(scr_promise_retain(${v.name}), ${tagC})`);
|
|
6232
|
+
}
|
|
6085
6233
|
case "func": {
|
|
6086
6234
|
// A closure entering the island as a host function (the
|
|
6087
6235
|
// package-callback pattern). from_closure retains the closure;
|
|
@@ -6258,10 +6406,19 @@ export function emitExpr(E, e) {
|
|
|
6258
6406
|
// emits u8 targets (canExitIslandToType).
|
|
6259
6407
|
return E.fallibleTemp(e.type, `scr_jsval_exit_bytes(${v.name})`);
|
|
6260
6408
|
default: {
|
|
6409
|
+
// `any[]`-declared slot: the engine array exits Array.isArray-
|
|
6410
|
+
// gated, elements BY REFERENCE (identity crosses; the spine is
|
|
6411
|
+
// a snapshot copy). JSON-safe element types keep the round
|
|
6412
|
+
// trip below.
|
|
6413
|
+
if (e.type.kind === "array" && e.type.elem.kind === "jsval") {
|
|
6414
|
+
return E.fallibleTemp(e.type, `scr_jsval_exit_jsval_arr(${v.name})`);
|
|
6415
|
+
}
|
|
6261
6416
|
// An undefined-armed union target: the engine's undefined takes
|
|
6262
6417
|
// the undefined arm FIRST — JSON cannot spell it (to_json would
|
|
6263
6418
|
// refuse the exit) — then null and data ride the round trip
|
|
6264
|
-
// into the union's dynCheck like any composite
|
|
6419
|
+
// into the union's dynCheck like any composite (or, for the
|
|
6420
|
+
// `any[] | undefined` defaulted-parameter spelling, the
|
|
6421
|
+
// jsval-element array exit wrapped into the data arm).
|
|
6265
6422
|
const undefTag = e.type.kind === "union" ? E.undefinedArmTag(e.type) : -1;
|
|
6266
6423
|
if (e.type.kind === "union" && undefTag >= 0) {
|
|
6267
6424
|
const name = `sc_t${E.tempCounter++}`;
|
|
@@ -6273,11 +6430,23 @@ export function emitExpr(E, e) {
|
|
|
6273
6430
|
E.line(`} else {`);
|
|
6274
6431
|
E.indent++;
|
|
6275
6432
|
E.frames.push([]);
|
|
6276
|
-
const
|
|
6277
|
-
const
|
|
6278
|
-
const
|
|
6279
|
-
|
|
6280
|
-
|
|
6433
|
+
const unionDef = E.unionsById.get(e.type.unionId);
|
|
6434
|
+
const dataArms = unionDef ? unionDef.arms.flatMap((a, i) => (isUnitType(a) ? [] : [{ a, i }])) : [];
|
|
6435
|
+
const jsvalArr = dataArms.length === 1 && dataArms[0].a.kind === "array" && dataArms[0].a.elem.kind === "jsval" ? dataArms[0] : null;
|
|
6436
|
+
if (jsvalArr) {
|
|
6437
|
+
// The `any[] | undefined` defaulted-parameter spelling:
|
|
6438
|
+
// the engine array exits BY REFERENCE into the data arm.
|
|
6439
|
+
const arr = E.fallibleTemp(jsvalArr.a, `scr_jsval_exit_jsval_arr(${v.name})`);
|
|
6440
|
+
E.moveTemp(arr);
|
|
6441
|
+
E.line(`${name} = scr_union_new_ref(${jsvalArr.i}, ${arr.name}, &scr_arr_retain_v, &scr_arr_release_v, NULL);`);
|
|
6442
|
+
}
|
|
6443
|
+
else {
|
|
6444
|
+
const json = E.fallibleTemp(STRING, `scr_jsval_to_json(${v.name})`);
|
|
6445
|
+
const dom = E.fallibleTemp(DYN, `scr_json_parse(${json.name})`);
|
|
6446
|
+
const out = E.fallibleTemp(e.type, `${E.dynCheckHelper(e.type)}(${dom.name}, NULL)`);
|
|
6447
|
+
E.moveTemp(out);
|
|
6448
|
+
E.line(`${name} = ${out.name};`);
|
|
6449
|
+
}
|
|
6281
6450
|
E.releaseFrame(E.frames.pop());
|
|
6282
6451
|
E.indent--;
|
|
6283
6452
|
E.line(`}`);
|
|
@@ -6299,7 +6468,9 @@ export function emitExpr(E, e) {
|
|
|
6299
6468
|
const v = E.emitExpr(e.value);
|
|
6300
6469
|
const payload = e.type.kind === "promise" && e.type.inner.kind === "void"
|
|
6301
6470
|
? "SCR_ISLP_VOID"
|
|
6302
|
-
: "
|
|
6471
|
+
: e.type.kind === "promise" && e.type.inner.kind === "array" && e.type.inner.elem.kind === "jsval"
|
|
6472
|
+
? "SCR_ISLP_JSVAL_ARR" // `any[]` fulfillment: the Array.isArray-gated by-reference exit at settle
|
|
6473
|
+
: "SCR_ISLP_JSVAL";
|
|
6303
6474
|
return E.fallibleTemp(e.type, `scr_jsval_bridge_promise(${v.name}, ${payload})`);
|
|
6304
6475
|
}
|
|
6305
6476
|
default: {
|