@scriptc/compiler 0.0.11 → 0.0.12
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 +12 -9
- package/ambient/scriptc.d.ts +2 -2
- package/dist/backend/cc.d.ts +2 -2
- package/dist/backend/emission/emit-async.js +1 -1
- package/dist/backend/emission/emit-exprs.js +97 -52
- 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 +97 -43
- 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/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 +7 -7
- package/dist/frontend/lowering/lower-builtins.js +92 -31
- 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 +66 -66
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +31 -5
- 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 +158 -112
- 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 +16 -16
- 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.js +11 -11
- 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 +191 -30
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +66 -22
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +10 -10
- package/dist/frontend/lowering/lowerer.js +51 -37
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.js +2 -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 +15 -15
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.js +38 -7
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +110 -98
- package/dist/ir/nodes.js +48 -21
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +44 -34
- 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 +4 -4
|
@@ -184,11 +184,11 @@ leading?: readonly IrExpr[]): IrExpr[];
|
|
|
184
184
|
* `type` has no undefined arm to wrap into. */
|
|
185
185
|
export declare function wrappedUndefined(L: Lowerer, type: IrType, loc: SrcLoc): IrExpr | null;
|
|
186
186
|
/** The synthesized argument for an omitted omittable param: the interned
|
|
187
|
-
* undefined arm of the param's `T | undefined` ABI union, or the
|
|
187
|
+
* undefined arm of the param's `T | undefined` ABI union, or the checked-dynamic tree
|
|
188
188
|
* undefined for a checked-dynamic param (`bar?: any`). */
|
|
189
189
|
/** The "absent argument" value for a param SLOT type, or null when the
|
|
190
190
|
* slot cannot hold one: the interned undefined arm for undefined-armed
|
|
191
|
-
* unions, the
|
|
191
|
+
* unions, the dyn undefined for checked-dynamic slots, the engine's own
|
|
192
192
|
* undefined for island slots. Shared by every call-completion loop
|
|
193
193
|
* (direct calls and calls through func-typed values). */
|
|
194
194
|
export declare function omittedArgFor(L: Lowerer, type: IrType, loc: SrcLoc): IrExpr | null;
|
|
@@ -382,7 +382,7 @@ export declare function lowerCall(L: Lowerer, expr: ts.CallExpression): IrExpr;
|
|
|
382
382
|
* - CHECKED-DYNAMIC (dyn spread sources — a JS rest binding, a dyn
|
|
383
383
|
* value): box the callee (dynFrom; a dyn callee is already boxed),
|
|
384
384
|
* convert every argument into dyn, and emit the spread-marked dynCall
|
|
385
|
-
* — the emitters build one fresh
|
|
385
|
+
* — the emitters build one fresh dyn argument array (spreads flatten
|
|
386
386
|
* left-to-right, non-iterables throw V8's TypeError) and apply through
|
|
387
387
|
* it; the boxed thunk delivers JS arity exactly. Result dyn, checked
|
|
388
388
|
* per use like every any-origin value.
|
|
@@ -404,7 +404,7 @@ export declare function lowerSpreadArgsCall(L: Lowerer, expr: ts.CallExpression,
|
|
|
404
404
|
* slots keep completeArgs' same-element spread packing. */
|
|
405
405
|
export declare function spreadNeedsRuntimeArity(shapes: readonly ParamShape[], argNodes: readonly ts.Expression[]): boolean;
|
|
406
406
|
/** The SHARED prototype names scr_dyn_invoke dispatches at runtime (the
|
|
407
|
-
* subset of
|
|
407
|
+
* subset of DYN_PROTO_METHOD_NAMES with a receiver-kind dispatch): the
|
|
408
408
|
* runtime runs the real method for the receiver's kind, throws Node's
|
|
409
409
|
* is-not-a-function where the kind's prototype lacks the name, and
|
|
410
410
|
* fences LOUDLY on real-but-unimplemented pairs. */
|
|
@@ -85,7 +85,7 @@ export function paramShape(L, param) {
|
|
|
85
85
|
const raw = L.irTypeOf(param.name);
|
|
86
86
|
// A DYNAMIC-TIER pattern source (`function f({} = a)` with
|
|
87
87
|
// `a: any` — jsval for island values, dyn for the checked-dynamic
|
|
88
|
-
//
|
|
88
|
+
// dyn): the slot holds its tier's undefined DIRECTLY, so the ABI
|
|
89
89
|
// is the slot itself — no synthesized union; the prologue tests
|
|
90
90
|
// undefined at runtime (declareParams).
|
|
91
91
|
if (raw.kind === "dyn" || raw.kind === "jsval") {
|
|
@@ -103,7 +103,7 @@ export function paramShape(L, param) {
|
|
|
103
103
|
}
|
|
104
104
|
if (param.dotDotDotToken) {
|
|
105
105
|
// A JS rest param with no static element type (`(...args)` — any[]):
|
|
106
|
-
// the VARIADIC dyn form. The lifted function takes one trailing
|
|
106
|
+
// the VARIADIC dyn form. The lifted function takes one trailing dyn
|
|
107
107
|
// ARRAY param the dyn call thunk fills with the call's surplus
|
|
108
108
|
// arguments; the binding is that array (dynRest — funcType marks
|
|
109
109
|
// `rest`, and the value only ever calls through the boxed thunk).
|
|
@@ -133,7 +133,7 @@ export function paramShape(L, param) {
|
|
|
133
133
|
const raw = L.irTypeOf(param.name);
|
|
134
134
|
// A DYNAMIC-TIER defaulted param (`function f(x = a)` with `a: any`
|
|
135
135
|
// — tsc types x any; jsval for island values, dyn for the checked-
|
|
136
|
-
// dynamic
|
|
136
|
+
// dynamic dyn): the slot holds its tier's undefined directly, so
|
|
137
137
|
// the ABI is the slot itself and the prologue's default test is the
|
|
138
138
|
// runtime undefined test (declareParams).
|
|
139
139
|
if (raw.kind === "dyn" || raw.kind === "jsval") {
|
|
@@ -169,7 +169,7 @@ export function paramShape(L, param) {
|
|
|
169
169
|
if (param.questionToken && !L.bareUndefinedArmedUnion(type) && type.kind !== "dyn" && type.kind !== "jsval") {
|
|
170
170
|
// `x?: unknown` where unknown came from an annotation: undefined is
|
|
171
171
|
// absorbed into the hole type, so no undefined ARM exists — but a
|
|
172
|
-
// checked-dynamic slot holds the
|
|
172
|
+
// checked-dynamic slot holds the dyn undefined directly (`bar?: any`
|
|
173
173
|
// — an omitted call passes it, undefinedArgFor), and an island slot
|
|
174
174
|
// the engine's own undefined likewise (`options?: [string?]` — an
|
|
175
175
|
// optional-tuple param, jsval-mapped), so dyn and jsval params stay
|
|
@@ -243,7 +243,7 @@ leading) {
|
|
|
243
243
|
// A missing argument for a CHECKED-DYNAMIC param (an implicit-any
|
|
244
244
|
// JS signature called short — `mustCall(fn)` with `expected`
|
|
245
245
|
// omitted): JS fills undefined, and the dyn slot holds exactly
|
|
246
|
-
// that — the undefined
|
|
246
|
+
// that — the undefined dyn value. tsc's arity families don't gate
|
|
247
247
|
// .js builds (SEMANTICS.md 116), so the completion lands here.
|
|
248
248
|
if (shape.type.kind === "dyn") {
|
|
249
249
|
return { kind: "dynFrom", value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc }, type: DYN, loc };
|
|
@@ -271,7 +271,7 @@ leading) {
|
|
|
271
271
|
else if (restAt >= 0 && shapes[restAt].mode === "dynRest") {
|
|
272
272
|
// The VARIADIC dyn pack (a JS `...args` with no static element
|
|
273
273
|
// type, or the synthetic `arguments` slot): surplus arguments
|
|
274
|
-
// convert through the dyn boundary into one fresh
|
|
274
|
+
// convert through the dyn boundary into one fresh dyn array —
|
|
275
275
|
// exactly what the boxed call thunk builds for indirect calls.
|
|
276
276
|
const elems = sources.slice(restAt).map((a) => {
|
|
277
277
|
if (isIr(a))
|
|
@@ -384,11 +384,11 @@ export function wrappedUndefined(L, type, loc) {
|
|
|
384
384
|
return wrapped.kind === "unionWrap" ? wrapped : null;
|
|
385
385
|
}
|
|
386
386
|
/** The synthesized argument for an omitted omittable param: the interned
|
|
387
|
-
* undefined arm of the param's `T | undefined` ABI union, or the
|
|
387
|
+
* undefined arm of the param's `T | undefined` ABI union, or the checked-dynamic tree
|
|
388
388
|
* undefined for a checked-dynamic param (`bar?: any`). */
|
|
389
389
|
/** The "absent argument" value for a param SLOT type, or null when the
|
|
390
390
|
* slot cannot hold one: the interned undefined arm for undefined-armed
|
|
391
|
-
* unions, the
|
|
391
|
+
* unions, the dyn undefined for checked-dynamic slots, the engine's own
|
|
392
392
|
* undefined for island slots. Shared by every call-completion loop
|
|
393
393
|
* (direct calls and calls through func-typed values). */
|
|
394
394
|
export function omittedArgFor(L, type, loc) {
|
|
@@ -529,7 +529,7 @@ export function appendImplicitUndefinedReturn(L, body, bodyReturn, loc) {
|
|
|
529
529
|
// A DYN body that can complete without returning (a JS function whose
|
|
530
530
|
// guarded return may not run — mustSucceed's `if (typeof fn ===
|
|
531
531
|
// 'function') return fn.apply(...)`): JS completes with undefined —
|
|
532
|
-
// the undefined
|
|
532
|
+
// the undefined dyn value.
|
|
533
533
|
if (bodyReturn.kind === "dyn") {
|
|
534
534
|
body.push({
|
|
535
535
|
kind: "return",
|
|
@@ -584,7 +584,7 @@ export function declaredReturnType(L, decl, blame) {
|
|
|
584
584
|
// The RECORD twin (the tracing suite's traced closures — `function ()
|
|
585
585
|
// { return expectedResult; }` infers `{ foo: string }`): JS object
|
|
586
586
|
// literals are checked-dynamic VALUES, so a record-typed return would
|
|
587
|
-
// copy the
|
|
587
|
+
// copy the dyn value into a struct at the return and copy it back out
|
|
588
588
|
// at any dyn boundary — identity lost twice (found.result !==
|
|
589
589
|
// expectedResult where Node passes the object through). The inferred
|
|
590
590
|
// shape is inference, not a contract: the return stays checked-
|
|
@@ -1332,7 +1332,7 @@ function resolveInferredReturn(L, inst, infer, body, decl) {
|
|
|
1332
1332
|
distinct.push(e.stmt.value.type);
|
|
1333
1333
|
}
|
|
1334
1334
|
if (distinct.length === 0) {
|
|
1335
|
-
final = DYN; // no valued return: JS completes with undefined — the
|
|
1335
|
+
final = DYN; // no valued return: JS completes with undefined — the dyn undefined, today's slot
|
|
1336
1336
|
}
|
|
1337
1337
|
else if (distinct.length === 1) {
|
|
1338
1338
|
const t = distinct[0];
|
|
@@ -1459,7 +1459,7 @@ export function lowerGenericFnValue(L, ref, info) {
|
|
|
1459
1459
|
const inst = genericValueInstance(L, ref, info, bindings);
|
|
1460
1460
|
// The value's type is the completed ABI signature — exact-arity, the
|
|
1461
1461
|
// declared-function value rule (dynRest slots stay out of the param
|
|
1462
|
-
// list; the rest marker carries the trailing
|
|
1462
|
+
// list; the rest marker carries the trailing dyn-array ABI).
|
|
1463
1463
|
const funcType = {
|
|
1464
1464
|
kind: "func",
|
|
1465
1465
|
params: inst.params.filter((p) => p.mode !== "dynRest").map((p) => p.type),
|
|
@@ -2442,7 +2442,7 @@ export function lowerCall(L, expr) {
|
|
|
2442
2442
|
// non-format argument: strings VERBATIM, everything else through
|
|
2443
2443
|
// inspect at the rest-args depth 2 (formatWithOptions) — scalar
|
|
2444
2444
|
// kinds byte-exactly, boxed functions as [Function: name] /
|
|
2445
|
-
// [Function (anonymous)], composites through the dyn
|
|
2445
|
+
// [Function (anonymous)], composites through the dyn walk
|
|
2446
2446
|
// (insp.dyn). Never throws — Node's console.log never does.
|
|
2447
2447
|
if (lowered.type.kind === "dyn") {
|
|
2448
2448
|
return {
|
|
@@ -2551,10 +2551,10 @@ export function lowerCall(L, expr) {
|
|
|
2551
2551
|
}
|
|
2552
2552
|
return { kind: "libCall", fn: "timers.queueMicrotask", args: [adapted], type: VOID, loc };
|
|
2553
2553
|
}
|
|
2554
|
-
// structuredClone: the JSON-safe + bytes subset over the
|
|
2554
|
+
// structuredClone: the JSON-safe + bytes subset over the checked-dynamic tree, deep;
|
|
2555
2555
|
// %DOMException clones through WebIDL serialization (name/message,
|
|
2556
2556
|
// the code re-derives). Functions/handles throw the spec's catchable
|
|
2557
|
-
// DataCloneError; cycles fence (the
|
|
2557
|
+
// DataCloneError; cycles fence (the checked-dynamic tree cannot represent them — Node
|
|
2558
2558
|
// clones cycles, a documented divergence). Option validation throws
|
|
2559
2559
|
// Node's exact errors; the zero-argument call Node's
|
|
2560
2560
|
// ERR_MISSING_ARGS. Provenance-checked like setTimeout.
|
|
@@ -2580,7 +2580,7 @@ export function lowerCall(L, expr) {
|
|
|
2580
2580
|
const valueNode = expr.arguments[0];
|
|
2581
2581
|
// A NON-EMPTY transfer array of static values: nothing static is
|
|
2582
2582
|
// transferable, so the call is Node's DataCloneError — decided here
|
|
2583
|
-
// (the list's values need no
|
|
2583
|
+
// (the list's values need no dyn representation to fail). An EMPTY
|
|
2584
2584
|
// literal transfer list is a no-op member and drops.
|
|
2585
2585
|
{
|
|
2586
2586
|
let optNode = expr.arguments[1];
|
|
@@ -2611,8 +2611,8 @@ export function lowerCall(L, expr) {
|
|
|
2611
2611
|
const value = toDynArg(valueNode);
|
|
2612
2612
|
const cloned = { kind: "libCall", fn: "dyn.structuredClone", args: [value, optsArg], type: DYN, loc };
|
|
2613
2613
|
// The declared result is the value's own type (the generic's T):
|
|
2614
|
-
// validate the
|
|
2615
|
-
// dyn-typed and unmappable results stay
|
|
2614
|
+
// validate the dyn copy back into it when the type can be checked;
|
|
2615
|
+
// dyn-typed and unmappable results stay dyn values (JS files).
|
|
2616
2616
|
const resultT = L.mapTypeOf(L.typeOf(expr));
|
|
2617
2617
|
if (resultT !== null && resultT.kind !== "dyn" && resultT.kind !== "void" &&
|
|
2618
2618
|
canDynCheckTo(resultT, (id) => L.shapes.get(id), (id) => L.unions.get(id))) {
|
|
@@ -2718,7 +2718,7 @@ export function lowerCall(L, expr) {
|
|
|
2718
2718
|
if (ts.isPropertyAccessExpression(expr.expression) &&
|
|
2719
2719
|
L.isIslandExpr(expr.expression.expression)) {
|
|
2720
2720
|
const receiver = L.lowerExpr(expr.expression.expression);
|
|
2721
|
-
// A checker-`any` receiver whose VALUE lives in the
|
|
2721
|
+
// A checker-`any` receiver whose VALUE lives in the checked-dynamic tree (a
|
|
2722
2722
|
// checked-dynamic local behind the any-typed spelling — the JS
|
|
2723
2723
|
// WeakSet placeholder, rest-args arrays): the checked-dynamic
|
|
2724
2724
|
// method machinery owns it — receiver-kind dispatch, stored-member
|
|
@@ -2765,7 +2765,7 @@ export function lowerCall(L, expr) {
|
|
|
2765
2765
|
}
|
|
2766
2766
|
const callee = L.lowerExpr(expr.expression);
|
|
2767
2767
|
// A checker-`any` callee that LOWERED checked-dynamic (a dyn member
|
|
2768
|
-
// chain's stored function): the
|
|
2768
|
+
// chain's stored function): the checked-dynamic tree's own call — dynCall reads and
|
|
2769
2769
|
// calls the stored member with Node's is-not-a-function TypeError
|
|
2770
2770
|
// on refusal.
|
|
2771
2771
|
if (callee.type.kind === "dyn") {
|
|
@@ -3031,7 +3031,7 @@ export function lowerCall(L, expr) {
|
|
|
3031
3031
|
}
|
|
3032
3032
|
// STATIC atob/btoa (str.atob / str.btoa — scr_string.c; WHATWG
|
|
3033
3033
|
// forgiving-base64, Node is the oracle). The argument crosses as a
|
|
3034
|
-
//
|
|
3034
|
+
// dyn value: WebIDL ToString runs in the runtime over the dyn kind
|
|
3035
3035
|
// (Node's atob(null) decodes "null"), a malformed input throws the
|
|
3036
3036
|
// catchable DOMException InvalidCharacterError, and the
|
|
3037
3037
|
// zero-argument call throws Node's TypeError [ERR_MISSING_ARGS].
|
|
@@ -3524,7 +3524,7 @@ export function lowerCall(L, expr) {
|
|
|
3524
3524
|
if (callee.type.kind === "dyn") {
|
|
3525
3525
|
if (expr.arguments.some((a) => ts.isSpreadElement(a))) {
|
|
3526
3526
|
// The runtime-arity lane: a dyn callee is already boxed — the
|
|
3527
|
-
// spread-marked dynCall applies through a fresh
|
|
3527
|
+
// spread-marked dynCall applies through a fresh dyn argument
|
|
3528
3528
|
// array (lowerSpreadArgsCall). Sources outside it keep the fence.
|
|
3529
3529
|
const spreadServed = lowerSpreadArgsCall(L, expr, callee, loc);
|
|
3530
3530
|
if (spreadServed)
|
|
@@ -3604,7 +3604,7 @@ export function lowerCall(L, expr) {
|
|
|
3604
3604
|
// skip — not a shape this surface models; fence.
|
|
3605
3605
|
for (let i = args.length; i < params.length; i++) {
|
|
3606
3606
|
// A missing argument completes with the slot's absent value — the
|
|
3607
|
-
// interned undefined arm, the
|
|
3607
|
+
// interned undefined arm, the dyn undefined for checked-dynamic
|
|
3608
3608
|
// slots (a JS-inferred wrapper like mustCall's, called short), or
|
|
3609
3609
|
// the engine undefined for island slots.
|
|
3610
3610
|
const absent = omittedArgFor(L, params[i], loc);
|
|
@@ -3624,7 +3624,7 @@ export function lowerCall(L, expr) {
|
|
|
3624
3624
|
* - CHECKED-DYNAMIC (dyn spread sources — a JS rest binding, a dyn
|
|
3625
3625
|
* value): box the callee (dynFrom; a dyn callee is already boxed),
|
|
3626
3626
|
* convert every argument into dyn, and emit the spread-marked dynCall
|
|
3627
|
-
* — the emitters build one fresh
|
|
3627
|
+
* — the emitters build one fresh dyn argument array (spreads flatten
|
|
3628
3628
|
* left-to-right, non-iterables throw V8's TypeError) and apply through
|
|
3629
3629
|
* it; the boxed thunk delivers JS arity exactly. Result dyn, checked
|
|
3630
3630
|
* per use like every any-origin value.
|
|
@@ -3712,7 +3712,7 @@ export function spreadNeedsRuntimeArity(shapes, argNodes) {
|
|
|
3712
3712
|
}
|
|
3713
3713
|
/** METHOD calls on dyn receivers (`pkg.name.replace(...)`, `rawName.split`,
|
|
3714
3714
|
* `ws.packages.filter(...)` — JSON.parse-derived values): validate the
|
|
3715
|
-
* receiver's
|
|
3715
|
+
* receiver's dyn kind, extract, and ride the STATIC method machinery — the
|
|
3716
3716
|
* dyn boundary's trust-but-verify stance extended to receivers. The
|
|
3717
3717
|
* receiver-kind mismatch throws V8's own catchable TypeErrors (nullish:
|
|
3718
3718
|
* "Cannot read properties of undefined (reading 'replace')"; other kinds:
|
|
@@ -3720,14 +3720,14 @@ export function spreadNeedsRuntimeArity(shapes, argNodes) {
|
|
|
3720
3720
|
* evaluate, where JS evaluates them first for the non-nullish case
|
|
3721
3721
|
* (SEMANTICS.md). String methods ride the string/regex intrinsic tables
|
|
3722
3722
|
* through a validated-string receiver; `.filter` runs the predicate over
|
|
3723
|
-
* the
|
|
3723
|
+
* the dyn array and validated-extracts the survivors into the element type
|
|
3724
3724
|
* the checker committed the result to. Null when the receiver isn't a dyn
|
|
3725
3725
|
* value or the method isn't claimable (the method-call fence stays). */
|
|
3726
3726
|
function lowerDynReceiverMethodCall(L, call, access) {
|
|
3727
3727
|
if (L.chainBlocked(call, access))
|
|
3728
3728
|
return null;
|
|
3729
3729
|
// Only checker-untyped receivers: `any`/`unknown`, or the `any[]` an
|
|
3730
|
-
// Array.isArray guard narrows them to (the value is STILL the
|
|
3730
|
+
// Array.isArray guard narrows them to (the value is STILL the checked-dynamic tree
|
|
3731
3731
|
// array — scalar narrowings bridge through maybeNarrow's dynCheck and
|
|
3732
3732
|
// take the ordinary typed paths, but there is no static home for an
|
|
3733
3733
|
// any-elemented array). Typed receivers keep their own lowerings.
|
|
@@ -3759,7 +3759,7 @@ function lowerDynReceiverMethodCall(L, call, access) {
|
|
|
3759
3759
|
return null;
|
|
3760
3760
|
// Typed-destination filter first (validated extraction into a real
|
|
3761
3761
|
// T[]); an untyped destination falls through to the runtime dispatch
|
|
3762
|
-
// below (the survivors stay
|
|
3762
|
+
// below (the survivors stay dyn values).
|
|
3763
3763
|
if (access.name.text === "filter") {
|
|
3764
3764
|
const extracted = lowerDynArrayFilterCall(L, call, access, recv);
|
|
3765
3765
|
if (extracted)
|
|
@@ -3767,10 +3767,10 @@ function lowerDynReceiverMethodCall(L, call, access) {
|
|
|
3767
3767
|
}
|
|
3768
3768
|
if (access.name.text === "flatMap")
|
|
3769
3769
|
return lowerDynArrayFlatMapCall(L, call, access, recv);
|
|
3770
|
-
// String methods claim only names NO other
|
|
3770
|
+
// String methods claim only names NO other dyn-representable kind's
|
|
3771
3771
|
// prototype declares (Array carries includes/indexOf/slice too): for
|
|
3772
3772
|
// these, "the receiver is a string, or the call throws V8's TypeError"
|
|
3773
|
-
// IS Node's semantics for every possible
|
|
3773
|
+
// IS Node's semantics for every possible dyn value. Shared names would
|
|
3774
3774
|
// need a receiver-kind dispatch — they keep the fence.
|
|
3775
3775
|
if (DYN_STRING_ONLY_METHODS.has(access.name.text)) {
|
|
3776
3776
|
const checked = () => dynStringReceiver(L, recv, access);
|
|
@@ -3804,7 +3804,7 @@ function lowerDynReceiverMethodCall(L, call, access) {
|
|
|
3804
3804
|
}
|
|
3805
3805
|
// SHARED prototype names with a runtime dispatch (scr_dyn_invoke):
|
|
3806
3806
|
// push/slice/join/forEach/map/apply/... dispatch on the receiver's
|
|
3807
|
-
// RUNTIME kind — the honest answer for names more than one
|
|
3807
|
+
// RUNTIME kind — the honest answer for names more than one dyn-
|
|
3808
3808
|
// representable prototype declares (test/common's mustCall internals:
|
|
3809
3809
|
// mustCallChecks.push(context), failed.forEach(fn), fn.apply(this,
|
|
3810
3810
|
// args)). Implemented (kind, name) pairs run JS-exact; real-but-
|
|
@@ -3826,18 +3826,18 @@ function lowerDynReceiverMethodCall(L, call, access) {
|
|
|
3826
3826
|
loc: locOf(call),
|
|
3827
3827
|
};
|
|
3828
3828
|
}
|
|
3829
|
-
// Names NO
|
|
3829
|
+
// Names NO dyn-representable prototype declares: the member can only
|
|
3830
3830
|
// be an OWN property, so "read the member, call it" IS Node's
|
|
3831
|
-
// semantics for every possible
|
|
3831
|
+
// semantics for every possible dyn value — `handlers.onDone(x)` on a
|
|
3832
3832
|
// checked-dynamic object calls the stored function (dynKeyGet answers
|
|
3833
3833
|
// the member or undefined; dynCall throws Node's exact catchable
|
|
3834
3834
|
// "handlers.onDone is not a function" on a non-function). Prototype
|
|
3835
3835
|
// names (map/join/hasOwnProperty/call/...) keep the fence: on a real
|
|
3836
|
-
//
|
|
3836
|
+
// dyn array/string/object Node would run the METHOD, which no stored
|
|
3837
3837
|
// member models. Order note: JS reads the callee before evaluating
|
|
3838
3838
|
// arguments — dynKeyGet's undefined-receiver TypeError fires first,
|
|
3839
3839
|
// exactly Node.
|
|
3840
|
-
if (
|
|
3840
|
+
if (DYN_PROTO_METHOD_NAMES.has(access.name.text))
|
|
3841
3841
|
return null;
|
|
3842
3842
|
// Optional forms (`obj.cb?.()`, `obj?.cb()`) belong to the chain
|
|
3843
3843
|
// machinery's short-circuit semantics — not modeled here yet.
|
|
@@ -3857,12 +3857,12 @@ function lowerDynReceiverMethodCall(L, call, access) {
|
|
|
3857
3857
|
const args = call.arguments.map((a) => L.lowerExprExpecting(a, DYN));
|
|
3858
3858
|
return { kind: "dynCall", callee: member, calleeName: access.getText(), args, type: DYN, loc };
|
|
3859
3859
|
}
|
|
3860
|
-
/** Prototype method names of the
|
|
3860
|
+
/** Prototype method names of the checked-dynamic tree-representable kinds (String, Array,
|
|
3861
3861
|
* Object, Function, Number prototypes): a dyn receiver call on one of
|
|
3862
3862
|
* these could be a REAL method on a real value, which a stored-member
|
|
3863
3863
|
* read would silently mis-answer — they keep the fence. Everything else
|
|
3864
|
-
* is own-property-or-throw for every
|
|
3865
|
-
const
|
|
3864
|
+
* is own-property-or-throw for every dyn value (the honest dynCall). */
|
|
3865
|
+
const DYN_PROTO_METHOD_NAMES = new Set([
|
|
3866
3866
|
// Object.prototype
|
|
3867
3867
|
"hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf",
|
|
3868
3868
|
// Function.prototype
|
|
@@ -3877,7 +3877,7 @@ const DOM_PROTO_METHOD_NAMES = new Set([
|
|
|
3877
3877
|
"toExponential", "toFixed", "toPrecision",
|
|
3878
3878
|
]);
|
|
3879
3879
|
/** The SHARED prototype names scr_dyn_invoke dispatches at runtime (the
|
|
3880
|
-
* subset of
|
|
3880
|
+
* subset of DYN_PROTO_METHOD_NAMES with a receiver-kind dispatch): the
|
|
3881
3881
|
* runtime runs the real method for the receiver's kind, throws Node's
|
|
3882
3882
|
* is-not-a-function where the kind's prototype lacks the name, and
|
|
3883
3883
|
* fences LOUDLY on real-but-unimplemented pairs. */
|
|
@@ -3891,7 +3891,7 @@ export const DYN_DISPATCH_METHODS = new Set([
|
|
|
3891
3891
|
// the runtime kind so a boxed IncomingMessage/ServerResponse/Socket
|
|
3892
3892
|
// routes onto the same entry points the static lowerings use (modeled
|
|
3893
3893
|
// members) or the loud not-supported ladder (real-but-unmodeled ones).
|
|
3894
|
-
// On every other
|
|
3894
|
+
// On every other dyn kind they answer exactly what the stored-member
|
|
3895
3895
|
// path answered (OBJ own members call; the rest throw Node's
|
|
3896
3896
|
// is-not-a-function).
|
|
3897
3897
|
"on", "once", "addListener", "removeListener", "off", "removeAllListeners",
|
|
@@ -3906,11 +3906,11 @@ export const DYN_DISPATCH_METHODS = new Set([
|
|
|
3906
3906
|
// The netServer half of the handle surface (`let server; server =
|
|
3907
3907
|
// createServer(...)` — the handle lives in a dyn binding whose
|
|
3908
3908
|
// closures the checker cannot narrow): listen/close dispatch onto the
|
|
3909
|
-
// server ops; no other
|
|
3909
|
+
// server ops; no other dyn prototype declares either name, so the
|
|
3910
3910
|
// remainder keeps the stored-member answers.
|
|
3911
3911
|
"listen", "close",
|
|
3912
3912
|
// Promise.prototype (SCR_DYN_PROMISE receivers): the reaction trio
|
|
3913
|
-
// rides the fiber machinery (scr_dyn_promise_then); on every other
|
|
3913
|
+
// rides the fiber machinery (scr_dyn_promise_then); on every other dyn
|
|
3914
3914
|
// kind then/catch/finally answer the stored-member path (OBJ own
|
|
3915
3915
|
// members call, the rest throw Node's is-not-a-function).
|
|
3916
3916
|
"then", "catch", "finally",
|
|
@@ -3924,15 +3924,15 @@ export const DYN_DISPATCH_METHODS = new Set([
|
|
|
3924
3924
|
"additionalHeaders", "altsvc", "origin",
|
|
3925
3925
|
]);
|
|
3926
3926
|
/** STR_METHODS ∪ the regex-form names, MINUS everything Array (or any
|
|
3927
|
-
* other
|
|
3927
|
+
* other dyn kind's prototype) also declares. */
|
|
3928
3928
|
const DYN_STRING_ONLY_METHODS = new Set([
|
|
3929
3929
|
"charCodeAt", "charAt", "startsWith", "endsWith", "substring", "repeat",
|
|
3930
3930
|
"trim", "trimStart", "trimEnd", "split", "padStart", "padEnd",
|
|
3931
3931
|
"toLowerCase", "toUpperCase", "replace", "replaceAll", "match", "matchAll",
|
|
3932
3932
|
"search",
|
|
3933
3933
|
]);
|
|
3934
|
-
/** `Array.isArray(v)` — a real runtime test on `unknown` values (the
|
|
3935
|
-
* array kind:
|
|
3934
|
+
/** `Array.isArray(v)` — a real runtime test on `unknown` values (the checked-dynamic tree's
|
|
3935
|
+
* array kind: dyn arrays answer true, bytes/objects/scalars false — exactly
|
|
3936
3936
|
* JS, Uint8Array included), a compile-time constant on statically-typed
|
|
3937
3937
|
* ones (an `T[]` value IS an array, every other static kind is not; folded
|
|
3938
3938
|
* only over side-effect-free reads, the `in`-operator discipline; unions
|
|
@@ -4667,7 +4667,7 @@ export function lambdaSignature(L, node) {
|
|
|
4667
4667
|
// VARIADIC JS functions: a dynRest param (above), or a plain function
|
|
4668
4668
|
// whose body reads `arguments` (test/common's mustCall wrapper —
|
|
4669
4669
|
// `function() { ...; return fn.apply(this, arguments); }`). Both mark
|
|
4670
|
-
// the func type `rest`: the lifted body takes one trailing
|
|
4670
|
+
// the func type `rest`: the lifted body takes one trailing dyn-array
|
|
4671
4671
|
// param, filled by the boxed call thunk with the call's arguments
|
|
4672
4672
|
// from index params.length on. `arguments` is only claimed in
|
|
4673
4673
|
// ZERO-param functions (there it IS the surplus array); alongside
|
|
@@ -4687,7 +4687,7 @@ export function lambdaSignature(L, node) {
|
|
|
4687
4687
|
shapes,
|
|
4688
4688
|
funcType: {
|
|
4689
4689
|
kind: "func",
|
|
4690
|
-
// dynRest is EXCLUDED (the boxed thunk fills the trailing
|
|
4690
|
+
// dynRest is EXCLUDED (the boxed thunk fills the trailing dyn
|
|
4691
4691
|
// array — no spelled slot); islandRest is INCLUDED (the trailing
|
|
4692
4692
|
// jsval param IS the engine arguments array, the REST host-call
|
|
4693
4693
|
// adapter's one uniform shape).
|
|
@@ -4770,7 +4770,7 @@ export function lowerLambda(L, node) {
|
|
|
4770
4770
|
try {
|
|
4771
4771
|
const { params, prologue } = L.declareParams(node.parameters, shapes);
|
|
4772
4772
|
// The VARIADIC `arguments` form (rest-marked with no declared rest
|
|
4773
|
-
// param): a synthetic trailing
|
|
4773
|
+
// param): a synthetic trailing dyn-array param carries the call's
|
|
4774
4774
|
// arguments; `arguments` reads resolve to it (identifier lowering).
|
|
4775
4775
|
if (funcType.rest && !shapes.some((s) => s.mode === "dynRest" || s.mode === "islandRest")) {
|
|
4776
4776
|
const argsLocal = L.declareHiddenLocal("%arguments", DYN);
|
|
@@ -4875,7 +4875,7 @@ export function lowerLambda(L, node) {
|
|
|
4875
4875
|
const first = captured[0];
|
|
4876
4876
|
const pos = ts.getLineAndCharacterOfPosition(L.program.getSourceFile(first.loc.file) ?? node.getSourceFile(), first.loc.start);
|
|
4877
4877
|
const params = funcType.params.map((t, i) => ({ localId: `%pf${i}`, name: `%pf${i}`, type: t }));
|
|
4878
|
-
// A REST-MARKED value type hides one synthetic trailing
|
|
4878
|
+
// A REST-MARKED value type hides one synthetic trailing dyn-array
|
|
4879
4879
|
// param in the lifted function (the boxed call thunk fills it) —
|
|
4880
4880
|
// the fence lambda must spell that slot too or the validator's
|
|
4881
4881
|
// closure-signature check trips (SC9001). Island rest types SPELL
|
|
@@ -5102,7 +5102,7 @@ export function lowerPromiseMethodCall(L, call, access) {
|
|
|
5102
5102
|
// A TYPED handler on a DYN-settling promise (the tracePromise
|
|
5103
5103
|
// result's `.then((value) => ...)` — the checker's generic
|
|
5104
5104
|
// instantiation typed the parameter, but the settled value is a
|
|
5105
|
-
//
|
|
5105
|
+
// dyn value): box the handler and ride the dyn-handler desugar
|
|
5106
5106
|
// below — its call thunk validates the settled value into the
|
|
5107
5107
|
// declared parameter type (the per-arg dynCheck), Node's own
|
|
5108
5108
|
// runtime contract for a value that came off the wire untyped.
|
|
@@ -5114,10 +5114,10 @@ export function lowerPromiseMethodCall(L, call, access) {
|
|
|
5114
5114
|
}
|
|
5115
5115
|
// A CHECKED-DYNAMIC handler VALUE (`p.then(common.mustCall())` — the
|
|
5116
5116
|
// Node-suite wrapper is an untyped rest-args function): the same
|
|
5117
|
-
// async desugar with the handler called through the
|
|
5117
|
+
// async desugar with the handler called through the checked-dynamic tree — the
|
|
5118
5118
|
// settled value boxes (dyn passes through; void arrives as JS's
|
|
5119
5119
|
// explicit undefined argument), the result promise settles with the
|
|
5120
|
-
// handler's
|
|
5120
|
+
// handler's dyn result. A receiver rejection passes through the
|
|
5121
5121
|
// await like the typed path; the dyn call's own argument checking
|
|
5122
5122
|
// throws Node's TypeError for non-callables.
|
|
5123
5123
|
if (cb.type.kind === "dyn") {
|
|
@@ -5127,7 +5127,7 @@ export function lowerPromiseMethodCall(L, call, access) {
|
|
|
5127
5127
|
if (canConvertToDyn(v.type, (id) => L.shapes.get(id), (id) => L.unions.get(id))) {
|
|
5128
5128
|
return { kind: "dynFrom", value: v, type: DYN, loc };
|
|
5129
5129
|
}
|
|
5130
|
-
L.unsupported("SC1090", call.arguments[0], `then handlers receiving '${L.fmt(v.type)}' values through an untyped handler (the settled value cannot cross the
|
|
5130
|
+
L.unsupported("SC1090", call.arguments[0], `then handlers receiving '${L.fmt(v.type)}' values through an untyped handler (the settled value cannot cross the checked-dynamic tree boundary)`);
|
|
5131
5131
|
};
|
|
5132
5132
|
const resultT = { kind: "promise", inner: DYN };
|
|
5133
5133
|
const fnName = `%fn${L.lambdaCounter++}_then`;
|
|
@@ -5353,8 +5353,8 @@ export function lowerPromiseMethodCall(L, call, access) {
|
|
|
5353
5353
|
}
|
|
5354
5354
|
}
|
|
5355
5355
|
// .catch on a DYN-SETTLING promise (the tracePromise result's
|
|
5356
|
-
// `.catch((e) => ...)`): the rejection reason is a
|
|
5357
|
-
// handler runs through the
|
|
5356
|
+
// `.catch((e) => ...)`): the rejection reason is a dyn value, so the
|
|
5357
|
+
// handler runs through the checked-dynamic tree — a lifted async helper awaits the
|
|
5358
5358
|
// receiver, passes fulfillments through as dyn, and on rejection
|
|
5359
5359
|
// calls the boxed handler with caughtToDyn's identity-preserving
|
|
5360
5360
|
// snapshot (the dyn-then desugar's catch twin).
|
|
@@ -5540,7 +5540,7 @@ export function lowerPromiseMethodCall(L, call, access) {
|
|
|
5540
5540
|
else if (R.kind === "dyn") {
|
|
5541
5541
|
// A checked-dynamic result (the dyn-handler .then's promise-of-dyn
|
|
5542
5542
|
// chained into .catch): falling off the handler's end resolves
|
|
5543
|
-
// with the
|
|
5543
|
+
// with the dyn undefined.
|
|
5544
5544
|
catchBody.push({ kind: "return", value: dynUndefinedExpr(loc), loc });
|
|
5545
5545
|
}
|
|
5546
5546
|
else if (R.kind === "jsval") {
|
|
@@ -6272,7 +6272,7 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
6272
6272
|
// REAL prototype semantics: reads delegate LIVE, writes shadow,
|
|
6273
6273
|
// and inspect renders Node's exact shapes ("[Object: null
|
|
6274
6274
|
// prototype]" included). null and engine-held (jsval) prototypes
|
|
6275
|
-
// route; checked-dynamic (
|
|
6275
|
+
// route; checked-dynamic (dyn) prototypes keep the named fence —
|
|
6276
6276
|
// their marshal into the engine is a DEEP COPY, so a later
|
|
6277
6277
|
// prototype mutation would be invisible through the created
|
|
6278
6278
|
// object where Node delegates live.
|
|
@@ -6337,7 +6337,7 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
6337
6337
|
const tProbe = probeLower(L, call.arguments[0]);
|
|
6338
6338
|
const sProbe = probeLower(L, call.arguments[1]);
|
|
6339
6339
|
// CHECKED-DYNAMIC target and source (the JS file-scope
|
|
6340
|
-
// object-literal identity story): the runtime
|
|
6340
|
+
// object-literal identity story): the runtime dyn copy — own
|
|
6341
6341
|
// members of the source land on the target, which returns.
|
|
6342
6342
|
if (tProbe?.type.kind === "dyn") {
|
|
6343
6343
|
const loc = locOf(call);
|
|
@@ -6372,7 +6372,7 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
6372
6372
|
// `Object.assign(target, ...sources)` over a CHECKED-DYNAMIC target
|
|
6373
6373
|
// — the n-ary/spread form (`Object.assign({}, ...plugins.map(p =>
|
|
6374
6374
|
// p.options), coreOptions)`, support.js's option-table merge). The
|
|
6375
|
-
// sources pack into one fresh
|
|
6375
|
+
// sources pack into one fresh dyn array FIRST — plain sources
|
|
6376
6376
|
// retain in, spread sources flatten through the spread-call walk
|
|
6377
6377
|
// (V8's exact TypeError texts, the source spelling carried for the
|
|
6378
6378
|
// nullish form) — so every source evaluates and flattens before any
|
|
@@ -6384,7 +6384,7 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
6384
6384
|
// spread copies in at the boundary, the documented aliasing
|
|
6385
6385
|
// stance); anything else keeps the fence. Targets: dyn values, a
|
|
6386
6386
|
// FRESH object-literal target (`Object.assign({}, ...)` — no alias
|
|
6387
|
-
// exists, so building it as a
|
|
6387
|
+
// exists, so building it as a dyn object instead of a record is
|
|
6388
6388
|
// unobservable), or a nullish unit (Node's ToObject TypeError
|
|
6389
6389
|
// throws at the call, catchably); aliased record targets keep the
|
|
6390
6390
|
// fence — their identity could not survive the conversion.
|
|
@@ -6459,7 +6459,7 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
6459
6459
|
// Object.defineProperties over a CHECKED-DYNAMIC target (test/common's
|
|
6460
6460
|
// _mustCallInner copying name/length onto the mustCall wrapper): the
|
|
6461
6461
|
// runtime turns each descriptor's `value` into a plain own property on
|
|
6462
|
-
// the
|
|
6462
|
+
// the dyn node (OBJ members; FUNC nodes carry an own-property table) —
|
|
6463
6463
|
// flags accepted and ignored, accessors throw loudly (SEMANTICS.md).
|
|
6464
6464
|
// The result is the target, like JS. Typed targets keep the fence:
|
|
6465
6465
|
// static shapes have no property table to extend.
|
|
@@ -6522,7 +6522,7 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
6522
6522
|
const keyNode = call.arguments[1];
|
|
6523
6523
|
const probed = probeLower(L, recvNode);
|
|
6524
6524
|
// A CHECKED-DYNAMIC receiver (the JS file-scope object-literal
|
|
6525
|
-
// identity story): the runtime
|
|
6525
|
+
// identity story): the runtime dyn probe — OBJ member presence, ARR
|
|
6526
6526
|
// index bounds, Node's ToObject TypeError on nullish.
|
|
6527
6527
|
if (probed?.type.kind === "dyn") {
|
|
6528
6528
|
const loc = locOf(call);
|
|
@@ -6562,9 +6562,9 @@ function lowerObjectStaticCall(L, call, access) {
|
|
|
6562
6562
|
const argNode = call.arguments[0];
|
|
6563
6563
|
// A CHECKED-DYNAMIC argument — the checker may still spell a record
|
|
6564
6564
|
// type (the JS file-scope object-literal identity story stores the
|
|
6565
|
-
//
|
|
6566
|
-
// runtime walks the
|
|
6567
|
-
// JS's own-key order) and answers a
|
|
6565
|
+
// dyn object), so the LOWERED value's kind is the dispatch: the
|
|
6566
|
+
// runtime walks the dyn node's own keys (integer-like keys first,
|
|
6567
|
+
// JS's own-key order) and answers a dyn array.
|
|
6568
6568
|
{
|
|
6569
6569
|
const probed = probeLower(L, argNode);
|
|
6570
6570
|
const isDyn = probed?.type.kind === "dyn";
|
|
@@ -6786,7 +6786,7 @@ export function lowerFunction(L, decl) {
|
|
|
6786
6786
|
const { params, prologue } = L.declareParams(decl.parameters, sig.params);
|
|
6787
6787
|
// The synthetic `arguments` slot (a dynRest shape BEYOND the declared
|
|
6788
6788
|
// parameters — collectSignatureInner appended it): one trailing
|
|
6789
|
-
//
|
|
6789
|
+
// dyn-array param, resolved by `arguments` reads.
|
|
6790
6790
|
if (sig.params.length > decl.parameters.length && sig.params[sig.params.length - 1].mode === "dynRest") {
|
|
6791
6791
|
const argsLocal = L.declareHiddenLocal("%arguments", DYN);
|
|
6792
6792
|
params.push({ localId: argsLocal.id, name: "%arguments", type: DYN });
|