@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
|
@@ -98,7 +98,7 @@ export declare function hoistVarBinding(L: Lowerer, symbol: ts.Symbol, nameNode:
|
|
|
98
98
|
* such reads `undefined`, never a TDZ error, so the hoisted slot must
|
|
99
99
|
* hold `undefined` from function entry — which is only honest for
|
|
100
100
|
* undefined-armed union types (the interned arm) and checked-dynamic
|
|
101
|
-
* bindings (the
|
|
101
|
+
* bindings (the dyn undefined). Everything else returns false
|
|
102
102
|
* and the reference lands on the named fence in rejectUnresolvedSymbol:
|
|
103
103
|
* a slot of a narrower type has no bit pattern for the `undefined` Node
|
|
104
104
|
* would yield if the capture ran early, and guessing "it won't" is the
|
|
@@ -486,7 +486,7 @@ export function hoistVarBinding(L, symbol, nameNode) {
|
|
|
486
486
|
const local = { id: `${name}.${count}`, name, type, mutable: true };
|
|
487
487
|
L.ctx.locals.push(local);
|
|
488
488
|
L.ctx.scopes[0].set(symbol, local);
|
|
489
|
-
// A checked-dynamic slot holds the
|
|
489
|
+
// A checked-dynamic slot holds the dyn undefined (a NULL dyn is a
|
|
490
490
|
// trap); everything else rides unassignedSlotInit (interned union arm,
|
|
491
491
|
// engine undefined for jsval).
|
|
492
492
|
const wrapped = type.kind === "dyn" ? dynUndefinedExpr(locOf(nameNode)) : L.unassignedSlotInit(type, locOf(nameNode));
|
|
@@ -502,7 +502,7 @@ export function hoistVarBinding(L, symbol, nameNode) {
|
|
|
502
502
|
* such reads `undefined`, never a TDZ error, so the hoisted slot must
|
|
503
503
|
* hold `undefined` from function entry — which is only honest for
|
|
504
504
|
* undefined-armed union types (the interned arm) and checked-dynamic
|
|
505
|
-
* bindings (the
|
|
505
|
+
* bindings (the dyn undefined). Everything else returns false
|
|
506
506
|
* and the reference lands on the named fence in rejectUnresolvedSymbol:
|
|
507
507
|
* a slot of a narrower type has no bit pattern for the `undefined` Node
|
|
508
508
|
* would yield if the capture ran early, and guessing "it won't" is the
|
|
@@ -536,7 +536,7 @@ export function predeclareForwardVar(L, symbol) {
|
|
|
536
536
|
const ctx = owner.ctx;
|
|
537
537
|
// Only a slot that can hold `undefined` can carry the pre-
|
|
538
538
|
// initialization reads: an undefined-armed union (the interned arm),
|
|
539
|
-
// a checked-dynamic binding (the
|
|
539
|
+
// a checked-dynamic binding (the dyn undefined), or a jsval 'any'
|
|
540
540
|
// binding (the engine's undefined).
|
|
541
541
|
const type = varBindingType(L, nameNode);
|
|
542
542
|
if (!type)
|
|
@@ -757,7 +757,7 @@ export function lowerStmt(L, stmt) {
|
|
|
757
757
|
// A bare `return;` in a union-returning function yields undefined
|
|
758
758
|
// (JS), which the undefined arm carries — tsc only allows the bare
|
|
759
759
|
// form when the return type includes undefined/void. A CHECKED-
|
|
760
|
-
// DYNAMIC return slot holds the
|
|
760
|
+
// DYNAMIC return slot holds the dyn undefined directly (the
|
|
761
761
|
// appendImplicitUndefinedReturn rule). What remains is JS-only —
|
|
762
762
|
// a JSDoc return claim the body contradicts (ms's parse: `@return
|
|
763
763
|
// {Number}` with a bare early `return;`): no undefined fits the
|
|
@@ -819,11 +819,11 @@ export function lowerStmt(L, stmt) {
|
|
|
819
819
|
const value = L.lowerExpr(stmt.expression);
|
|
820
820
|
if (value.type.kind === "void")
|
|
821
821
|
L.badType(stmt.expression, L.typeOf(stmt.expression));
|
|
822
|
-
// A dyn throw rides the REF cell arm (scr_throw_ref over the
|
|
822
|
+
// A dyn throw rides the REF cell arm (scr_throw_ref over the checked-dynamic tree
|
|
823
823
|
// node — identity preserved through catch bindings, caughtToDyn
|
|
824
824
|
// passes it back by reference). The JS-lane traced-call shape:
|
|
825
|
-
// `throw err` where err arrived as a
|
|
826
|
-
// narrowing over the payload stays false (the
|
|
825
|
+
// `throw err` where err arrived as a dyn argument. instanceof
|
|
826
|
+
// narrowing over the payload stays false (the checked-dynamic tree's %error encoding
|
|
827
827
|
// is not a hierarchy object — SEMANTICS.md).
|
|
828
828
|
return { kind: "throw", value, loc: locOf(stmt) };
|
|
829
829
|
}
|
|
@@ -919,9 +919,9 @@ export function lowerVarStatement(L, stmt) {
|
|
|
919
919
|
}
|
|
920
920
|
// `const { NGHTTP2_CANCEL } = http2.constants` — a destructure over
|
|
921
921
|
// the baked constants table: alias plumbing, no storage (uses read
|
|
922
|
-
// their literals via
|
|
922
|
+
// their literals via builtinConstantBindingOf; collectGlobals skipped
|
|
923
923
|
// the globals by the same test).
|
|
924
|
-
if (L.
|
|
924
|
+
if (L.builtinConstantsDestructureDecl(decl.name, decl.initializer))
|
|
925
925
|
return [];
|
|
926
926
|
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
927
927
|
// `const { createSign } = crypto` over a builtin NAMESPACE binding:
|
|
@@ -1018,7 +1018,7 @@ export function lowerDestructuringDecl(L, decl, isLet) {
|
|
|
1018
1018
|
let init = L.lowerExpr(decl.initializer);
|
|
1019
1019
|
// A TS `any`-origin source whose lowered value is NOT a destructurable
|
|
1020
1020
|
// shape (`var { x } = <any>0` — the cast erases to the f64; a dyn
|
|
1021
|
-
// value — the
|
|
1021
|
+
// value — the checked-dynamic tree has no destructure): JS reads the properties off
|
|
1022
1022
|
// whatever the value is (a number answers undefined) — engine
|
|
1023
1023
|
// semantics, the dynamic-family fence. Record and array sources fall
|
|
1024
1024
|
// through to their lowerings, island handles to theirs (--dynamic
|
|
@@ -1276,16 +1276,16 @@ export function lowerBindingPattern(L, pattern, srcRef, srcType, isLet, out, dyn
|
|
|
1276
1276
|
L.lowerBindingPattern(pattern, () => ({ kind: "varRef", localId: chars.id, type: charsT, loc }), charsT, isLet, out);
|
|
1277
1277
|
return;
|
|
1278
1278
|
}
|
|
1279
|
-
// DYN sources (`const [a, b] = d` over a
|
|
1279
|
+
// DYN sources (`const [a, b] = d` over a dyn value, `([_, code]) =>`
|
|
1280
1280
|
// params destructuring dyn callback arguments — the suite harness's
|
|
1281
1281
|
// _expectWarning shapes): the source packs ONCE through the spread
|
|
1282
1282
|
// walk (dyn.iterPack — arrays element-by-element, strings by code
|
|
1283
1283
|
// point, bytes by byte; every other kind throws V8's destructuring
|
|
1284
1284
|
// TypeError, the compile-time spelling when the source has one),
|
|
1285
1285
|
// then positions bind the pack's index keys as dyn values — reads
|
|
1286
|
-
// past the end bind undefined, exactly JS. Defaults fire on the
|
|
1286
|
+
// past the end bind undefined, exactly JS. Defaults fire on the checked-dynamic tree
|
|
1287
1287
|
// undefined (JS's rule); rest elements keep the fence (surplus
|
|
1288
|
-
// packing over the
|
|
1288
|
+
// packing over the checked-dynamic tree needs a slice the IR does not spell yet).
|
|
1289
1289
|
if (srcType.kind === "dyn") {
|
|
1290
1290
|
const loc = locOf(pattern);
|
|
1291
1291
|
const pack = L.declareHiddenLocal("%dpack", DYN);
|
|
@@ -1316,14 +1316,14 @@ export function lowerBindingPattern(L, pattern, srcRef, srcType, isLet, out, dyn
|
|
|
1316
1316
|
loc: elLoc,
|
|
1317
1317
|
};
|
|
1318
1318
|
if (el.initializer) {
|
|
1319
|
-
// The default fires exactly on the
|
|
1320
|
-
// its value converting into the
|
|
1319
|
+
// The default fires exactly on the dyn undefined (JS's rule),
|
|
1320
|
+
// its value converting into the checked-dynamic tree like any dyn-slot value.
|
|
1321
1321
|
const rl = L.declareHiddenLocal("%delem", DYN);
|
|
1322
1322
|
out.push({ kind: "varDecl", localId: rl.id, init: value, loc: elLoc });
|
|
1323
1323
|
const ref = () => ({ kind: "varRef", localId: rl.id, type: DYN, loc: elLoc });
|
|
1324
1324
|
const dflt = L.coerceToExpected(L.lowerExpr(el.initializer), DYN);
|
|
1325
1325
|
if (dflt.type.kind !== "dyn") {
|
|
1326
|
-
L.unsupported("SC1031", el.initializer, `defaults of '${L.fmt(dflt.type)}' type over checked-dynamic sources (the value cannot convert into the
|
|
1326
|
+
L.unsupported("SC1031", el.initializer, `defaults of '${L.fmt(dflt.type)}' type over checked-dynamic sources (the value cannot convert into the checked-dynamic tree)`);
|
|
1327
1327
|
}
|
|
1328
1328
|
value = {
|
|
1329
1329
|
kind: "ternary",
|
|
@@ -2537,7 +2537,7 @@ export function bindPatternTarget(L, name, value, isLet, out) {
|
|
|
2537
2537
|
// a pattern binding whose VALUE lowered checked-dynamic stays dyn
|
|
2538
2538
|
// where the checker spells an island-world type (`function f({
|
|
2539
2539
|
// plugins = [] } = {})` over a JSDoc '(string | object)[]=' member —
|
|
2540
|
-
// the read is a
|
|
2540
|
+
// the read is a dyn keyed read whose members may be wrapped island
|
|
2541
2541
|
// values) or a type with no mapping at all (the varDecl rule's
|
|
2542
2542
|
// unmappable-declared-type stance, `string | object` bindings
|
|
2543
2543
|
// included). Marshaling here would fence or deep-copy; the value's
|
|
@@ -2702,9 +2702,9 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2702
2702
|
return null;
|
|
2703
2703
|
// `const { NGHTTP2_CANCEL } = http2.constants` — a destructure over
|
|
2704
2704
|
// the baked constants table: alias plumbing, no storage (uses read
|
|
2705
|
-
// their literals via
|
|
2705
|
+
// their literals via builtinConstantBindingOf; collectGlobals skipped
|
|
2706
2706
|
// the globals by the same test).
|
|
2707
|
-
if (L.
|
|
2707
|
+
if (L.builtinConstantsDestructureDecl(decl.name, decl.initializer))
|
|
2708
2708
|
return null;
|
|
2709
2709
|
// `const Writable = stream.Writable` — a stream class through the
|
|
2710
2710
|
// namespace binding: alias plumbing, no storage (uses resolve through
|
|
@@ -2790,7 +2790,7 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2790
2790
|
// a loop — must NOT reset the persisting binding.
|
|
2791
2791
|
if (isVarDeclared(decl))
|
|
2792
2792
|
return null;
|
|
2793
|
-
// Checked-dynamic globals hold the
|
|
2793
|
+
// Checked-dynamic globals hold the dyn undefined from their
|
|
2794
2794
|
// declaration statement on; unions and jsval ride
|
|
2795
2795
|
// unassignedSlotInit's arms.
|
|
2796
2796
|
const wrapped = g.type.kind === "dyn" ? dynUndefinedExpr(locOf(decl)) : L.unassignedSlotInit(g.type, locOf(decl));
|
|
@@ -2845,7 +2845,7 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2845
2845
|
const local = L.declareLocal(decl.name, decl.name.text, type, isLet);
|
|
2846
2846
|
// tsc's definite-assignment analysis never guards `any` reads, so
|
|
2847
2847
|
// uninitialized bindings must hold their world's undefined, never
|
|
2848
|
-
// NULL: unions the interned arm, dyn the
|
|
2848
|
+
// NULL: unions the interned arm, dyn the dyn undefined, jsval the
|
|
2849
2849
|
// engine's — all readable immediately, exactly Node.
|
|
2850
2850
|
const init = type.kind === "dyn" ? dynUndefinedExpr(locOf(decl)) : L.unassignedSlotInit(type, locOf(decl));
|
|
2851
2851
|
return { kind: "varDecl", localId: local.id, init, loc: locOf(decl) };
|
|
@@ -2869,7 +2869,7 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2869
2869
|
}
|
|
2870
2870
|
// A dyn initializer under an unmappable declared type (`const ws =
|
|
2871
2871
|
// pkg.workspaces` — the lowering world types the unknown-receiver read
|
|
2872
|
-
// `any`, which a static build cannot hold): the VALUE is a
|
|
2872
|
+
// `any`, which a static build cannot hold): the VALUE is a dyn
|
|
2873
2873
|
// subtree, so the local stays dyn — later narrowing tests and checked
|
|
2874
2874
|
// casts read it like any JSON.parse result.
|
|
2875
2875
|
// `const p = import("./m")` / `const ns = await import("./m")`: the
|
|
@@ -2894,7 +2894,7 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2894
2894
|
// the island-HANDLE local rule's mirror): a binding whose
|
|
2895
2895
|
// INITIALIZER lowered checked-dynamic stays dyn even where the
|
|
2896
2896
|
// checker spells 'any' (`const parsers = options.parsers ?? {}` over
|
|
2897
|
-
// an 'object'-typed bag — the read is a
|
|
2897
|
+
// an 'object'-typed bag — the read is a dyn keyed read). Marshaling
|
|
2898
2898
|
// into the engine here would deep-copy data and sever aliasing; the
|
|
2899
2899
|
// value's world is the honest dispatch, and every use site already
|
|
2900
2900
|
// handles dyn (validated exits, routed engine ops for wrapped
|
|
@@ -2921,7 +2921,7 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
2921
2921
|
// pushes of anything non-numeric would fence and typed exits would
|
|
2922
2922
|
// mismatch the checker's evolved reads downstream. The binding is
|
|
2923
2923
|
// checked-dynamic instead (the `let x = {}` stance, and lower-modules'
|
|
2924
|
-
// file-scope evolving-array rule): pushes ride the
|
|
2924
|
+
// file-scope evolving-array rule): pushes ride the dyn array, typed
|
|
2925
2925
|
// exits dynCheck.
|
|
2926
2926
|
if ((type === null || type.kind === "array") && isJsSourceFile(decl.getSourceFile())) {
|
|
2927
2927
|
let initExpr = decl.initializer;
|
|
@@ -3000,6 +3000,15 @@ export function lowerVarDecl(L, decl, isLet) {
|
|
|
3000
3000
|
// bridge is an independent observer of the same settlement).
|
|
3001
3001
|
if (init.type.kind === "jsval" && type.kind === "promise")
|
|
3002
3002
|
type = JSVAL;
|
|
3003
|
+
// An island value under an `any[]`-declared LOCAL spelling stays an
|
|
3004
|
+
// island HANDLE too (the runtime-world rule): the jsval-element-array
|
|
3005
|
+
// exit is a CALL-boundary conversion (the loadPlugins param ABI) —
|
|
3006
|
+
// converting a local would strand the engine's own prototypes
|
|
3007
|
+
// (join/map/... on a native handle-element array), where the handle
|
|
3008
|
+
// routes every use engine-side.
|
|
3009
|
+
if (init.type.kind === "jsval" && type.kind === "array" && type.elem.kind === "jsval") {
|
|
3010
|
+
type = JSVAL;
|
|
3011
|
+
}
|
|
3003
3012
|
// A STATIC array of island HANDLES under an unannotated declared type
|
|
3004
3013
|
// spelling evolved elements (`const kept = fns.filter(...)` over an
|
|
3005
3014
|
// evolving-`any` receiver — the handle-element lowering keeps the
|
|
@@ -3847,7 +3856,7 @@ export function lowerExprStatement(L, expr) {
|
|
|
3847
3856
|
const loc = locOf(expr);
|
|
3848
3857
|
// Dispatch follows the RUNTIME world (383(d)): a checker-'any'
|
|
3849
3858
|
// receiver whose value LOWERED checked-dynamic (`bag.nested.x
|
|
3850
|
-
// = v` behind an 'object'-typed bag) takes the
|
|
3859
|
+
// = v` behind an 'object'-typed bag) takes the dyn keyed
|
|
3851
3860
|
// write — the routed JSVAL arm lands it on the real engine
|
|
3852
3861
|
// object.
|
|
3853
3862
|
if (obj.type.kind === "dyn") {
|
|
@@ -3944,7 +3953,7 @@ export function lowerExprStatement(L, expr) {
|
|
|
3944
3953
|
}
|
|
3945
3954
|
// `h.onDone = cb` on a CHECKED-DYNAMIC receiver (a JS `let h =
|
|
3946
3955
|
// {}` evolving object, an implicit-any param, a dyn member
|
|
3947
|
-
// chain): the
|
|
3956
|
+
// chain): the dyn keyed write — the value converts INTO dyn
|
|
3948
3957
|
// (closures box), the runtime sets the member on OBJ receivers
|
|
3949
3958
|
// and throws Node's TypeErrors on the rest. The receiver is
|
|
3950
3959
|
// PROBED (probeLower) and claimed exactly when it lowers to
|
|
@@ -3964,7 +3973,7 @@ export function lowerExprStatement(L, expr) {
|
|
|
3964
3973
|
}
|
|
3965
3974
|
// `events.defaultMaxListeners = v` in STATEMENT position — the
|
|
3966
3975
|
// module-property write Node validates (the lowerBinary
|
|
3967
|
-
// expression twin): the value crosses into the
|
|
3976
|
+
// expression twin): the value crosses into the checked-dynamic tree, the runtime
|
|
3968
3977
|
// ladder throws Node's exact errors, valid numbers apply.
|
|
3969
3978
|
if (!expr.left.questionDotToken && expr.left.name.text === "defaultMaxListeners") {
|
|
3970
3979
|
const bi = L.builtinMemberOf(expr.left);
|
|
@@ -4268,7 +4277,7 @@ function lowerCompoundToTarget(L, expr, compound, target) {
|
|
|
4268
4277
|
isJsSourceFile(expr.getSourceFile())) {
|
|
4269
4278
|
// JS any-origin operands: check to number and compute natively
|
|
4270
4279
|
// (the binary-operator stance) — the dyn target takes the result
|
|
4271
|
-
// back through the usual
|
|
4280
|
+
// back through the usual dyn conversion.
|
|
4272
4281
|
const checkNum = (e) => e.type.kind === "dyn" ? { kind: "dynCheck", value: e, type: F64, loc: e.loc } : e;
|
|
4273
4282
|
const computed = { kind: "bin", op: compound, left: checkNum(read), right: checkNum(rhs), type: F64, loc };
|
|
4274
4283
|
value = target.type.kind === "dyn" ? { kind: "dynFrom", value: computed, type: DYN, loc } : computed;
|
|
@@ -5100,7 +5109,7 @@ function destructAssignPiece(L, prop, islandSource) {
|
|
|
5100
5109
|
// keys resolve statically (the record path's rule) — the keyed read
|
|
5101
5110
|
// below takes the folded name. A RUNTIME-valued key over an ISLAND
|
|
5102
5111
|
// source reads through the engine's own indexing at the element's
|
|
5103
|
-
// pattern position (`({ [key]: w } = src)`); over the
|
|
5112
|
+
// pattern position (`({ [key]: w } = src)`); over the checked-dynamic tree the fence
|
|
5104
5113
|
// stays.
|
|
5105
5114
|
const folded = patternKeyNameOf(L, prop.name);
|
|
5106
5115
|
if (folded === null) {
|
|
@@ -5550,12 +5559,12 @@ export function lowerForOf(L, stmt) {
|
|
|
5550
5559
|
if (iterable.type.kind === "jsval") {
|
|
5551
5560
|
return lowerForOfIsland(L, stmt, iterable, labels);
|
|
5552
5561
|
}
|
|
5553
|
-
// A CHECKED-DYNAMIC iterable (`unknown[]
|
|
5554
|
-
// `(string | object)[]
|
|
5555
|
-
//
|
|
5556
|
-
//
|
|
5562
|
+
// A CHECKED-DYNAMIC iterable (`unknown[]`, the collapsed
|
|
5563
|
+
// `(string | object)[]`, JSON-parsed values, wrapped engine
|
|
5564
|
+
// values): the source packs ONCE through the spread walk and a
|
|
5565
|
+
// hidden index loop binds each element as a dyn value.
|
|
5557
5566
|
if (iterable.type.kind === "dyn") {
|
|
5558
|
-
L
|
|
5567
|
+
return lowerForOfDyn(L, stmt, iterable, labels);
|
|
5559
5568
|
}
|
|
5560
5569
|
if (iterable.type.kind !== "array") {
|
|
5561
5570
|
L.badType(stmt.expression, L.typeOf(stmt.expression));
|
|
@@ -5928,6 +5937,158 @@ function lowerForOfClassIterator(L, stmt, iterable, cit, labels) {
|
|
|
5928
5937
|
* (break/return out of a partial iteration calling it.return()) is NOT
|
|
5929
5938
|
* run — a divergence only a custom island iterator with a return()
|
|
5930
5939
|
* method can observe. */
|
|
5940
|
+
/** For-of over a CHECKED-DYNAMIC iterable: the source packs ONCE
|
|
5941
|
+
* through the spread walk (dyn.iterPack — dyn arrays element-by-
|
|
5942
|
+
* element, strings by code point, bytes by byte; a WRAPPED engine
|
|
5943
|
+
* value drains through the ENGINE's own iterator protocol via the
|
|
5944
|
+
* iter_drain arm; every other kind throws V8's not-iterable
|
|
5945
|
+
* TypeError, the identifier spelling when the head has one), then a
|
|
5946
|
+
* hidden index loop binds each element as a dyn value. The pack is an
|
|
5947
|
+
* eager SNAPSHOT (the matchAll stance): body mutations of a dyn-array
|
|
5948
|
+
* source don't extend the iteration where JS's live array iterator
|
|
5949
|
+
* would — documented divergence; engine sources drain through their
|
|
5950
|
+
* own protocol, so generators/Maps/Sets step exactly once like Node. */
|
|
5951
|
+
function lowerForOfDyn(L, stmt, iterable, labels) {
|
|
5952
|
+
const loc = locOf(stmt);
|
|
5953
|
+
const head = stmt.expression;
|
|
5954
|
+
// V8's for-of CallPrinter spellings: named sources (identifiers and
|
|
5955
|
+
// plain property chains) read "<src> is not iterable", call heads
|
|
5956
|
+
// with a nameable callee "<callee> is not a function or its return
|
|
5957
|
+
// value is not iterable"; everything else keeps the runtime kind
|
|
5958
|
+
// wording. The runtime uses the spelling VERBATIM when non-empty.
|
|
5959
|
+
const headText = (e) => {
|
|
5960
|
+
if (ts.isIdentifier(e))
|
|
5961
|
+
return e.text;
|
|
5962
|
+
if (ts.isPropertyAccessExpression(e) && !e.questionDotToken && ts.isIdentifier(e.name)) {
|
|
5963
|
+
const base = headText(e.expression);
|
|
5964
|
+
return base !== null ? `${base}.${e.name.text}` : null;
|
|
5965
|
+
}
|
|
5966
|
+
return null;
|
|
5967
|
+
};
|
|
5968
|
+
const headName = headText(head);
|
|
5969
|
+
const calleeName = ts.isCallExpression(head) ? headText(head.expression) : null;
|
|
5970
|
+
const spell = headName !== null
|
|
5971
|
+
? `${headName} is not iterable`
|
|
5972
|
+
: calleeName !== null
|
|
5973
|
+
? `${calleeName} is not a function or its return value is not iterable`
|
|
5974
|
+
: "";
|
|
5975
|
+
const pack = L.declareHiddenLocal("%dofpack", DYN);
|
|
5976
|
+
const idx = L.declareHiddenLocal("%dofi", F64);
|
|
5977
|
+
idx.mutable = true;
|
|
5978
|
+
const packRef = () => ({ kind: "varRef", localId: pack.id, type: DYN, loc });
|
|
5979
|
+
const iRef = () => ({ kind: "varRef", localId: idx.id, type: F64, loc });
|
|
5980
|
+
const elemInit = () => ({ kind: "libCall", fn: "dyn.arrAt", args: [packRef(), iRef()], type: DYN, loc });
|
|
5981
|
+
L.scopes.push(new Map());
|
|
5982
|
+
try {
|
|
5983
|
+
const binds = [];
|
|
5984
|
+
if (!ts.isVariableDeclarationList(stmt.initializer)) {
|
|
5985
|
+
// Pre-declared heads: identifier targets assign the existing
|
|
5986
|
+
// binding once per pass (JS's shared-binding rule); literal
|
|
5987
|
+
// patterns run the destructuring-assignment machinery over the
|
|
5988
|
+
// dyn element; member targets keep the fence.
|
|
5989
|
+
let target = stmt.initializer;
|
|
5990
|
+
while (ts.isParenthesizedExpression(target))
|
|
5991
|
+
target = target.expression;
|
|
5992
|
+
const tmp = L.declareHiddenLocal("%vof", DYN);
|
|
5993
|
+
binds.push({ kind: "varDecl", localId: tmp.id, init: elemInit(), loc });
|
|
5994
|
+
const elemRef = { kind: "varRef", localId: tmp.id, type: DYN, loc };
|
|
5995
|
+
if (ts.isArrayLiteralExpression(target) || ts.isObjectLiteralExpression(target)) {
|
|
5996
|
+
binds.push(lowerDestructuringAssign(L, target, elemRef, target, loc));
|
|
5997
|
+
}
|
|
5998
|
+
else if (ts.isIdentifier(target) && L.resolveWritable(target)) {
|
|
5999
|
+
const writable = L.resolveWritable(target);
|
|
6000
|
+
binds.push({
|
|
6001
|
+
kind: "assign",
|
|
6002
|
+
localId: writable.id,
|
|
6003
|
+
value: L.coerceInto(target, elemRef, writable.type),
|
|
6004
|
+
loc,
|
|
6005
|
+
});
|
|
6006
|
+
}
|
|
6007
|
+
else {
|
|
6008
|
+
L.unsupported("SC1090", stmt.initializer, "for-of over a pre-declared variable (declare the loop variable in the loop: for (const x of ...))");
|
|
6009
|
+
}
|
|
6010
|
+
}
|
|
6011
|
+
else {
|
|
6012
|
+
const list = stmt.initializer;
|
|
6013
|
+
if ((list.flags & ts.NodeFlags.Using) !== 0) {
|
|
6014
|
+
L.unsupported("SC1090", list, "'using' declarations (dispose-at-scope-exit semantics)");
|
|
6015
|
+
}
|
|
6016
|
+
const isLet = (list.flags & ts.NodeFlags.Let) !== 0 || (list.flags & ts.NodeFlags.BlockScoped) === 0;
|
|
6017
|
+
const decl = list.declarations[0];
|
|
6018
|
+
if (ts.isArrayBindingPattern(decl.name) || ts.isObjectBindingPattern(decl.name)) {
|
|
6019
|
+
const tmp = L.declareHiddenLocal("%destr", DYN);
|
|
6020
|
+
binds.push({ kind: "varDecl", localId: tmp.id, init: elemInit(), loc });
|
|
6021
|
+
L.lowerBindingPattern(decl.name, () => ({ kind: "varRef", localId: tmp.id, type: DYN, loc }), DYN, isLet, binds);
|
|
6022
|
+
}
|
|
6023
|
+
else if (ts.isIdentifier(decl.name)) {
|
|
6024
|
+
const varTarget = forOfVarTarget(L, decl);
|
|
6025
|
+
if (varTarget) {
|
|
6026
|
+
// `for (var x of d)`: the element mechanics stay on a hidden
|
|
6027
|
+
// per-iteration local; the body opens by assigning the ONE
|
|
6028
|
+
// hoisted var binding (the array head's rule).
|
|
6029
|
+
const tmp = L.declareHiddenLocal("%vof", DYN);
|
|
6030
|
+
binds.push({ kind: "varDecl", localId: tmp.id, init: elemInit(), loc });
|
|
6031
|
+
binds.push({
|
|
6032
|
+
kind: "assign",
|
|
6033
|
+
localId: varTarget.id,
|
|
6034
|
+
value: L.coerceInto(decl.name, { kind: "varRef", localId: tmp.id, type: DYN, loc }, varTarget.type),
|
|
6035
|
+
loc,
|
|
6036
|
+
});
|
|
6037
|
+
}
|
|
6038
|
+
else {
|
|
6039
|
+
const local = L.declareLocal(decl.name, decl.name.text, DYN, isLet);
|
|
6040
|
+
binds.push({ kind: "varDecl", localId: local.id, init: elemInit(), loc });
|
|
6041
|
+
}
|
|
6042
|
+
}
|
|
6043
|
+
else {
|
|
6044
|
+
L.unsupported("SC1031", decl.name);
|
|
6045
|
+
}
|
|
6046
|
+
}
|
|
6047
|
+
const body = L.inCtl("loop", () => L.lowerScopedBlock(stmt.statement), labels);
|
|
6048
|
+
return {
|
|
6049
|
+
kind: "block",
|
|
6050
|
+
body: [
|
|
6051
|
+
{
|
|
6052
|
+
kind: "varDecl",
|
|
6053
|
+
localId: pack.id,
|
|
6054
|
+
init: {
|
|
6055
|
+
kind: "libCall",
|
|
6056
|
+
fn: "dyn.iterPack",
|
|
6057
|
+
args: [iterable, { kind: "strLit", value: spell, type: STRING, loc }],
|
|
6058
|
+
type: DYN,
|
|
6059
|
+
loc,
|
|
6060
|
+
},
|
|
6061
|
+
loc,
|
|
6062
|
+
},
|
|
6063
|
+
{
|
|
6064
|
+
kind: "for",
|
|
6065
|
+
init: { kind: "varDecl", localId: idx.id, init: { kind: "numLit", value: 0, type: F64, loc }, loc },
|
|
6066
|
+
cond: {
|
|
6067
|
+
kind: "bin",
|
|
6068
|
+
op: "<",
|
|
6069
|
+
left: iRef(),
|
|
6070
|
+
right: { kind: "libCall", fn: "dyn.arrLen", args: [packRef()], type: F64, loc },
|
|
6071
|
+
type: BOOL,
|
|
6072
|
+
loc,
|
|
6073
|
+
},
|
|
6074
|
+
update: {
|
|
6075
|
+
kind: "assign",
|
|
6076
|
+
localId: idx.id,
|
|
6077
|
+
value: { kind: "bin", op: "+", left: iRef(), right: { kind: "numLit", value: 1, type: F64, loc }, type: F64, loc },
|
|
6078
|
+
loc,
|
|
6079
|
+
},
|
|
6080
|
+
body: [...binds, ...body],
|
|
6081
|
+
...(labels && { labels }),
|
|
6082
|
+
loc,
|
|
6083
|
+
},
|
|
6084
|
+
],
|
|
6085
|
+
loc,
|
|
6086
|
+
};
|
|
6087
|
+
}
|
|
6088
|
+
finally {
|
|
6089
|
+
L.scopes.pop();
|
|
6090
|
+
}
|
|
6091
|
+
}
|
|
5931
6092
|
function lowerForOfIsland(L, stmt, iterable, labels) {
|
|
5932
6093
|
const loc = locOf(stmt);
|
|
5933
6094
|
if (!ts.isVariableDeclarationList(stmt.initializer)) {
|