@scriptc/compiler 0.0.32 → 0.0.34
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/dist/backend/cc-cache.test.js +430 -1
- package/dist/backend/cc-cache.test.js.map +1 -1
- package/dist/backend/cc.d.ts +25 -0
- package/dist/backend/cc.js +818 -88
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-exprs.js +79 -3
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-shapes.js +37 -4
- package/dist/backend/emission/emit-shapes.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +23 -7
- package/dist/backend/emission/emitter.js +171 -27
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/emission/may-throw.js +7 -4
- package/dist/backend/emission/may-throw.js.map +1 -1
- package/dist/backend/ffi-callbacks.d.ts +38 -1
- package/dist/backend/ffi-callbacks.js +76 -3
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/library-identity.d.ts +22 -0
- package/dist/backend/library-identity.js +103 -0
- package/dist/backend/library-identity.js.map +1 -0
- package/dist/backend/llvm/emitter.d.ts +3 -0
- package/dist/backend/llvm/emitter.js +278 -17
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.d.ts +1 -0
- package/dist/backend/llvm/shapes.js +25 -1
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/mangle.d.ts +1 -0
- package/dist/backend/mangle.js +3 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/object-localize.d.ts +5 -5
- package/dist/backend/object-localize.js +19 -16
- package/dist/backend/object-localize.js.map +1 -1
- package/dist/backend/object-localize.test.js +37 -13
- package/dist/backend/object-localize.test.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +2 -0
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/ffi/profile.d.ts +17 -5
- package/dist/ffi/profile.js +169 -22
- package/dist/ffi/profile.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +82 -0
- package/dist/frontend/input-tracker.js +380 -0
- package/dist/frontend/input-tracker.js.map +1 -0
- package/dist/frontend/input-tracker.test.d.ts +1 -0
- package/dist/frontend/input-tracker.test.js +137 -0
- package/dist/frontend/input-tracker.test.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.js +2 -8
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +1 -0
- package/dist/frontend/lowering/lower-calls.js +244 -163
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +3 -0
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.js +113 -28
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +67 -1
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +45 -26
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +1 -1
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +48 -3
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +79 -29
- package/dist/frontend/lowering/lowerer.js +429 -87
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.js +25 -26
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static.js +29 -30
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm-static.test.d.ts +1 -0
- package/dist/frontend/npm-static.test.js +15 -0
- package/dist/frontend/npm-static.test.js.map +1 -0
- package/dist/frontend/npm.js +5 -17
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.js +2 -6
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.js +8 -29
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +2 -0
- package/dist/frontend/ts7/checker.js +20 -3
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/program.js +17 -18
- package/dist/frontend/ts7/program.js.map +1 -1
- package/dist/frontend/types.d.ts +41 -0
- package/dist/frontend/types.js +147 -8
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +275 -41
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +42 -12
- package/dist/ir/nodes.js +7 -1
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/validate.js +104 -1
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/early-cache.d.ts +65 -0
- package/dist/library/early-cache.js +380 -0
- package/dist/library/early-cache.js.map +1 -0
- package/dist/library/early-cache.test.d.ts +1 -0
- package/dist/library/early-cache.test.js +528 -0
- package/dist/library/early-cache.test.js.map +1 -0
- package/dist/library/int-infer.js +14 -0
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +21 -4
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/profile.d.ts +3 -0
- package/dist/library/profile.js +9 -1
- package/dist/library/profile.js.map +1 -1
- package/dist/library/semantic-source.d.ts +13 -0
- package/dist/library/semantic-source.js +257 -0
- package/dist/library/semantic-source.js.map +1 -0
- package/dist/library/semantic-source.test.d.ts +1 -0
- package/dist/library/semantic-source.test.js +113 -0
- package/dist/library/semantic-source.test.js.map +1 -0
- package/dist/library/sidecar.d.ts +6 -0
- package/dist/library/sidecar.js +11 -0
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +1 -1
|
@@ -8,7 +8,7 @@ import { ARRAY_METHODS, MAP_METHODS, SET_COMBINE_METHODS, SET_METHODS, STR_METHO
|
|
|
8
8
|
import { droppableStatic, isRequireMainFilename, lowerDynObjectLiteral, probeLower, pureReemittable } from "./lower-exprs.js";
|
|
9
9
|
import { forOfVarTarget, lowerDestructuringAssign } from "./lower-stmts.js";
|
|
10
10
|
import { isJsSourceFile, locOf } from "../program.js";
|
|
11
|
-
import {
|
|
11
|
+
import { islandPrimitiveExit, lowerDynDispatchMethodCall } from "./lower-calls.js";
|
|
12
12
|
import { typeKey } from "../types.js";
|
|
13
13
|
import { dynUndefinedExpr, own } from "./lowerer.js";
|
|
14
14
|
/** Lower an expression whose checker type is statically `undefined`/`void`.
|
|
@@ -142,7 +142,11 @@ export function lowerArrayMethodCall(L, call, access) {
|
|
|
142
142
|
{
|
|
143
143
|
const receiver = L.lowerExpr(access.expression);
|
|
144
144
|
if (receiver.type.kind === "jsval") {
|
|
145
|
-
const
|
|
145
|
+
const loweredArgs = call.arguments.map((a) => L.lowerExpr(a));
|
|
146
|
+
if (name === "filter" && loweredArgs[0]?.type.kind === "func" && loweredArgs[0].type.ret.kind === "void") {
|
|
147
|
+
L.unsupported("SC1090", call.arguments[0], "'.filter()' with a void-returning predicate (the callback return value is erased before its truthiness can be tested)");
|
|
148
|
+
}
|
|
149
|
+
const args = loweredArgs.map((arg, i) => L.jsvalIn(arg, call.arguments[i]));
|
|
146
150
|
const result = { kind: "jsOp", op: "callMethod", name, args: [receiver, ...args], type: JSVAL, loc };
|
|
147
151
|
return islandPrimitiveExit(L, call, result);
|
|
148
152
|
}
|
|
@@ -155,21 +159,9 @@ export function lowerArrayMethodCall(L, call, access) {
|
|
|
155
159
|
// ICE). Consumers validate the dyn result where a static type is
|
|
156
160
|
// required (dynCheck — the member-read discipline).
|
|
157
161
|
if (receiver.type.kind === "dyn") {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
const args = call.arguments.map((a) => L.lowerExprExpecting(a, DYN));
|
|
163
|
-
return {
|
|
164
|
-
kind: "dynInvoke",
|
|
165
|
-
recv: receiver,
|
|
166
|
-
method: name,
|
|
167
|
-
calleeName: access.getText(),
|
|
168
|
-
args,
|
|
169
|
-
type: DYN,
|
|
170
|
-
loc,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
162
|
+
const dispatched = lowerDynDispatchMethodCall(L, call, access, receiver, true);
|
|
163
|
+
if (dispatched)
|
|
164
|
+
return dispatched;
|
|
173
165
|
L.noLowering(`.${name} on an array value held in a checked-dynamic binding`, call, "assign it to an array-typed binding first (the validated extraction), then call the method");
|
|
174
166
|
}
|
|
175
167
|
// An evolving-`any` array binding under --dynamic whose flow type
|
|
@@ -596,12 +588,64 @@ export function lowerArrayHofCall(L, call, access, method, elem) {
|
|
|
596
588
|
// declaration, so the honest answer is the fence).
|
|
597
589
|
L.unsupported("SC1090", call, "'.map()' with a callback returning 'unknown'-typed values (the result array has no static element type — annotate the callback's return)");
|
|
598
590
|
}
|
|
599
|
-
|
|
591
|
+
// JS applies ToBoolean to whatever the predicate answers, so a non-bool
|
|
592
|
+
// result is not an error — the filter loop wraps the call in the same
|
|
593
|
+
// toBool an `if` statement would apply. The island/dyn shapes, whose
|
|
594
|
+
// truthiness needs the engine, and void, whose real answer the ABI has
|
|
595
|
+
// already discarded, keep the fence. No separate
|
|
596
|
+
// requireTruthyUnion call belongs here: its check (no dyn/caught arm)
|
|
597
|
+
// IS filterPredicateOk's union branch, so it could never speak.
|
|
598
|
+
if (method === "filter" && !filterPredicateOk(L, fnRet)) {
|
|
599
|
+
if (fnRet.kind === "void") {
|
|
600
|
+
L.unsupported("SC1090", argNode, "'.filter()' with a void-returning predicate (the callback return value is erased before its truthiness can be tested)");
|
|
601
|
+
}
|
|
600
602
|
L.badType(argNode, L.typeOf(argNode));
|
|
603
|
+
}
|
|
601
604
|
const helper = arrayHofHelper(L, method, elem, fnRet, arity, loc);
|
|
602
605
|
const resultType = method === "map" ? arrayOf(fnRet) : method === "filter" ? arrayOf(elem) : VOID;
|
|
603
606
|
return { kind: "call", callee: helper, args: [receiver, fnArg], type: resultType, loc };
|
|
604
607
|
}
|
|
608
|
+
/** The predicate result kinds `.filter()` accepts. JS applies ToBoolean to
|
|
609
|
+
* whatever the callback answers, so a bool is not required: the scalars and
|
|
610
|
+
* the reference kinds have constant or by-value answers, and a union is fine
|
|
611
|
+
* when every arm does. void/dyn/jsval/caught stay out — see below. */
|
|
612
|
+
function filterPredicateOk(L, ret) {
|
|
613
|
+
if (ret.kind === "bool")
|
|
614
|
+
return true;
|
|
615
|
+
// VOID is a TYPE erasure, not a runtime value: TS lets a value-returning
|
|
616
|
+
// function sit in a void-returning slot (`const p: (n: number) => void =
|
|
617
|
+
// (n) => n`), so the predicate's real answer can be truthy while the
|
|
618
|
+
// compiled ABI has already discarded it. Treating void as constantly
|
|
619
|
+
// falsy would silently answer [] where Node answers [1]. Fenced until
|
|
620
|
+
// the returned value can be preserved through the void ABI.
|
|
621
|
+
// dyn/jsval/caught stay out too: no native ToBoolean to compile against.
|
|
622
|
+
if (ret.kind === "void")
|
|
623
|
+
return false;
|
|
624
|
+
if (ret.kind === "dyn" || ret.kind === "jsval" || ret.kind === "caught")
|
|
625
|
+
return false;
|
|
626
|
+
if (ret.kind === "union") {
|
|
627
|
+
const def = L.unions.get(ret.unionId);
|
|
628
|
+
return def !== undefined && def.arms.every((a) => a.kind !== "dyn" && a.kind !== "caught");
|
|
629
|
+
}
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
/** The filter loop's condition: the predicate's result put through JS
|
|
633
|
+
* ToBoolean. A bool answer is already the condition; everything else takes
|
|
634
|
+
* the same `toBool` wrapper an `if` statement would apply (a union answer
|
|
635
|
+
* routes through its interned per-arm truthy helper). */
|
|
636
|
+
function filterCond(call, fnRet, loc) {
|
|
637
|
+
if (fnRet.kind === "bool")
|
|
638
|
+
return call;
|
|
639
|
+
// No constant-false arm here: void is fenced at the call site, and a
|
|
640
|
+
// bare undefinedT/nullT return cannot arise (mapType sends `undefined`/
|
|
641
|
+
// `void` returns to void and a standalone `null` return to the unit-ONLY
|
|
642
|
+
// UNION, which routes through toBool below; ir/validate.ts rejects a
|
|
643
|
+
// bare unit return type outright). filterPredicateOk already rejected
|
|
644
|
+
// the arms with no native ToBoolean (dyn/caught) — which is exactly what
|
|
645
|
+
// requireTruthyUnion checks — and it did so at the call site, where a
|
|
646
|
+
// real node exists for the diagnostic.
|
|
647
|
+
return { kind: "toBool", operand: call, type: BOOL, loc };
|
|
648
|
+
}
|
|
605
649
|
/** Interned synthetic loop function for one (method, elem, fnRet, arity)
|
|
606
650
|
* combo. Named `%arr.<method>.<n>` ('%' keeps it out of the user
|
|
607
651
|
* namespace); rides `liftedFns` into the module like a lifted lambda (it
|
|
@@ -934,7 +978,9 @@ export function buildArrayHofFn(L, name, method, elem, fnRet, arity, loc) {
|
|
|
934
978
|
{ kind: "varDecl", localId: "v.0", init: getElem, loc },
|
|
935
979
|
{
|
|
936
980
|
kind: "if",
|
|
937
|
-
|
|
981
|
+
// ToBoolean over the predicate's answer — inert when it already
|
|
982
|
+
// returned bool, the per-union helper when it returned a union.
|
|
983
|
+
cond: filterCond(callF(ref("v.0", elem)), fnRet, loc),
|
|
938
984
|
then: [push(arrT, ref("v.0", elem))],
|
|
939
985
|
else_: null,
|
|
940
986
|
loc,
|
|
@@ -5808,6 +5854,7 @@ export function objectIterOverIndexShape(L, node, member, argIr, shape, receiver
|
|
|
5808
5854
|
const body = [
|
|
5809
5855
|
{ kind: "varDecl", localId: "out.0", init: { kind: "arrayLit", elems: [], type: resultT, loc }, loc },
|
|
5810
5856
|
];
|
|
5857
|
+
const fieldStmts = new Map();
|
|
5811
5858
|
// Declared fields, in declaration order. Undefined-valued fields
|
|
5812
5859
|
// skip at runtime (the unset-optional convention); values surface
|
|
5813
5860
|
// into the element type or the site fences with the field named.
|
|
@@ -5875,7 +5922,7 @@ export function objectIterOverIndexShape(L, node, member, argIr, shape, receiver
|
|
|
5875
5922
|
loc,
|
|
5876
5923
|
};
|
|
5877
5924
|
}
|
|
5878
|
-
|
|
5925
|
+
const fieldStmt = utag >= 0 && f.type.kind === "union"
|
|
5879
5926
|
? {
|
|
5880
5927
|
kind: "if",
|
|
5881
5928
|
cond: { kind: "unionIsTag", unionId: f.type.unionId, tag: utag, negated: true, value: raw, type: BOOL, loc },
|
|
@@ -5883,7 +5930,9 @@ export function objectIterOverIndexShape(L, node, member, argIr, shape, receiver
|
|
|
5883
5930
|
else_: null,
|
|
5884
5931
|
loc,
|
|
5885
5932
|
}
|
|
5886
|
-
: push(pushed)
|
|
5933
|
+
: push(pushed);
|
|
5934
|
+
fieldStmts.set(f.name, fieldStmt);
|
|
5935
|
+
body.push(fieldStmt);
|
|
5887
5936
|
}
|
|
5888
5937
|
// The overflow walk: a fresh key snapshot in JS own-key order, each
|
|
5889
5938
|
// value read back through the overflow-only keyed read (declared
|
|
@@ -5930,8 +5979,9 @@ export function objectIterOverIndexShape(L, node, member, argIr, shape, receiver
|
|
|
5930
5979
|
],
|
|
5931
5980
|
loc,
|
|
5932
5981
|
}, { kind: "return", value: outRef, loc });
|
|
5982
|
+
const suffix = body.slice(1 + fieldStmts.size);
|
|
5933
5983
|
L.arrHofHelpers.set(key, helper);
|
|
5934
|
-
|
|
5984
|
+
const fn = {
|
|
5935
5985
|
name: helper,
|
|
5936
5986
|
params: [{ localId: "r.0", name: "r", type: argIr }],
|
|
5937
5987
|
returnType: resultT,
|
|
@@ -5944,7 +5994,16 @@ export function objectIterOverIndexShape(L, node, member, argIr, shape, receiver
|
|
|
5944
5994
|
],
|
|
5945
5995
|
body,
|
|
5946
5996
|
loc,
|
|
5997
|
+
};
|
|
5998
|
+
L.shapeOrderHelperFinalizers.push(() => {
|
|
5999
|
+
const current = L.shapes.get(argIr.shapeId) ?? shape;
|
|
6000
|
+
const currentOrder = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
6001
|
+
fn.body = [body[0], ...currentOrder.flatMap((name) => {
|
|
6002
|
+
const stmt = fieldStmts.get(name);
|
|
6003
|
+
return stmt ? [stmt] : [];
|
|
6004
|
+
}), ...suffix];
|
|
5947
6005
|
});
|
|
6006
|
+
L.liftedFns.push(fn);
|
|
5948
6007
|
}
|
|
5949
6008
|
return { kind: "call", callee: helper, args: [receiver], type: resultT, loc };
|
|
5950
6009
|
}
|
|
@@ -6310,6 +6369,7 @@ export function lowerRecordOvfCaptureHelper(L, fromId, toId, loc) {
|
|
|
6310
6369
|
loc,
|
|
6311
6370
|
},
|
|
6312
6371
|
];
|
|
6372
|
+
const fieldStmts = new Map();
|
|
6313
6373
|
// Source declared fields in declaration order, skipping unset
|
|
6314
6374
|
// optionals (stance 37) and the direct-initialized (consumed) names.
|
|
6315
6375
|
for (const ff of orderedFields) {
|
|
@@ -6328,7 +6388,7 @@ export function lowerRecordOvfCaptureHelper(L, fromId, toId, loc) {
|
|
|
6328
6388
|
...(to.fields.some((f) => f.name === ff.name) ? {} : { overflowOnly: true }),
|
|
6329
6389
|
loc,
|
|
6330
6390
|
};
|
|
6331
|
-
|
|
6391
|
+
const fieldStmt = utag >= 0 && ff.type.kind === "union"
|
|
6332
6392
|
? {
|
|
6333
6393
|
kind: "if",
|
|
6334
6394
|
cond: { kind: "unionIsTag", unionId: ff.type.unionId, tag: utag, negated: true, value: raw, type: BOOL, loc },
|
|
@@ -6336,7 +6396,9 @@ export function lowerRecordOvfCaptureHelper(L, fromId, toId, loc) {
|
|
|
6336
6396
|
else_: null,
|
|
6337
6397
|
loc,
|
|
6338
6398
|
}
|
|
6339
|
-
: write
|
|
6399
|
+
: write;
|
|
6400
|
+
fieldStmts.set(ff.name, fieldStmt);
|
|
6401
|
+
body.push(fieldStmt);
|
|
6340
6402
|
}
|
|
6341
6403
|
// The source overflow, in JS own-key order (only index-signature
|
|
6342
6404
|
// sources carry one).
|
|
@@ -6375,7 +6437,8 @@ export function lowerRecordOvfCaptureHelper(L, fromId, toId, loc) {
|
|
|
6375
6437
|
});
|
|
6376
6438
|
}
|
|
6377
6439
|
body.push({ kind: "return", value: outRef, loc });
|
|
6378
|
-
|
|
6440
|
+
const suffix = body.slice(1 + fieldStmts.size);
|
|
6441
|
+
const fn = {
|
|
6379
6442
|
name,
|
|
6380
6443
|
params: [{ localId: "s.0", name: "s", type: fromT }],
|
|
6381
6444
|
returnType: toT,
|
|
@@ -6392,7 +6455,16 @@ export function lowerRecordOvfCaptureHelper(L, fromId, toId, loc) {
|
|
|
6392
6455
|
],
|
|
6393
6456
|
body,
|
|
6394
6457
|
loc,
|
|
6458
|
+
};
|
|
6459
|
+
L.shapeOrderHelperFinalizers.push(() => {
|
|
6460
|
+
const current = L.shapes.get(fromId) ?? from;
|
|
6461
|
+
const currentOrder = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
6462
|
+
fn.body = [body[0], ...currentOrder.flatMap((field) => {
|
|
6463
|
+
const stmt = fieldStmts.get(field);
|
|
6464
|
+
return stmt ? [stmt] : [];
|
|
6465
|
+
}), ...suffix];
|
|
6395
6466
|
});
|
|
6467
|
+
L.liftedFns.push(fn);
|
|
6396
6468
|
return name;
|
|
6397
6469
|
}
|
|
6398
6470
|
/** `Object.assign(target, ...sources)` into an INDEX-SIGNATURE record:
|
|
@@ -6485,6 +6557,7 @@ export function lowerObjectAssignIndexShape(L, call) {
|
|
|
6485
6557
|
const sRef = ref("s.0", fromT);
|
|
6486
6558
|
const intoSlot = (v, lift) => lift === "dyn" ? { kind: "dynFrom", value: v, type: DYN, loc } : L.applyWidthLift(lift, v, tIv, loc);
|
|
6487
6559
|
const body = [];
|
|
6560
|
+
const fieldStmts = new Map();
|
|
6488
6561
|
for (const ff of plan.fields) {
|
|
6489
6562
|
const raw = { kind: "recordGet", obj: sRef, shapeId: plan.fromId, field: ff.name, type: ff.type, loc };
|
|
6490
6563
|
const utag = ff.type.kind === "union" ? L.armTag(ff.type.unionId, UNDEFINED_T) : -1;
|
|
@@ -6496,7 +6569,7 @@ export function lowerObjectAssignIndexShape(L, call) {
|
|
|
6496
6569
|
value: intoSlot(raw, ff.lift),
|
|
6497
6570
|
loc,
|
|
6498
6571
|
};
|
|
6499
|
-
|
|
6572
|
+
const fieldStmt = utag >= 0 && ff.type.kind === "union"
|
|
6500
6573
|
? {
|
|
6501
6574
|
kind: "if",
|
|
6502
6575
|
cond: { kind: "unionIsTag", unionId: ff.type.unionId, tag: utag, negated: true, value: raw, type: BOOL, loc },
|
|
@@ -6504,7 +6577,9 @@ export function lowerObjectAssignIndexShape(L, call) {
|
|
|
6504
6577
|
else_: null,
|
|
6505
6578
|
loc,
|
|
6506
6579
|
}
|
|
6507
|
-
: write
|
|
6580
|
+
: write;
|
|
6581
|
+
fieldStmts.set(ff.name, fieldStmt);
|
|
6582
|
+
body.push(fieldStmt);
|
|
6508
6583
|
}
|
|
6509
6584
|
const ksT = arrayOf(STRING);
|
|
6510
6585
|
const fromShape = L.shapes.get(plan.fromId);
|
|
@@ -6542,7 +6617,8 @@ export function lowerObjectAssignIndexShape(L, call) {
|
|
|
6542
6617
|
});
|
|
6543
6618
|
}
|
|
6544
6619
|
body.push({ kind: "return", value: tRef, loc });
|
|
6545
|
-
|
|
6620
|
+
const suffix = body.slice(fieldStmts.size);
|
|
6621
|
+
const fn = {
|
|
6546
6622
|
name,
|
|
6547
6623
|
params: [
|
|
6548
6624
|
{ localId: "t.0", name: "t", type: toT },
|
|
@@ -6562,7 +6638,16 @@ export function lowerObjectAssignIndexShape(L, call) {
|
|
|
6562
6638
|
],
|
|
6563
6639
|
body,
|
|
6564
6640
|
loc,
|
|
6641
|
+
};
|
|
6642
|
+
L.shapeOrderHelperFinalizers.push(() => {
|
|
6643
|
+
const current = L.shapes.get(plan.fromId) ?? fromShape;
|
|
6644
|
+
const currentOrder = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
6645
|
+
fn.body = [...currentOrder.flatMap((field) => {
|
|
6646
|
+
const stmt = fieldStmts.get(field);
|
|
6647
|
+
return stmt ? [stmt] : [];
|
|
6648
|
+
}), ...suffix];
|
|
6565
6649
|
});
|
|
6650
|
+
L.liftedFns.push(fn);
|
|
6566
6651
|
return name;
|
|
6567
6652
|
};
|
|
6568
6653
|
let acc = L.lowerExprExpecting(call.arguments[0], targetIr);
|