@loopdive/js2 0.58.0 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +20 -11
- package/dist/codegen/array-element-typing.d.ts +28 -14
- package/dist/codegen/context/types.d.ts +57 -10
- package/dist/codegen/fnctor-escape-gate.d.ts +37 -0
- package/dist/codegen/host-import-allowlist.d.ts +2 -2
- package/dist/codegen/index.d.ts +18 -1
- package/dist/codegen/literals.d.ts +27 -0
- package/dist/codegen/member-set-dispatch.d.ts +2 -2
- package/dist/codegen/registry/imports.d.ts +19 -1
- package/dist/codegen/shared.d.ts +24 -0
- package/dist/index.d.ts +41 -12
- package/dist/index.js +2 -2
- package/dist/{runtime-d_SmcBlN.js → runtime-UuI75J3h.js} +1623 -734
- package/dist/runtime.js +1 -1
- package/package.json +1 -1
|
@@ -8780,7 +8780,7 @@ function lookupAllowlistEntry(name) {
|
|
|
8780
8780
|
}
|
|
8781
8781
|
return void 0;
|
|
8782
8782
|
}
|
|
8783
|
-
function isHostImportAllowed(module, name) {
|
|
8783
|
+
function isHostImportAllowed(module, name, linkedNamespaces) {
|
|
8784
8784
|
if (module === "env") {
|
|
8785
8785
|
const entry = lookupAllowlistEntry(name);
|
|
8786
8786
|
if (entry) return { allowed: true };
|
|
@@ -8789,6 +8789,9 @@ function isHostImportAllowed(module, name) {
|
|
|
8789
8789
|
if (ALWAYS_ALLOWED_IMPORT_MODULES.has(module)) {
|
|
8790
8790
|
return { allowed: true };
|
|
8791
8791
|
}
|
|
8792
|
+
if (linkedNamespaces?.has(module)) {
|
|
8793
|
+
return { allowed: true };
|
|
8794
|
+
}
|
|
8792
8795
|
return { allowed: false, reason: "non-env-host-module" };
|
|
8793
8796
|
}
|
|
8794
8797
|
function buildStrictHostImportError(module, name) {
|
|
@@ -8803,14 +8806,14 @@ function buildStrictHostImportError(module, name) {
|
|
|
8803
8806
|
}
|
|
8804
8807
|
return `Host import "${module}.${name}" requested under --no-host-imports / WASI strict mode, but the name is not on the dual-mode allowlist (src/codegen/host-import-allowlist.ts). Either add a Wasm-native fallback for this feature or, if you need a transitional host import, add an entry to HOST_IMPORT_ALLOWLIST citing the tracking issue and include "[allowlist-grow]" in your PR description.`;
|
|
8805
8808
|
}
|
|
8806
|
-
function scanForLeakedHostImports(imports) {
|
|
8809
|
+
function scanForLeakedHostImports(imports, linkedNamespaces) {
|
|
8807
8810
|
const leaks = [];
|
|
8808
8811
|
const seen = /* @__PURE__ */ new Set();
|
|
8809
8812
|
for (const imp of imports) {
|
|
8810
8813
|
const key = `${imp.module}\0${imp.name}`;
|
|
8811
8814
|
if (seen.has(key)) continue;
|
|
8812
8815
|
seen.add(key);
|
|
8813
|
-
const decision = isHostImportAllowed(imp.module, imp.name);
|
|
8816
|
+
const decision = isHostImportAllowed(imp.module, imp.name, linkedNamespaces);
|
|
8814
8817
|
if (!decision.allowed) {
|
|
8815
8818
|
leaks.push({ module: imp.module, name: imp.name, reason: decision.reason });
|
|
8816
8819
|
}
|
|
@@ -8825,21 +8828,16 @@ function buildLeakedHostImportError(leak) {
|
|
|
8825
8828
|
return base + `The name is not on the dual-mode allowlist (src/codegen/host-import-allowlist.ts). Add a Wasm-native fallback for this feature, or — for a transitional host import — add an allowlist entry citing the tracking issue and include "[allowlist-grow]" in your PR description.`;
|
|
8826
8829
|
}
|
|
8827
8830
|
function funcTypeKey(params, results) {
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
if (
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
if (i > 0) key += ",";
|
|
8839
|
-
key += r.kind;
|
|
8840
|
-
if (r.kind === "ref" || r.kind === "ref_null") key += ":" + r.typeIdx;
|
|
8841
|
-
}
|
|
8842
|
-
return key;
|
|
8831
|
+
const part = (v) => {
|
|
8832
|
+
let s = v.kind;
|
|
8833
|
+
if (v.kind === "ref" || v.kind === "ref_null") s += ":" + v.typeIdx;
|
|
8834
|
+
else if (v.kind === "i32") {
|
|
8835
|
+
if (v.boolean) s += ":bool";
|
|
8836
|
+
else if (v.symbol) s += ":sym";
|
|
8837
|
+
}
|
|
8838
|
+
return s;
|
|
8839
|
+
};
|
|
8840
|
+
return params.map(part).join(",") + "|" + results.map(part).join(",");
|
|
8843
8841
|
}
|
|
8844
8842
|
function addFuncType(ctx, params, results, name) {
|
|
8845
8843
|
const key = funcTypeKey(params, results);
|
|
@@ -9084,7 +9082,7 @@ function addImport(ctx, module, name, desc) {
|
|
|
9084
9082
|
);
|
|
9085
9083
|
}
|
|
9086
9084
|
if (ctx.strictNoHostImports) {
|
|
9087
|
-
const decision = isHostImportAllowed(module, name);
|
|
9085
|
+
const decision = isHostImportAllowed(module, name, ctx.linkedNamespaces);
|
|
9088
9086
|
if (!decision.allowed) {
|
|
9089
9087
|
const message = buildStrictHostImportError(module, name);
|
|
9090
9088
|
ctx.errors.push({ message, line: 0, column: 0, severity: "degrade" });
|
|
@@ -9130,6 +9128,11 @@ function addStringConstantGlobal(ctx, value) {
|
|
|
9130
9128
|
function nextModuleGlobalIdx(ctx) {
|
|
9131
9129
|
return ctx.numImportGlobals + ctx.mod.globals.length;
|
|
9132
9130
|
}
|
|
9131
|
+
function recordInModuleInitFlagRead(ctx) {
|
|
9132
|
+
const flagGet = { op: "global.get", index: 0 };
|
|
9133
|
+
(ctx.inModuleInitFlagReads ??= []).push(flagGet);
|
|
9134
|
+
return flagGet;
|
|
9135
|
+
}
|
|
9133
9136
|
function localGlobalIdx(ctx, absIdx) {
|
|
9134
9137
|
return absIdx - ctx.numImportGlobals;
|
|
9135
9138
|
}
|
|
@@ -12515,6 +12518,15 @@ function flushLateImportShifts$1(ctx, fctx) {
|
|
|
12515
12518
|
function isAnyValue$1(type, ctx) {
|
|
12516
12519
|
return (type.kind === "ref" || type.kind === "ref_null") && type.typeIdx === ctx.anyValueTypeIdx && ctx.anyValueTypeIdx >= 0;
|
|
12517
12520
|
}
|
|
12521
|
+
function isStrictBooleanReturnType(t) {
|
|
12522
|
+
return (t.flags & (ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral)) !== 0;
|
|
12523
|
+
}
|
|
12524
|
+
function brandExternMethodResult(_ctx, tsReturnType, valType) {
|
|
12525
|
+
if (!tsReturnType) return valType;
|
|
12526
|
+
if (valType.kind !== "i32" || valType.boolean) return valType;
|
|
12527
|
+
if (!isStrictBooleanReturnType(tsReturnType)) return valType;
|
|
12528
|
+
return { kind: "i32", boolean: true };
|
|
12529
|
+
}
|
|
12518
12530
|
let _ensureAnyHelpers = () => {
|
|
12519
12531
|
throw unregisteredDelegateError("ensureAnyHelpers");
|
|
12520
12532
|
};
|
|
@@ -34159,6 +34171,12 @@ function emitToString(ctx, fctx, valType, tsType, hint) {
|
|
|
34159
34171
|
return nativeStringType(ctx);
|
|
34160
34172
|
}
|
|
34161
34173
|
if (hint === "default") {
|
|
34174
|
+
const refTypeIdx = valType.typeIdx;
|
|
34175
|
+
const structName = refTypeIdx !== void 0 ? ctx.typeIdxToStructName.get(refTypeIdx) : void 0;
|
|
34176
|
+
if (structName !== void 0 && ctx.funcMap.get(`${structName}_toString`) !== void 0 && ctx.funcMap.get(`${structName}_valueOf`) === void 0 && ctx.funcMap.get(`${structName}_@@toPrimitive`) === void 0) {
|
|
34177
|
+
coerceType$1(ctx, fctx, valType, { kind: "externref" }, "string");
|
|
34178
|
+
return { kind: "externref" };
|
|
34179
|
+
}
|
|
34162
34180
|
coerceType$1(ctx, fctx, valType, { kind: "externref" });
|
|
34163
34181
|
const toStrIdx = ensureLateImport$1(
|
|
34164
34182
|
ctx,
|
|
@@ -34594,377 +34612,6 @@ function isAllowedUse(checker, id, safe, fnDecls, fnParamSyms, nodeFsBindings) {
|
|
|
34594
34612
|
}
|
|
34595
34613
|
return false;
|
|
34596
34614
|
}
|
|
34597
|
-
const EMPTY_RESULT = {
|
|
34598
|
-
sites: /* @__PURE__ */ new Map(),
|
|
34599
|
-
approved: /* @__PURE__ */ new Set(),
|
|
34600
|
-
approvedNames: /* @__PURE__ */ new Set(),
|
|
34601
|
-
receiverStruct: /* @__PURE__ */ new Map(),
|
|
34602
|
-
newThisOwnerNames: /* @__PURE__ */ new Set(),
|
|
34603
|
-
ctorDeclByName: /* @__PURE__ */ new Map()
|
|
34604
|
-
};
|
|
34605
|
-
function fnctorDeclFromSymbol(sym) {
|
|
34606
|
-
for (const decl of sym.getDeclarations() ?? []) {
|
|
34607
|
-
if (ts.isFunctionDeclaration(decl) && decl.body) return decl;
|
|
34608
|
-
if (ts.isFunctionExpression(decl) && decl.body) return decl;
|
|
34609
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
34610
|
-
let init = decl.initializer;
|
|
34611
|
-
while (ts.isParenthesizedExpression(init)) init = init.expression;
|
|
34612
|
-
if (ts.isFunctionExpression(init) && init.body) return init;
|
|
34613
|
-
}
|
|
34614
|
-
}
|
|
34615
|
-
return void 0;
|
|
34616
|
-
}
|
|
34617
|
-
const RETURN_INFER_MAX_DEPTH = 6;
|
|
34618
|
-
const GENERIC_METHOD_CALL = /* @__PURE__ */ new Set(["call", "apply", "bind"]);
|
|
34619
|
-
function resolveFnctorSymbol(checker, calleeExpr) {
|
|
34620
|
-
let e = calleeExpr;
|
|
34621
|
-
while (ts.isParenthesizedExpression(e) || ts.isAsExpression(e) || ts.isNonNullExpression(e)) {
|
|
34622
|
-
e = e.expression;
|
|
34623
|
-
}
|
|
34624
|
-
if (!ts.isIdentifier(e)) return void 0;
|
|
34625
|
-
const sym = checker.getSymbolAtLocation(e);
|
|
34626
|
-
const decls = sym?.getDeclarations();
|
|
34627
|
-
if (!sym || !decls) return void 0;
|
|
34628
|
-
for (const decl of decls) {
|
|
34629
|
-
if (ts.isClassDeclaration(decl) || ts.isClassExpression(decl)) return void 0;
|
|
34630
|
-
if (ts.isFunctionDeclaration(decl) && decl.body) return sym;
|
|
34631
|
-
if (ts.isFunctionExpression(decl) && decl.body) return sym;
|
|
34632
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
34633
|
-
let init = decl.initializer;
|
|
34634
|
-
while (ts.isParenthesizedExpression(init)) init = init.expression;
|
|
34635
|
-
if (ts.isFunctionExpression(init) && init.body) return sym;
|
|
34636
|
-
if (ts.isArrowFunction(init)) return void 0;
|
|
34637
|
-
}
|
|
34638
|
-
}
|
|
34639
|
-
return void 0;
|
|
34640
|
-
}
|
|
34641
|
-
function collectFnctorOwnFields(ctorSym) {
|
|
34642
|
-
const fields = /* @__PURE__ */ new Set();
|
|
34643
|
-
const decls = ctorSym.getDeclarations() ?? [];
|
|
34644
|
-
for (const decl of decls) {
|
|
34645
|
-
let body;
|
|
34646
|
-
if ((ts.isFunctionDeclaration(decl) || ts.isFunctionExpression(decl)) && decl.body) body = decl.body;
|
|
34647
|
-
else if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
34648
|
-
let init = decl.initializer;
|
|
34649
|
-
while (ts.isParenthesizedExpression(init)) init = init.expression;
|
|
34650
|
-
if (ts.isFunctionExpression(init) && init.body) body = init.body;
|
|
34651
|
-
}
|
|
34652
|
-
if (!body) continue;
|
|
34653
|
-
const walk = (node) => {
|
|
34654
|
-
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(node.left) && node.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
34655
|
-
fields.add(node.left.name.text);
|
|
34656
|
-
}
|
|
34657
|
-
forEachChild$1(node, walk);
|
|
34658
|
-
};
|
|
34659
|
-
walk(body);
|
|
34660
|
-
}
|
|
34661
|
-
return fields;
|
|
34662
|
-
}
|
|
34663
|
-
function classifyUse(checker, idNode, ownFields) {
|
|
34664
|
-
const parent = idNode.parent;
|
|
34665
|
-
if (ts.isPropertyAccessExpression(parent) && parent.expression === idNode) {
|
|
34666
|
-
const name = parent.name.text;
|
|
34667
|
-
if (ownFields.has(name)) return "typed";
|
|
34668
|
-
return "dynamic";
|
|
34669
|
-
}
|
|
34670
|
-
if (ts.isElementAccessExpression(parent) && parent.expression === idNode) {
|
|
34671
|
-
return "dynamic";
|
|
34672
|
-
}
|
|
34673
|
-
if (ts.isCallExpression(parent) && parent.arguments.length > 0 && parent.arguments[0] === idNode) {
|
|
34674
|
-
const callee = parent.expression;
|
|
34675
|
-
if (ts.isPropertyAccessExpression(callee) && GENERIC_METHOD_CALL.has(callee.name.text)) {
|
|
34676
|
-
return "dynamic";
|
|
34677
|
-
}
|
|
34678
|
-
}
|
|
34679
|
-
if (ts.isCallExpression(parent)) {
|
|
34680
|
-
const argIdx = parent.arguments.indexOf(idNode);
|
|
34681
|
-
if (argIdx >= 0) {
|
|
34682
|
-
const sig = checker.getResolvedSignature(parent);
|
|
34683
|
-
const paramSym = sig?.parameters[argIdx];
|
|
34684
|
-
if (paramSym) {
|
|
34685
|
-
const pType = checker.getTypeOfSymbolAtLocation(paramSym, idNode);
|
|
34686
|
-
if (isAnyOrUnknown(pType)) return "dynamic";
|
|
34687
|
-
}
|
|
34688
|
-
return "neutral";
|
|
34689
|
-
}
|
|
34690
|
-
}
|
|
34691
|
-
if (ts.isReturnStatement(parent)) {
|
|
34692
|
-
return "neutral";
|
|
34693
|
-
}
|
|
34694
|
-
return "neutral";
|
|
34695
|
-
}
|
|
34696
|
-
function isAnyOrUnknown(t) {
|
|
34697
|
-
return (t.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
|
|
34698
|
-
}
|
|
34699
|
-
function bindingOf(newExpr) {
|
|
34700
|
-
const parent = newExpr.parent;
|
|
34701
|
-
if (ts.isVariableDeclaration(parent) && parent.initializer === newExpr && ts.isIdentifier(parent.name)) {
|
|
34702
|
-
return parent.name;
|
|
34703
|
-
}
|
|
34704
|
-
return void 0;
|
|
34705
|
-
}
|
|
34706
|
-
function unwrapExpr(e) {
|
|
34707
|
-
let cur = e;
|
|
34708
|
-
while (ts.isParenthesizedExpression(cur) || ts.isAsExpression(cur) || ts.isNonNullExpression(cur)) {
|
|
34709
|
-
cur = cur.expression;
|
|
34710
|
-
}
|
|
34711
|
-
return cur;
|
|
34712
|
-
}
|
|
34713
|
-
function isFunctionLike$2(node) {
|
|
34714
|
-
return ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node);
|
|
34715
|
-
}
|
|
34716
|
-
function buildProtoMethodIndex(sourceFile) {
|
|
34717
|
-
const idx = /* @__PURE__ */ new Map();
|
|
34718
|
-
const walk = (n) => {
|
|
34719
|
-
if (ts.isBinaryExpression(n) && n.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(n.left)) {
|
|
34720
|
-
const rhs = unwrapExpr(n.right);
|
|
34721
|
-
if (isFunctionLike$2(rhs)) {
|
|
34722
|
-
const name = n.left.name.text;
|
|
34723
|
-
const arr = idx.get(name);
|
|
34724
|
-
if (arr) arr.push(rhs);
|
|
34725
|
-
else idx.set(name, [rhs]);
|
|
34726
|
-
}
|
|
34727
|
-
}
|
|
34728
|
-
forEachChild$1(n, walk);
|
|
34729
|
-
};
|
|
34730
|
-
walk(sourceFile);
|
|
34731
|
-
return idx;
|
|
34732
|
-
}
|
|
34733
|
-
function resolveCalleeFunction(checker, callExpr, protoIndex) {
|
|
34734
|
-
const callee = unwrapExpr(callExpr.expression);
|
|
34735
|
-
let sym;
|
|
34736
|
-
if (ts.isPropertyAccessExpression(callee)) {
|
|
34737
|
-
sym = checker.getSymbolAtLocation(callee.name) ?? checker.getSymbolAtLocation(callee);
|
|
34738
|
-
} else if (ts.isIdentifier(callee)) {
|
|
34739
|
-
sym = checker.getSymbolAtLocation(callee);
|
|
34740
|
-
}
|
|
34741
|
-
if (sym) {
|
|
34742
|
-
for (const decl of sym.getDeclarations() ?? []) {
|
|
34743
|
-
const fn = functionFromDeclaration(decl);
|
|
34744
|
-
if (fn?.body) return fn;
|
|
34745
|
-
}
|
|
34746
|
-
}
|
|
34747
|
-
if (ts.isPropertyAccessExpression(callee)) {
|
|
34748
|
-
const cands = protoIndex.get(callee.name.text);
|
|
34749
|
-
if (cands && cands.length === 1 && cands[0].body) return cands[0];
|
|
34750
|
-
}
|
|
34751
|
-
return void 0;
|
|
34752
|
-
}
|
|
34753
|
-
function functionFromDeclaration(decl) {
|
|
34754
|
-
if (isFunctionLike$2(decl)) return decl;
|
|
34755
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
34756
|
-
const init = unwrapExpr(decl.initializer);
|
|
34757
|
-
if (isFunctionLike$2(init)) return init;
|
|
34758
|
-
return void 0;
|
|
34759
|
-
}
|
|
34760
|
-
if (ts.isPropertyAssignment(decl)) {
|
|
34761
|
-
const init = unwrapExpr(decl.initializer);
|
|
34762
|
-
if (isFunctionLike$2(init)) return init;
|
|
34763
|
-
return void 0;
|
|
34764
|
-
}
|
|
34765
|
-
if (ts.isMethodDeclaration(decl)) return decl;
|
|
34766
|
-
if (ts.isPropertyAccessExpression(decl) || ts.isElementAccessExpression(decl)) {
|
|
34767
|
-
const parent = decl.parent;
|
|
34768
|
-
if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && parent.left === decl) {
|
|
34769
|
-
const rhs = unwrapExpr(parent.right);
|
|
34770
|
-
if (isFunctionLike$2(rhs)) return rhs;
|
|
34771
|
-
}
|
|
34772
|
-
}
|
|
34773
|
-
return void 0;
|
|
34774
|
-
}
|
|
34775
|
-
function singleReturnExpr(fn) {
|
|
34776
|
-
const body = fn.body;
|
|
34777
|
-
if (!body) return void 0;
|
|
34778
|
-
if (!ts.isBlock(body)) return body;
|
|
34779
|
-
const returns = [];
|
|
34780
|
-
const walk = (n) => {
|
|
34781
|
-
if (ts.isReturnStatement(n)) {
|
|
34782
|
-
if (n.expression) returns.push(n.expression);
|
|
34783
|
-
return;
|
|
34784
|
-
}
|
|
34785
|
-
if (isFunctionLike$2(n)) return;
|
|
34786
|
-
forEachChild$1(n, walk);
|
|
34787
|
-
};
|
|
34788
|
-
walk(body);
|
|
34789
|
-
return returns.length === 1 ? returns[0] : void 0;
|
|
34790
|
-
}
|
|
34791
|
-
function inferReturnStruct(checker, fn, depth, memo, protoIndex) {
|
|
34792
|
-
if (memo.has(fn)) return memo.get(fn);
|
|
34793
|
-
if (depth <= 0) return void 0;
|
|
34794
|
-
memo.set(fn, void 0);
|
|
34795
|
-
const ret2 = singleReturnExpr(fn);
|
|
34796
|
-
let result;
|
|
34797
|
-
if (ret2) {
|
|
34798
|
-
const r = unwrapExpr(ret2);
|
|
34799
|
-
if (ts.isNewExpression(r)) {
|
|
34800
|
-
const ctorSym = resolveFnctorSymbol(checker, r.expression);
|
|
34801
|
-
if (ctorSym) result = `__fnctor_${ctorSym.name}`;
|
|
34802
|
-
} else if (ts.isCallExpression(r)) {
|
|
34803
|
-
const callee = resolveCalleeFunction(checker, r, protoIndex);
|
|
34804
|
-
if (callee) result = inferReturnStruct(checker, callee, depth - 1, memo, protoIndex);
|
|
34805
|
-
}
|
|
34806
|
-
}
|
|
34807
|
-
memo.set(fn, result);
|
|
34808
|
-
return result;
|
|
34809
|
-
}
|
|
34810
|
-
function buildReceiverStructMap(checker, sourceFile, usesBySymbol) {
|
|
34811
|
-
const map = /* @__PURE__ */ new Map();
|
|
34812
|
-
const memo = /* @__PURE__ */ new Map();
|
|
34813
|
-
const protoIndex = buildProtoMethodIndex(sourceFile);
|
|
34814
|
-
const visit = (node) => {
|
|
34815
|
-
if (ts.isVariableDeclaration(node) && node.initializer && ts.isIdentifier(node.name)) {
|
|
34816
|
-
const init = unwrapExpr(node.initializer);
|
|
34817
|
-
if (ts.isCallExpression(init)) {
|
|
34818
|
-
const callee = resolveCalleeFunction(checker, init, protoIndex);
|
|
34819
|
-
const struct = callee ? inferReturnStruct(checker, callee, RETURN_INFER_MAX_DEPTH, memo, protoIndex) : void 0;
|
|
34820
|
-
if (struct) {
|
|
34821
|
-
const bindSym = checker.getSymbolAtLocation(node.name);
|
|
34822
|
-
const uses = bindSym ? usesBySymbol.get(bindSym) ?? [] : [];
|
|
34823
|
-
for (const use of uses) {
|
|
34824
|
-
if (use === node.name) continue;
|
|
34825
|
-
map.set(use, struct);
|
|
34826
|
-
}
|
|
34827
|
-
}
|
|
34828
|
-
}
|
|
34829
|
-
}
|
|
34830
|
-
forEachChild$1(node, visit);
|
|
34831
|
-
};
|
|
34832
|
-
visit(sourceFile);
|
|
34833
|
-
return map;
|
|
34834
|
-
}
|
|
34835
|
-
function analyzeFnctorEscapeGate(checker, sourceFile) {
|
|
34836
|
-
const sites = /* @__PURE__ */ new Map();
|
|
34837
|
-
const approved = /* @__PURE__ */ new Set();
|
|
34838
|
-
const approvedNames = /* @__PURE__ */ new Set();
|
|
34839
|
-
const newSites = [];
|
|
34840
|
-
const collect = (node) => {
|
|
34841
|
-
if (ts.isNewExpression(node)) {
|
|
34842
|
-
const ctorSym = resolveFnctorSymbol(checker, node.expression);
|
|
34843
|
-
if (ctorSym) newSites.push({ newExpr: node, ctorSym });
|
|
34844
|
-
}
|
|
34845
|
-
forEachChild$1(node, collect);
|
|
34846
|
-
};
|
|
34847
|
-
collect(sourceFile);
|
|
34848
|
-
if (newSites.length === 0) return EMPTY_RESULT;
|
|
34849
|
-
const ctorDeclByName = /* @__PURE__ */ new Map();
|
|
34850
|
-
for (const { ctorSym } of newSites) {
|
|
34851
|
-
if (ctorDeclByName.has(ctorSym.name)) continue;
|
|
34852
|
-
const decl = fnctorDeclFromSymbol(ctorSym);
|
|
34853
|
-
if (decl) ctorDeclByName.set(ctorSym.name, decl);
|
|
34854
|
-
}
|
|
34855
|
-
const usesBySymbol = /* @__PURE__ */ new Map();
|
|
34856
|
-
const indexUses = (node) => {
|
|
34857
|
-
if (ts.isIdentifier(node)) {
|
|
34858
|
-
const sym = checker.getSymbolAtLocation(node);
|
|
34859
|
-
if (sym) {
|
|
34860
|
-
const arr = usesBySymbol.get(sym);
|
|
34861
|
-
if (arr) arr.push(node);
|
|
34862
|
-
else usesBySymbol.set(sym, [node]);
|
|
34863
|
-
}
|
|
34864
|
-
}
|
|
34865
|
-
forEachChild$1(node, indexUses);
|
|
34866
|
-
};
|
|
34867
|
-
indexUses(sourceFile);
|
|
34868
|
-
for (const { newExpr, ctorSym } of newSites) {
|
|
34869
|
-
const ownFields = collectFnctorOwnFields(ctorSym);
|
|
34870
|
-
let sawDynamic = false;
|
|
34871
|
-
let sawTyped = false;
|
|
34872
|
-
const bind = bindingOf(newExpr);
|
|
34873
|
-
if (bind) {
|
|
34874
|
-
const bindSym = checker.getSymbolAtLocation(bind);
|
|
34875
|
-
const uses = bindSym ? usesBySymbol.get(bindSym) ?? [] : [];
|
|
34876
|
-
for (const use of uses) {
|
|
34877
|
-
if (use === bind) continue;
|
|
34878
|
-
const c = classifyUse(checker, use, ownFields);
|
|
34879
|
-
if (c === "typed") sawTyped = true;
|
|
34880
|
-
else if (c === "dynamic") sawDynamic = true;
|
|
34881
|
-
}
|
|
34882
|
-
} else {
|
|
34883
|
-
let inner = newExpr;
|
|
34884
|
-
let parent = inner.parent;
|
|
34885
|
-
while (ts.isParenthesizedExpression(parent) || ts.isAsExpression(parent) || ts.isNonNullExpression(parent)) {
|
|
34886
|
-
inner = parent;
|
|
34887
|
-
parent = parent.parent;
|
|
34888
|
-
}
|
|
34889
|
-
if (ts.isPropertyAccessExpression(parent) && parent.expression === inner) {
|
|
34890
|
-
if (ownFields.has(parent.name.text)) sawTyped = true;
|
|
34891
|
-
else sawDynamic = true;
|
|
34892
|
-
} else if (ts.isElementAccessExpression(parent) && parent.expression === inner) {
|
|
34893
|
-
sawDynamic = true;
|
|
34894
|
-
} else if (ts.isCallExpression(parent) && parent.arguments.length > 0 && parent.arguments[0] === inner && ts.isPropertyAccessExpression(parent.expression) && GENERIC_METHOD_CALL.has(parent.expression.name.text)) {
|
|
34895
|
-
sawDynamic = true;
|
|
34896
|
-
}
|
|
34897
|
-
}
|
|
34898
|
-
let cls;
|
|
34899
|
-
if (sawTyped) cls = "keep-typed";
|
|
34900
|
-
else if (sawDynamic) cls = "reconstruct";
|
|
34901
|
-
else cls = "keep-static";
|
|
34902
|
-
sites.set(newExpr, cls);
|
|
34903
|
-
if (cls === "reconstruct") {
|
|
34904
|
-
approved.add(newExpr);
|
|
34905
|
-
approvedNames.add(ctorSym.name);
|
|
34906
|
-
}
|
|
34907
|
-
}
|
|
34908
|
-
const receiverStruct = buildReceiverStructMap(checker, sourceFile, usesBySymbol);
|
|
34909
|
-
if (process.env.JS2WASM_LOG_FNCTOR_GATE === "1" && (sites.size > 0 || receiverStruct.size > 0)) {
|
|
34910
|
-
const counts = { reconstruct: 0, "keep-typed": 0, "keep-static": 0 };
|
|
34911
|
-
for (const c of sites.values()) counts[c]++;
|
|
34912
|
-
console.error(
|
|
34913
|
-
`[#2660 fnctor-escape-gate] ${sites.size} new F() site(s): reconstruct=${counts.reconstruct} keep-typed=${counts["keep-typed"]} keep-static=${counts["keep-static"]}; receiverStruct flow-map entries=${receiverStruct.size}`
|
|
34914
|
-
);
|
|
34915
|
-
}
|
|
34916
|
-
const newThisOwnerNames = /* @__PURE__ */ new Set();
|
|
34917
|
-
return { sites, approved, approvedNames, receiverStruct, newThisOwnerNames, ctorDeclByName };
|
|
34918
|
-
}
|
|
34919
|
-
function deriveFnctorFields(ctx, funcDecl) {
|
|
34920
|
-
const body = funcDecl.body;
|
|
34921
|
-
if (!body) return [];
|
|
34922
|
-
const fields = [];
|
|
34923
|
-
function recordThisField(lhs, valueExpr) {
|
|
34924
|
-
const fieldName = lhs.name.text;
|
|
34925
|
-
if (fields.some((f) => f.name === fieldName)) return;
|
|
34926
|
-
const lhsType = ctx.checker.getTypeAtLocation(lhs);
|
|
34927
|
-
const rhsType = ctx.checker.getTypeAtLocation(valueExpr);
|
|
34928
|
-
const lhsWasm = resolveWasmType(ctx, lhsType);
|
|
34929
|
-
const rhsWasm = resolveWasmType(ctx, rhsType);
|
|
34930
|
-
const fieldType = lhsWasm.kind === "externref" ? rhsWasm : lhsWasm;
|
|
34931
|
-
fields.push({ name: fieldName, type: fieldType, mutable: true });
|
|
34932
|
-
}
|
|
34933
|
-
function collectAssignmentChain(expr) {
|
|
34934
|
-
if (ts.isBinaryExpression(expr) && expr.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(expr.left) && expr.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
34935
|
-
recordThisField(expr.left, expr.right);
|
|
34936
|
-
collectAssignmentChain(expr.right);
|
|
34937
|
-
}
|
|
34938
|
-
}
|
|
34939
|
-
function collectThisAssignments(stmts) {
|
|
34940
|
-
for (const stmt of stmts) {
|
|
34941
|
-
if (ts.isExpressionStatement(stmt) && ts.isBinaryExpression(stmt.expression)) {
|
|
34942
|
-
collectAssignmentChain(stmt.expression);
|
|
34943
|
-
}
|
|
34944
|
-
if (ts.isIfStatement(stmt)) {
|
|
34945
|
-
if (ts.isBlock(stmt.thenStatement)) {
|
|
34946
|
-
collectThisAssignments(stmt.thenStatement.statements);
|
|
34947
|
-
}
|
|
34948
|
-
if (stmt.elseStatement && ts.isBlock(stmt.elseStatement)) {
|
|
34949
|
-
collectThisAssignments(stmt.elseStatement.statements);
|
|
34950
|
-
}
|
|
34951
|
-
}
|
|
34952
|
-
if ((ts.isForStatement(stmt) || ts.isForInStatement(stmt) || ts.isForOfStatement(stmt) || ts.isWhileStatement(stmt) || ts.isDoStatement(stmt)) && ts.isBlock(stmt.statement)) {
|
|
34953
|
-
collectThisAssignments(stmt.statement.statements);
|
|
34954
|
-
}
|
|
34955
|
-
}
|
|
34956
|
-
}
|
|
34957
|
-
collectThisAssignments(body.statements);
|
|
34958
|
-
for (const field of fields) {
|
|
34959
|
-
if (field.type.kind === "ref") {
|
|
34960
|
-
field.type = {
|
|
34961
|
-
kind: "ref_null",
|
|
34962
|
-
typeIdx: field.type.typeIdx
|
|
34963
|
-
};
|
|
34964
|
-
}
|
|
34965
|
-
}
|
|
34966
|
-
return fields;
|
|
34967
|
-
}
|
|
34968
34615
|
function fnSymbolOf(checker, node) {
|
|
34969
34616
|
if (ts.isFunctionDeclaration(node) && node.name) return checker.getSymbolAtLocation(node.name);
|
|
34970
34617
|
if (ts.isMethodDeclaration(node) && ts.isIdentifier(node.name)) return checker.getSymbolAtLocation(node.name);
|
|
@@ -37361,7 +37008,7 @@ function applyIrTailCalls(ctx, body, funcTypeIdx) {
|
|
|
37361
37008
|
};
|
|
37362
37009
|
return convertBuffer(ctx, body, caller);
|
|
37363
37010
|
}
|
|
37364
|
-
function isFunctionLike$
|
|
37011
|
+
function isFunctionLike$2(node) {
|
|
37365
37012
|
return ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node) || ts.isAccessor(node) || ts.isConstructorDeclaration(node);
|
|
37366
37013
|
}
|
|
37367
37014
|
function containsLinearU8Allocation(ctx, node) {
|
|
@@ -37370,7 +37017,7 @@ function containsLinearU8Allocation(ctx, node) {
|
|
|
37370
37017
|
let found = false;
|
|
37371
37018
|
const visit = (child) => {
|
|
37372
37019
|
if (found) return;
|
|
37373
|
-
if (child !== node && isFunctionLike$
|
|
37020
|
+
if (child !== node && isFunctionLike$2(child)) return;
|
|
37374
37021
|
if (ts.isVariableDeclaration(child) && ts.isIdentifier(child.name) && child.initializer && ts.isNewExpression(child.initializer) && ts.isIdentifier(child.initializer.expression) && child.initializer.expression.text === "Uint8Array" && isLinearU8RepresentableNew(ctx, child.initializer)) {
|
|
37375
37022
|
const sym = ctx.checker.getSymbolAtLocation(child.name);
|
|
37376
37023
|
if (sym && linear.safeBindings.has(sym)) {
|
|
@@ -51355,15 +51002,184 @@ function tryEmitLinearU8StdWrite(ctx, fctx, bufArg, writeSinkIdx, fd) {
|
|
|
51355
51002
|
fctx.body.push({ op: "drop" });
|
|
51356
51003
|
return true;
|
|
51357
51004
|
}
|
|
51005
|
+
function dispatcherName$2(propName, strict) {
|
|
51006
|
+
return strict ? `__set_member_${propName}` : `__set_member_nonstrict_${propName}`;
|
|
51007
|
+
}
|
|
51008
|
+
function reserveMemberSetDispatch(ctx, propName, strict, fctx) {
|
|
51009
|
+
const name = dispatcherName$2(propName, strict);
|
|
51010
|
+
const existing = ctx.funcMap.get(name);
|
|
51011
|
+
if (existing !== void 0) return existing;
|
|
51012
|
+
const fallbackName = strict ? "__extern_set_strict" : "__extern_set";
|
|
51013
|
+
const setIdx = ensureLateImport$1(
|
|
51014
|
+
ctx,
|
|
51015
|
+
fallbackName,
|
|
51016
|
+
[{ kind: "externref" }, { kind: "externref" }, { kind: "externref" }],
|
|
51017
|
+
[]
|
|
51018
|
+
);
|
|
51019
|
+
if (setIdx === void 0) return void 0;
|
|
51020
|
+
addStringConstantGlobal(ctx, propName);
|
|
51021
|
+
addUnionImportsViaRegistry(ctx);
|
|
51022
|
+
if (fctx) flushLateImportShifts$1(ctx, fctx);
|
|
51023
|
+
const typeIdx = addFuncType(ctx, [{ kind: "externref" }, { kind: "externref" }], [], "$member_set_dispatch_type");
|
|
51024
|
+
const funcIdx = ctx.numImportFuncs + ctx.mod.functions.length;
|
|
51025
|
+
ctx.mod.functions.push({
|
|
51026
|
+
name,
|
|
51027
|
+
typeIdx,
|
|
51028
|
+
locals: [],
|
|
51029
|
+
// Placeholder; filled by fillMemberSetDispatch. `unreachable` keeps the stub
|
|
51030
|
+
// valid (no results) if the fill is ever skipped (it never is — the fill
|
|
51031
|
+
// iterates the same name set this reserve populates).
|
|
51032
|
+
body: [{ op: "unreachable" }],
|
|
51033
|
+
exported: false
|
|
51034
|
+
});
|
|
51035
|
+
ctx.funcMap.set(name, funcIdx);
|
|
51036
|
+
(ctx.memberSetDispatchNames ??= /* @__PURE__ */ new Set()).add(`${propName}\0${strict ? "S" : "N"}`);
|
|
51037
|
+
return funcIdx;
|
|
51038
|
+
}
|
|
51039
|
+
function fillMemberSetDispatch(ctx) {
|
|
51040
|
+
const mod = ctx.mod;
|
|
51041
|
+
for (const key of ctx.memberSetDispatchNames ?? []) {
|
|
51042
|
+
const sep = key.lastIndexOf("\0");
|
|
51043
|
+
const propName = sep >= 0 ? key.slice(0, sep) : key;
|
|
51044
|
+
const strict = sep >= 0 ? key.slice(sep + 1) === "S" : true;
|
|
51045
|
+
const dispIdx = ctx.funcMap.get(dispatcherName$2(propName, strict));
|
|
51046
|
+
if (dispIdx === void 0) continue;
|
|
51047
|
+
const dispFn = mod.functions[dispIdx - ctx.numImportFuncs];
|
|
51048
|
+
if (!dispFn) continue;
|
|
51049
|
+
const candidates = findAlternateStructsForField(ctx, propName, -1).filter((c) => c.mutable);
|
|
51050
|
+
const fallbackIdx = ctx.funcMap.get(strict ? "__extern_set_strict" : "__extern_set");
|
|
51051
|
+
const fallback = fallbackIdx !== void 0 ? [
|
|
51052
|
+
{ op: "local.get", index: 0 },
|
|
51053
|
+
// recv
|
|
51054
|
+
...stringConstantExternrefInstrs(ctx, propName),
|
|
51055
|
+
{ op: "local.get", index: 1 },
|
|
51056
|
+
// val
|
|
51057
|
+
{ op: "call", funcIdx: fallbackIdx }
|
|
51058
|
+
] : [];
|
|
51059
|
+
const buildSetDispatch = (idx) => {
|
|
51060
|
+
if (idx >= candidates.length) return fallback;
|
|
51061
|
+
const cand = candidates[idx];
|
|
51062
|
+
const coerce = coercionInstrs(ctx, { kind: "externref" }, cand.fieldType);
|
|
51063
|
+
const setFieldInstrs = [
|
|
51064
|
+
{ op: "local.get", index: 2 },
|
|
51065
|
+
// __any
|
|
51066
|
+
{ op: "ref.cast", typeIdx: cand.structTypeIdx },
|
|
51067
|
+
{ op: "local.get", index: 1 },
|
|
51068
|
+
// val (externref)
|
|
51069
|
+
...coerce,
|
|
51070
|
+
{ op: "struct.set", typeIdx: cand.structTypeIdx, fieldIdx: cand.fieldIdx }
|
|
51071
|
+
];
|
|
51072
|
+
return [
|
|
51073
|
+
{ op: "local.get", index: 2 },
|
|
51074
|
+
// __any
|
|
51075
|
+
{ op: "ref.test", typeIdx: cand.structTypeIdx },
|
|
51076
|
+
{
|
|
51077
|
+
op: "if",
|
|
51078
|
+
blockType: { kind: "empty" },
|
|
51079
|
+
then: setFieldInstrs,
|
|
51080
|
+
else: buildSetDispatch(idx + 1)
|
|
51081
|
+
}
|
|
51082
|
+
];
|
|
51083
|
+
};
|
|
51084
|
+
dispFn.locals = [{ name: "__any", type: { kind: "anyref" } }];
|
|
51085
|
+
dispFn.body = [
|
|
51086
|
+
{ op: "local.get", index: 0 },
|
|
51087
|
+
// recv (externref)
|
|
51088
|
+
{ op: "any.convert_extern" },
|
|
51089
|
+
{ op: "local.set", index: 2 },
|
|
51090
|
+
// __any
|
|
51091
|
+
...buildSetDispatch(0)
|
|
51092
|
+
];
|
|
51093
|
+
}
|
|
51094
|
+
}
|
|
51095
|
+
function dispatcherName$1(propName) {
|
|
51096
|
+
return `__get_member_${propName}`;
|
|
51097
|
+
}
|
|
51098
|
+
function reserveMemberGetDispatch(ctx, propName, fctx) {
|
|
51099
|
+
const name = dispatcherName$1(propName);
|
|
51100
|
+
const existing = ctx.funcMap.get(name);
|
|
51101
|
+
if (existing !== void 0) return existing;
|
|
51102
|
+
const getIdx = ensureLateImport$1(
|
|
51103
|
+
ctx,
|
|
51104
|
+
"__extern_get",
|
|
51105
|
+
[{ kind: "externref" }, { kind: "externref" }],
|
|
51106
|
+
[{ kind: "externref" }]
|
|
51107
|
+
);
|
|
51108
|
+
if (getIdx === void 0) return void 0;
|
|
51109
|
+
addStringConstantGlobal(ctx, propName);
|
|
51110
|
+
addUnionImportsViaRegistry(ctx);
|
|
51111
|
+
if (fctx) flushLateImportShifts$1(ctx, fctx);
|
|
51112
|
+
const typeIdx = addFuncType(ctx, [{ kind: "externref" }], [{ kind: "externref" }], "$member_get_dispatch_type");
|
|
51113
|
+
const funcIdx = ctx.numImportFuncs + ctx.mod.functions.length;
|
|
51114
|
+
ctx.mod.functions.push({
|
|
51115
|
+
name,
|
|
51116
|
+
typeIdx,
|
|
51117
|
+
locals: [],
|
|
51118
|
+
body: [{ op: "unreachable" }],
|
|
51119
|
+
exported: false
|
|
51120
|
+
});
|
|
51121
|
+
ctx.funcMap.set(name, funcIdx);
|
|
51122
|
+
(ctx.memberGetDispatchNames ??= /* @__PURE__ */ new Set()).add(propName);
|
|
51123
|
+
return funcIdx;
|
|
51124
|
+
}
|
|
51125
|
+
function fillMemberGetDispatch(ctx) {
|
|
51126
|
+
const mod = ctx.mod;
|
|
51127
|
+
const getIdx = ctx.funcMap.get("__extern_get");
|
|
51128
|
+
for (const propName of ctx.memberGetDispatchNames ?? []) {
|
|
51129
|
+
const dispIdx = ctx.funcMap.get(dispatcherName$1(propName));
|
|
51130
|
+
if (dispIdx === void 0) continue;
|
|
51131
|
+
const dispFn = mod.functions[dispIdx - ctx.numImportFuncs];
|
|
51132
|
+
if (!dispFn) continue;
|
|
51133
|
+
const candidates = findAlternateStructsForField(ctx, propName, -1);
|
|
51134
|
+
const fallback = getIdx !== void 0 ? [
|
|
51135
|
+
{ op: "local.get", index: 0 },
|
|
51136
|
+
// recv
|
|
51137
|
+
...stringConstantExternrefInstrs(ctx, propName),
|
|
51138
|
+
{ op: "call", funcIdx: getIdx }
|
|
51139
|
+
] : [{ op: "ref.null.extern" }];
|
|
51140
|
+
const buildGetDispatch = (idx) => {
|
|
51141
|
+
if (idx >= candidates.length) return fallback;
|
|
51142
|
+
const cand = candidates[idx];
|
|
51143
|
+
const box = coercionInstrs(ctx, cand.fieldType, { kind: "externref" });
|
|
51144
|
+
const readInstrs = [
|
|
51145
|
+
{ op: "local.get", index: 1 },
|
|
51146
|
+
// __any
|
|
51147
|
+
{ op: "ref.cast", typeIdx: cand.structTypeIdx },
|
|
51148
|
+
{ op: "struct.get", typeIdx: cand.structTypeIdx, fieldIdx: cand.fieldIdx },
|
|
51149
|
+
...box
|
|
51150
|
+
];
|
|
51151
|
+
return [
|
|
51152
|
+
{ op: "local.get", index: 1 },
|
|
51153
|
+
// __any
|
|
51154
|
+
{ op: "ref.test", typeIdx: cand.structTypeIdx },
|
|
51155
|
+
{
|
|
51156
|
+
op: "if",
|
|
51157
|
+
blockType: { kind: "val", type: { kind: "externref" } },
|
|
51158
|
+
then: readInstrs,
|
|
51159
|
+
else: buildGetDispatch(idx + 1)
|
|
51160
|
+
}
|
|
51161
|
+
];
|
|
51162
|
+
};
|
|
51163
|
+
dispFn.locals = [{ name: "__any", type: { kind: "anyref" } }];
|
|
51164
|
+
dispFn.body = [
|
|
51165
|
+
{ op: "local.get", index: 0 },
|
|
51166
|
+
// recv (externref)
|
|
51167
|
+
{ op: "any.convert_extern" },
|
|
51168
|
+
{ op: "local.set", index: 1 },
|
|
51169
|
+
// __any
|
|
51170
|
+
...buildGetDispatch(0)
|
|
51171
|
+
];
|
|
51172
|
+
}
|
|
51173
|
+
}
|
|
51358
51174
|
const VEC_SEARCH_METHODS = /* @__PURE__ */ new Set(["indexOf", "lastIndexOf", "includes"]);
|
|
51359
|
-
function dispatcherName
|
|
51175
|
+
function dispatcherName(methodName, arity) {
|
|
51360
51176
|
return `__call_m_${methodName}_${arity}`;
|
|
51361
51177
|
}
|
|
51362
51178
|
function varargDispatcherName(methodName) {
|
|
51363
51179
|
return `__call_m_${methodName}_vararg`;
|
|
51364
51180
|
}
|
|
51365
51181
|
function reserveClosedMethodDispatch(ctx, methodName, arity = 0) {
|
|
51366
|
-
const name = dispatcherName
|
|
51182
|
+
const name = dispatcherName(methodName, arity);
|
|
51367
51183
|
const existing = ctx.funcMap.get(name);
|
|
51368
51184
|
if (existing !== void 0) return existing;
|
|
51369
51185
|
ensureObjVecBuilders(ctx);
|
|
@@ -51488,7 +51304,7 @@ function fillClosedMethodDispatch(ctx) {
|
|
|
51488
51304
|
const slash = key.lastIndexOf("/");
|
|
51489
51305
|
const methodName = slash >= 0 ? key.slice(0, slash) : key;
|
|
51490
51306
|
const arity = slash >= 0 ? Number.parseInt(key.slice(slash + 1), 10) || 0 : 0;
|
|
51491
|
-
const dispIdx = ctx.funcMap.get(dispatcherName
|
|
51307
|
+
const dispIdx = ctx.funcMap.get(dispatcherName(methodName, arity));
|
|
51492
51308
|
if (dispIdx === void 0) continue;
|
|
51493
51309
|
const dispFn = mod.functions[dispIdx - ctx.numImportFuncs];
|
|
51494
51310
|
if (!dispFn) continue;
|
|
@@ -51686,8 +51502,8 @@ function compileConsoleCall(ctx, fctx, expr, method) {
|
|
|
51686
51502
|
}
|
|
51687
51503
|
for (const arg of expr.arguments) {
|
|
51688
51504
|
const argType = ctx.checker.getTypeAtLocation(arg);
|
|
51689
|
-
compileExpression$1(ctx, fctx, arg);
|
|
51690
51505
|
if (isStringType(argType)) {
|
|
51506
|
+
compileExpression$1(ctx, fctx, arg);
|
|
51691
51507
|
if (ctx.nativeStrings && ctx.nativeStrTypeIdx >= 0) {
|
|
51692
51508
|
ensureNativeStringExternBridge(ctx);
|
|
51693
51509
|
flushLateImportShifts(ctx, fctx);
|
|
@@ -51705,16 +51521,25 @@ function compileConsoleCall(ctx, fctx, expr, method) {
|
|
|
51705
51521
|
fctx.body.push({ op: "call", funcIdx });
|
|
51706
51522
|
}
|
|
51707
51523
|
} else if (isBooleanType(argType)) {
|
|
51524
|
+
compileExpression$1(ctx, fctx, arg, { kind: "i32" });
|
|
51708
51525
|
const funcIdx = ctx.funcMap.get(`console_${method}_bool`);
|
|
51709
51526
|
if (funcIdx !== void 0) {
|
|
51710
51527
|
fctx.body.push({ op: "call", funcIdx });
|
|
51711
51528
|
}
|
|
51712
51529
|
} else if (isNumberType(argType)) {
|
|
51530
|
+
compileExpression$1(ctx, fctx, arg, { kind: "f64" });
|
|
51713
51531
|
const funcIdx = ctx.funcMap.get(`console_${method}_number`);
|
|
51714
51532
|
if (funcIdx !== void 0) {
|
|
51715
51533
|
fctx.body.push({ op: "call", funcIdx });
|
|
51716
51534
|
}
|
|
51717
51535
|
} else {
|
|
51536
|
+
const res = compileExpression$1(ctx, fctx, arg);
|
|
51537
|
+
if (res && typeof res === "object" && "kind" in res) {
|
|
51538
|
+
const k = res.kind;
|
|
51539
|
+
if (k === "f64" || k === "i32" || k === "i64") {
|
|
51540
|
+
coerceType$2(ctx, fctx, res, { kind: "externref" });
|
|
51541
|
+
}
|
|
51542
|
+
}
|
|
51718
51543
|
const funcIdx = ctx.funcMap.get(`console_${method}_externref`);
|
|
51719
51544
|
if (funcIdx !== void 0) {
|
|
51720
51545
|
fctx.body.push({ op: "call", funcIdx });
|
|
@@ -60965,7 +60790,8 @@ function compileObjectKeysOrValues(ctx, fctx, method, expr) {
|
|
|
60965
60790
|
fctx.body.push({ op: "unreachable" });
|
|
60966
60791
|
return { kind: "externref" };
|
|
60967
60792
|
}
|
|
60968
|
-
const
|
|
60793
|
+
const argIsHostObjectVar = ts.isIdentifier(arg) && ctx.externrefAccessorVars.has(arg.text);
|
|
60794
|
+
const structName = argIsHostObjectVar ? void 0 : resolveStructName(ctx, argType);
|
|
60969
60795
|
if (!structName) {
|
|
60970
60796
|
const isAnyOrUnknown2 = (argType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
|
|
60971
60797
|
const tsProps = argType.getProperties?.();
|
|
@@ -64756,13 +64582,14 @@ function compileVariableStatement(ctx, fctx, stmt) {
|
|
|
64756
64582
|
}
|
|
64757
64583
|
return false;
|
|
64758
64584
|
});
|
|
64759
|
-
|
|
64585
|
+
const initIsHostSpreadLiteral = decl.initializer !== void 0 && ts.isObjectLiteralExpression(decl.initializer) && objectLiteralSpreadTakesHostPath(ctx, decl.initializer);
|
|
64586
|
+
if (initIsAccessorLiteral || initIsHostSpreadLiteral) {
|
|
64760
64587
|
ctx.externrefAccessorVars.add(name);
|
|
64761
64588
|
}
|
|
64762
64589
|
const standaloneRegExpMatchArrayType = inferStandaloneRegExpMatchArrayType$1(ctx, decl.initializer);
|
|
64763
64590
|
const subarraySubviewType = inferSubarraySubviewType(ctx, fctx, decl.initializer);
|
|
64764
64591
|
const initIsProxy = decl.initializer !== void 0 && isProxyConstruction(decl.initializer) && ts.isIdentifier(decl.name) && !proxyResultEscapesToCall(decl, decl.name.text);
|
|
64765
|
-
const wasmType = initIsAccessorLiteral ? { kind: "externref" } : isI32CoercedLocal ? { kind: "i32" } : isI32SpecializedArray ? { kind: "ref_null", typeIdx: getOrRegisterVecType(ctx, "i32", { kind: "i32" }) } : widenedTypeIdx !== void 0 ? { kind: "ref_null", typeIdx: widenedTypeIdx } : subarraySubviewType ?? inferredVecType ?? standaloneRegExpMatchArrayType ?? (decl.initializer && isStringMethodReturningHostArray(ctx, decl.initializer) ? { kind: "externref" } : decl.initializer && isPromiseHostCall(ctx, decl.initializer) ? { kind: "externref" } : (
|
|
64592
|
+
const wasmType = initIsAccessorLiteral || initIsHostSpreadLiteral ? { kind: "externref" } : isI32CoercedLocal ? { kind: "i32" } : isI32SpecializedArray ? { kind: "ref_null", typeIdx: getOrRegisterVecType(ctx, "i32", { kind: "i32" }) } : widenedTypeIdx !== void 0 ? { kind: "ref_null", typeIdx: widenedTypeIdx } : subarraySubviewType ?? inferredVecType ?? standaloneRegExpMatchArrayType ?? (decl.initializer && isStringMethodReturningHostArray(ctx, decl.initializer) ? { kind: "externref" } : decl.initializer && isPromiseHostCall(ctx, decl.initializer) ? { kind: "externref" } : (
|
|
64766
64593
|
// (#2615) `new Proxy(target, handler)` returns a host/native
|
|
64767
64594
|
// Proxy externref. The checker types it as the TARGET's
|
|
64768
64595
|
// struct (ProxyConstructor returns T), so the default slot
|
|
@@ -78146,6 +77973,7 @@ function compileNewExpression(ctx, fctx, expr) {
|
|
|
78146
77973
|
const type = ctx.checker.getTypeAtLocation(expr);
|
|
78147
77974
|
const symbol = type.getSymbol();
|
|
78148
77975
|
let className = symbol?.name;
|
|
77976
|
+
let thisFnctorSym;
|
|
78149
77977
|
if (className && !ctx.classSet.has(className)) {
|
|
78150
77978
|
const mapped = ctx.classExprNameMap.get(className);
|
|
78151
77979
|
if (mapped) {
|
|
@@ -78163,6 +77991,13 @@ function compileNewExpression(ctx, fctx, expr) {
|
|
|
78163
77991
|
}
|
|
78164
77992
|
}
|
|
78165
77993
|
}
|
|
77994
|
+
if ((!className || !ctx.classSet.has(className)) && expr.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
77995
|
+
const owner = resolveEnclosingFnctorOwner(ctx.checker, expr);
|
|
77996
|
+
if (owner && ctx.fnctorEscapeGate?.approvedNames.has(owner.name)) {
|
|
77997
|
+
className = owner.name;
|
|
77998
|
+
thisFnctorSym = owner.sym;
|
|
77999
|
+
}
|
|
78000
|
+
}
|
|
78166
78001
|
if (ctx.standalone && (isGlobalRegExpType(type) || ts.isIdentifier(expr.expression) && isGlobalRegExpIdentifier(ctx, expr.expression))) {
|
|
78167
78002
|
return compileStandaloneRegExpConstructor(ctx, fctx, expr.arguments ?? [], expr);
|
|
78168
78003
|
}
|
|
@@ -78186,7 +78021,7 @@ function compileNewExpression(ctx, fctx, expr) {
|
|
|
78186
78021
|
return { kind: "ref", typeIdx: cachedFnCtor.structTypeIdx };
|
|
78187
78022
|
}
|
|
78188
78023
|
} else {
|
|
78189
|
-
const decls = symbol?.getDeclarations();
|
|
78024
|
+
const decls = (symbol ?? thisFnctorSym)?.getDeclarations();
|
|
78190
78025
|
if (decls) {
|
|
78191
78026
|
for (const decl of decls) {
|
|
78192
78027
|
if (ts.isFunctionDeclaration(decl) && decl.body) {
|
|
@@ -81199,8 +81034,41 @@ function isGlobalEvalIdentifier(ident, checker) {
|
|
|
81199
81034
|
if (!decls || decls.length === 0) return true;
|
|
81200
81035
|
return decls.every((d) => d.getSourceFile().isDeclarationFile);
|
|
81201
81036
|
}
|
|
81037
|
+
function ensureFuncValueWrappersRegistered(ctx, sf) {
|
|
81038
|
+
const flag = ctx;
|
|
81039
|
+
if (flag.__funcValueWrappersRegistered) return;
|
|
81040
|
+
flag.__funcValueWrappersRegistered = true;
|
|
81041
|
+
const usedAsValue = /* @__PURE__ */ new Set();
|
|
81042
|
+
const visit = (node) => {
|
|
81043
|
+
if (ts.isIdentifier(node)) {
|
|
81044
|
+
const p = node.parent;
|
|
81045
|
+
const isCallee = p && ts.isCallExpression(p) && p.expression === node;
|
|
81046
|
+
const isNewCallee = p && ts.isNewExpression(p) && p.expression === node;
|
|
81047
|
+
const isOwnName = p && (ts.isFunctionDeclaration(p) || ts.isFunctionExpression(p)) && p.name === node;
|
|
81048
|
+
if (!isCallee && !isNewCallee && !isOwnName) {
|
|
81049
|
+
const sym = ctx.checker.getSymbolAtLocation(node);
|
|
81050
|
+
const decl = sym?.valueDeclaration;
|
|
81051
|
+
if (decl && ts.isFunctionDeclaration(decl) && decl.name) {
|
|
81052
|
+
usedAsValue.add(decl.name.text);
|
|
81053
|
+
}
|
|
81054
|
+
}
|
|
81055
|
+
}
|
|
81056
|
+
ts.forEachChild(node, visit);
|
|
81057
|
+
};
|
|
81058
|
+
visit(sf);
|
|
81059
|
+
for (const name of usedAsValue) {
|
|
81060
|
+
const funcIdx = ctx.funcMap.get(name);
|
|
81061
|
+
if (funcIdx === void 0) continue;
|
|
81062
|
+
const caps = ctx.nestedFuncCaptures.get(name);
|
|
81063
|
+
if (caps && caps.length > 0) continue;
|
|
81064
|
+
const sig = getFuncSignature(ctx, funcIdx);
|
|
81065
|
+
if (!sig) continue;
|
|
81066
|
+
getOrCreateFuncRefWrapperTypes(ctx, sig.params, sig.results);
|
|
81067
|
+
}
|
|
81068
|
+
}
|
|
81202
81069
|
function tryEmitInlineDynamicCall(ctx, fctx, expr, isKnownVariable) {
|
|
81203
81070
|
if (!isKnownVariable) return null;
|
|
81071
|
+
ensureFuncValueWrappersRegistered(ctx, expr.getSourceFile());
|
|
81204
81072
|
const arity = expr.arguments.length;
|
|
81205
81073
|
const supported = (t) => {
|
|
81206
81074
|
if (t === null) return true;
|
|
@@ -85183,7 +85051,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
85183
85051
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
85184
85052
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
85185
85053
|
if (wasmFuncReturnsVoid(ctx, finalStaticIdx)) return VOID_RESULT;
|
|
85186
|
-
return
|
|
85054
|
+
return brandExternMethodResult(
|
|
85055
|
+
ctx,
|
|
85056
|
+
retType,
|
|
85057
|
+
getWasmFuncReturnType(ctx, finalStaticIdx) ?? resolveWasmType(ctx, retType)
|
|
85058
|
+
);
|
|
85187
85059
|
}
|
|
85188
85060
|
return VOID_RESULT;
|
|
85189
85061
|
}
|
|
@@ -85665,7 +85537,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
85665
85537
|
const retType = ctx.checker.getReturnTypeOfSignature(sig2);
|
|
85666
85538
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
85667
85539
|
if (wasmFuncReturnsVoid(ctx, finalMethodIdx2)) return VOID_RESULT;
|
|
85668
|
-
return
|
|
85540
|
+
return brandExternMethodResult(
|
|
85541
|
+
ctx,
|
|
85542
|
+
retType,
|
|
85543
|
+
getWasmFuncReturnType(ctx, finalMethodIdx2) ?? resolveWasmType(ctx, retType)
|
|
85544
|
+
);
|
|
85669
85545
|
}
|
|
85670
85546
|
return VOID_RESULT;
|
|
85671
85547
|
}
|
|
@@ -85699,7 +85575,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
85699
85575
|
if (sig2) {
|
|
85700
85576
|
const retType = ctx.checker.getReturnTypeOfSignature(sig2);
|
|
85701
85577
|
if (!isEffectivelyVoidReturn(ctx, retType, fullName))
|
|
85702
|
-
callReturnType =
|
|
85578
|
+
callReturnType = brandExternMethodResult(
|
|
85579
|
+
ctx,
|
|
85580
|
+
retType,
|
|
85581
|
+
getWasmFuncReturnType(ctx, funcIdx) ?? resolveWasmType(ctx, retType)
|
|
85582
|
+
);
|
|
85703
85583
|
}
|
|
85704
85584
|
const tmp = allocLocal(fctx, `__ng_recv_${fctx.locals.length}`, recvType);
|
|
85705
85585
|
fctx.body.push({ op: "local.tee", index: tmp });
|
|
@@ -85791,7 +85671,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
85791
85671
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
85792
85672
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
85793
85673
|
if (wasmFuncReturnsVoid(ctx, finalMethodIdx)) return VOID_RESULT;
|
|
85794
|
-
return
|
|
85674
|
+
return brandExternMethodResult(
|
|
85675
|
+
ctx,
|
|
85676
|
+
retType,
|
|
85677
|
+
getWasmFuncReturnType(ctx, finalMethodIdx) ?? resolveWasmType(ctx, retType)
|
|
85678
|
+
);
|
|
85795
85679
|
}
|
|
85796
85680
|
return VOID_RESULT;
|
|
85797
85681
|
}
|
|
@@ -85816,7 +85700,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
85816
85700
|
if (sig2) {
|
|
85817
85701
|
const retType = ctx.checker.getReturnTypeOfSignature(sig2);
|
|
85818
85702
|
if (!isEffectivelyVoidReturn(ctx, retType, fullName))
|
|
85819
|
-
callReturnType =
|
|
85703
|
+
callReturnType = brandExternMethodResult(
|
|
85704
|
+
ctx,
|
|
85705
|
+
retType,
|
|
85706
|
+
getWasmFuncReturnType(ctx, funcIdx) ?? resolveWasmType(ctx, retType)
|
|
85707
|
+
);
|
|
85820
85708
|
}
|
|
85821
85709
|
const tmp = allocLocal(fctx, `__ng_srecv_${fctx.locals.length}`, recvType);
|
|
85822
85710
|
fctx.body.push({ op: "local.tee", index: tmp });
|
|
@@ -85911,7 +85799,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
85911
85799
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
85912
85800
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
85913
85801
|
if (wasmFuncReturnsVoid(ctx, finalStructMethodIdx)) return VOID_RESULT;
|
|
85914
|
-
return
|
|
85802
|
+
return brandExternMethodResult(
|
|
85803
|
+
ctx,
|
|
85804
|
+
retType,
|
|
85805
|
+
getWasmFuncReturnType(ctx, finalStructMethodIdx) ?? resolveWasmType(ctx, retType)
|
|
85806
|
+
);
|
|
85915
85807
|
}
|
|
85916
85808
|
return VOID_RESULT;
|
|
85917
85809
|
}
|
|
@@ -86708,6 +86600,89 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
86708
86600
|
fctx.body.push({ op: "call", funcIdx: dispatchResolvedIdx });
|
|
86709
86601
|
return { kind: "externref" };
|
|
86710
86602
|
}
|
|
86603
|
+
if (!ctx.standalone && (methodName === "push" || methodName === "pop") && ctx.vecTypeMap.size > 0) {
|
|
86604
|
+
const mcIdx = ensureLateImport(
|
|
86605
|
+
ctx,
|
|
86606
|
+
"__extern_method_call",
|
|
86607
|
+
[{ kind: "externref" }, { kind: "externref" }, { kind: "externref" }],
|
|
86608
|
+
[{ kind: "externref" }]
|
|
86609
|
+
);
|
|
86610
|
+
const arrNewIdx = ensureLateImport(ctx, "__js_array_new", [], [{ kind: "externref" }]);
|
|
86611
|
+
const arrPushIdx = ensureLateImport(
|
|
86612
|
+
ctx,
|
|
86613
|
+
"__js_array_push",
|
|
86614
|
+
[{ kind: "externref" }, { kind: "externref" }],
|
|
86615
|
+
[]
|
|
86616
|
+
);
|
|
86617
|
+
const boxNumIdx = methodName === "push" ? ensureLateImport(ctx, "__box_number", [{ kind: "f64" }], [{ kind: "externref" }]) : void 0;
|
|
86618
|
+
addStringConstantGlobal(ctx, methodName);
|
|
86619
|
+
flushLateImportShifts(ctx, fctx);
|
|
86620
|
+
const vecOpIdx = reserveVecMethodHelper(ctx, methodName === "push" ? "push" : "pop");
|
|
86621
|
+
if (vecOpIdx !== void 0 && mcIdx !== void 0 && arrNewIdx !== void 0 && arrPushIdx !== void 0 && (methodName === "pop" || boxNumIdx !== void 0)) {
|
|
86622
|
+
const recvT = compileExpression$1(ctx, fctx, propAccess.expression, { kind: "externref" });
|
|
86623
|
+
if (recvT && recvT.kind !== "externref") coerceType$2(ctx, fctx, recvT, { kind: "externref" });
|
|
86624
|
+
else if (!recvT) fctx.body.push({ op: "ref.null.extern" });
|
|
86625
|
+
const recvLocal = allocLocal(fctx, `__nvm_recv_${fctx.locals.length}`, { kind: "externref" });
|
|
86626
|
+
fctx.body.push({ op: "local.set", index: recvLocal });
|
|
86627
|
+
let argLocal;
|
|
86628
|
+
if (methodName === "push") {
|
|
86629
|
+
const a = expr.arguments[0];
|
|
86630
|
+
if (a) {
|
|
86631
|
+
const at = compileExpression$1(ctx, fctx, a, { kind: "externref" });
|
|
86632
|
+
if (at && at.kind !== "externref") coerceType$2(ctx, fctx, at, { kind: "externref" });
|
|
86633
|
+
else if (!at) fctx.body.push({ op: "ref.null.extern" });
|
|
86634
|
+
} else {
|
|
86635
|
+
fctx.body.push({ op: "ref.null.extern" });
|
|
86636
|
+
}
|
|
86637
|
+
argLocal = allocLocal(fctx, `__nvm_arg_${fctx.locals.length}`, { kind: "externref" });
|
|
86638
|
+
fctx.body.push({ op: "local.set", index: argLocal });
|
|
86639
|
+
}
|
|
86640
|
+
const anyTmp = allocLocal(fctx, `__nvm_any_${fctx.locals.length}`, { kind: "anyref" });
|
|
86641
|
+
fctx.body.push({ op: "local.get", index: recvLocal });
|
|
86642
|
+
fctx.body.push({ op: "any.convert_extern" });
|
|
86643
|
+
fctx.body.push({ op: "local.set", index: anyTmp });
|
|
86644
|
+
let emitted = false;
|
|
86645
|
+
for (const vi of new Set(ctx.vecTypeMap.values())) {
|
|
86646
|
+
fctx.body.push({ op: "local.get", index: anyTmp });
|
|
86647
|
+
fctx.body.push({ op: "ref.test", typeIdx: vi });
|
|
86648
|
+
if (emitted) fctx.body.push({ op: "i32.or" });
|
|
86649
|
+
emitted = true;
|
|
86650
|
+
}
|
|
86651
|
+
const thenStart = fctx.body.length;
|
|
86652
|
+
if (methodName === "push") {
|
|
86653
|
+
fctx.body.push({ op: "local.get", index: recvLocal });
|
|
86654
|
+
fctx.body.push({ op: "local.get", index: argLocal });
|
|
86655
|
+
fctx.body.push({ op: "call", funcIdx: vecOpIdx });
|
|
86656
|
+
fctx.body.push({ op: "f64.convert_i32_s" });
|
|
86657
|
+
fctx.body.push({ op: "call", funcIdx: boxNumIdx });
|
|
86658
|
+
} else {
|
|
86659
|
+
fctx.body.push({ op: "local.get", index: recvLocal });
|
|
86660
|
+
fctx.body.push({ op: "call", funcIdx: vecOpIdx });
|
|
86661
|
+
}
|
|
86662
|
+
const thenInstrs = fctx.body.splice(thenStart);
|
|
86663
|
+
const elseStart = fctx.body.length;
|
|
86664
|
+
fctx.body.push({ op: "call", funcIdx: arrNewIdx });
|
|
86665
|
+
const argsLocal = allocLocal(fctx, `__nvm_args_${fctx.locals.length}`, { kind: "externref" });
|
|
86666
|
+
fctx.body.push({ op: "local.set", index: argsLocal });
|
|
86667
|
+
if (methodName === "push") {
|
|
86668
|
+
fctx.body.push({ op: "local.get", index: argsLocal });
|
|
86669
|
+
fctx.body.push({ op: "local.get", index: argLocal });
|
|
86670
|
+
fctx.body.push({ op: "call", funcIdx: arrPushIdx });
|
|
86671
|
+
}
|
|
86672
|
+
fctx.body.push({ op: "local.get", index: recvLocal });
|
|
86673
|
+
fctx.body.push(...stringConstantExternrefInstrs(ctx, methodName));
|
|
86674
|
+
fctx.body.push({ op: "local.get", index: argsLocal });
|
|
86675
|
+
fctx.body.push({ op: "call", funcIdx: mcIdx });
|
|
86676
|
+
const elseInstrs = fctx.body.splice(elseStart);
|
|
86677
|
+
fctx.body.push({
|
|
86678
|
+
op: "if",
|
|
86679
|
+
blockType: { kind: "val", type: { kind: "externref" } },
|
|
86680
|
+
then: thenInstrs,
|
|
86681
|
+
else: elseInstrs
|
|
86682
|
+
});
|
|
86683
|
+
return { kind: "externref" };
|
|
86684
|
+
}
|
|
86685
|
+
}
|
|
86711
86686
|
{
|
|
86712
86687
|
let arrNewIdx;
|
|
86713
86688
|
let arrPushIdx;
|
|
@@ -87842,7 +87817,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
87842
87817
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
87843
87818
|
if (isEffectivelyVoidReturn(ctx, retType, funcName)) return VOID_RESULT;
|
|
87844
87819
|
if (wasmFuncReturnsVoid(ctx, finalFuncIdx)) return VOID_RESULT;
|
|
87845
|
-
return
|
|
87820
|
+
return brandExternMethodResult(
|
|
87821
|
+
ctx,
|
|
87822
|
+
retType,
|
|
87823
|
+
getWasmFuncReturnType(ctx, finalFuncIdx) ?? resolveWasmType(ctx, retType)
|
|
87824
|
+
);
|
|
87846
87825
|
}
|
|
87847
87826
|
return getWasmFuncReturnType(ctx, finalFuncIdx) ?? { kind: "f64" };
|
|
87848
87827
|
}
|
|
@@ -88291,7 +88270,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
88291
88270
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
88292
88271
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
88293
88272
|
if (wasmFuncReturnsVoid(ctx, funcIdx)) return VOID_RESULT;
|
|
88294
|
-
return
|
|
88273
|
+
return brandExternMethodResult(
|
|
88274
|
+
ctx,
|
|
88275
|
+
retType,
|
|
88276
|
+
getWasmFuncReturnType(ctx, funcIdx) ?? resolveWasmType(ctx, retType)
|
|
88277
|
+
);
|
|
88295
88278
|
}
|
|
88296
88279
|
return VOID_RESULT;
|
|
88297
88280
|
}
|
|
@@ -88309,7 +88292,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
88309
88292
|
if (sig2) {
|
|
88310
88293
|
const retType = ctx.checker.getReturnTypeOfSignature(sig2);
|
|
88311
88294
|
if (!isEffectivelyVoidReturn(ctx, retType, fullName))
|
|
88312
|
-
callReturnType =
|
|
88295
|
+
callReturnType = brandExternMethodResult(
|
|
88296
|
+
ctx,
|
|
88297
|
+
retType,
|
|
88298
|
+
getWasmFuncReturnType(ctx, funcIdx) ?? resolveWasmType(ctx, retType)
|
|
88299
|
+
);
|
|
88313
88300
|
}
|
|
88314
88301
|
const tmp = allocLocal(fctx, `__ng_ea_recv_${fctx.locals.length}`, recvType);
|
|
88315
88302
|
fctx.body.push({ op: "local.tee", index: tmp });
|
|
@@ -88382,7 +88369,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
88382
88369
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
88383
88370
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
88384
88371
|
if (wasmFuncReturnsVoid(ctx, funcIdx)) return VOID_RESULT;
|
|
88385
|
-
return
|
|
88372
|
+
return brandExternMethodResult(
|
|
88373
|
+
ctx,
|
|
88374
|
+
retType,
|
|
88375
|
+
getWasmFuncReturnType(ctx, funcIdx) ?? resolveWasmType(ctx, retType)
|
|
88376
|
+
);
|
|
88386
88377
|
}
|
|
88387
88378
|
return VOID_RESULT;
|
|
88388
88379
|
}
|
|
@@ -88416,7 +88407,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
88416
88407
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
88417
88408
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
88418
88409
|
if (wasmFuncReturnsVoid(ctx, funcIdx)) return VOID_RESULT;
|
|
88419
|
-
return
|
|
88410
|
+
return brandExternMethodResult(
|
|
88411
|
+
ctx,
|
|
88412
|
+
retType,
|
|
88413
|
+
getWasmFuncReturnType(ctx, funcIdx) ?? resolveWasmType(ctx, retType)
|
|
88414
|
+
);
|
|
88420
88415
|
}
|
|
88421
88416
|
return VOID_RESULT;
|
|
88422
88417
|
}
|
|
@@ -88646,7 +88641,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
88646
88641
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
88647
88642
|
if (isEffectivelyVoidReturn(ctx, retType, funcName)) return VOID_RESULT;
|
|
88648
88643
|
if (wasmFuncReturnsVoid(ctx, finalFuncIdx)) return VOID_RESULT;
|
|
88649
|
-
return
|
|
88644
|
+
return brandExternMethodResult(
|
|
88645
|
+
ctx,
|
|
88646
|
+
retType,
|
|
88647
|
+
getWasmFuncReturnType(ctx, finalFuncIdx) ?? resolveWasmType(ctx, retType)
|
|
88648
|
+
);
|
|
88650
88649
|
}
|
|
88651
88650
|
return getWasmFuncReturnType(ctx, finalFuncIdx) ?? { kind: "f64" };
|
|
88652
88651
|
}
|
|
@@ -88693,7 +88692,11 @@ function compileCallExpression(ctx, fctx, expr, expectedType) {
|
|
|
88693
88692
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
88694
88693
|
if (isEffectivelyVoidReturn(ctx, retType, fullName)) return VOID_RESULT;
|
|
88695
88694
|
if (wasmFuncReturnsVoid(ctx, finalCallIdx)) return VOID_RESULT;
|
|
88696
|
-
return
|
|
88695
|
+
return brandExternMethodResult(
|
|
88696
|
+
ctx,
|
|
88697
|
+
retType,
|
|
88698
|
+
getWasmFuncReturnType(ctx, finalCallIdx) ?? resolveWasmType(ctx, retType)
|
|
88699
|
+
);
|
|
88697
88700
|
}
|
|
88698
88701
|
return VOID_RESULT;
|
|
88699
88702
|
}
|
|
@@ -89043,7 +89046,11 @@ function compileConditionalCallee(ctx, fctx, expr, condExpr) {
|
|
|
89043
89046
|
const retType = ctx.checker.getReturnTypeOfSignature(branchSigs[0]);
|
|
89044
89047
|
if (isEffectivelyVoidReturn(ctx, retType, funcName)) return VOID_RESULT;
|
|
89045
89048
|
if (wasmFuncReturnsVoid(ctx, finalFuncIdx)) return VOID_RESULT;
|
|
89046
|
-
return
|
|
89049
|
+
return brandExternMethodResult(
|
|
89050
|
+
ctx,
|
|
89051
|
+
retType,
|
|
89052
|
+
getWasmFuncReturnType(ctx, finalFuncIdx) ?? resolveWasmType(ctx, retType)
|
|
89053
|
+
);
|
|
89047
89054
|
}
|
|
89048
89055
|
return callRetType ?? getWasmFuncReturnType(ctx, finalFuncIdx) ?? { kind: "f64" };
|
|
89049
89056
|
}
|
|
@@ -91197,6 +91204,50 @@ function emitExternrefBackedOwnFieldWrite(ctx, fctx, target, value, fieldName) {
|
|
|
91197
91204
|
fctx.body.push({ op: "local.get", index: tmpBoxed });
|
|
91198
91205
|
return { kind: "externref" };
|
|
91199
91206
|
}
|
|
91207
|
+
function tryEmitPinnedStructMemberSet(ctx, fctx, target, value) {
|
|
91208
|
+
if (ts.isPrivateIdentifier(target.name)) return void 0;
|
|
91209
|
+
const propName = target.name.text;
|
|
91210
|
+
if (propName === "length" || propName === "constructor" || propName === "__proto__" || propName === "prototype" || propName === "name") {
|
|
91211
|
+
return void 0;
|
|
91212
|
+
}
|
|
91213
|
+
const accessType = ctx.checker.getTypeAtLocation(target);
|
|
91214
|
+
if (accessType.getCallSignatures && accessType.getCallSignatures().length > 0) return void 0;
|
|
91215
|
+
if (reserveMemberSetDispatch(
|
|
91216
|
+
ctx,
|
|
91217
|
+
propName,
|
|
91218
|
+
/*strict*/
|
|
91219
|
+
true,
|
|
91220
|
+
fctx
|
|
91221
|
+
) === void 0) return void 0;
|
|
91222
|
+
const objResult = compileExpression$1(ctx, fctx, target.expression);
|
|
91223
|
+
if (objResult && objResult.kind !== "externref") {
|
|
91224
|
+
coerceType$2(ctx, fctx, objResult, { kind: "externref" });
|
|
91225
|
+
} else if (!objResult) {
|
|
91226
|
+
fctx.body.push({ op: "ref.null.extern" });
|
|
91227
|
+
}
|
|
91228
|
+
const objLocal = allocLocal(fctx, `__pset_obj_${fctx.locals.length}`, { kind: "externref" });
|
|
91229
|
+
fctx.body.push({ op: "local.set", index: objLocal });
|
|
91230
|
+
const valResult = compileExpression$1(ctx, fctx, value);
|
|
91231
|
+
if (valResult && valResult.kind !== "externref") {
|
|
91232
|
+
coerceType$2(ctx, fctx, valResult, { kind: "externref" });
|
|
91233
|
+
} else if (!valResult) {
|
|
91234
|
+
fctx.body.push({ op: "ref.null.extern" });
|
|
91235
|
+
}
|
|
91236
|
+
const valLocal = allocLocal(fctx, `__pset_val_${fctx.locals.length}`, { kind: "externref" });
|
|
91237
|
+
fctx.body.push({ op: "local.set", index: valLocal });
|
|
91238
|
+
const dispatched = emitAlternateStructSetDispatch(
|
|
91239
|
+
ctx,
|
|
91240
|
+
fctx,
|
|
91241
|
+
objLocal,
|
|
91242
|
+
valLocal,
|
|
91243
|
+
propName,
|
|
91244
|
+
/*strict*/
|
|
91245
|
+
true
|
|
91246
|
+
);
|
|
91247
|
+
if (!dispatched) return void 0;
|
|
91248
|
+
fctx.body.push({ op: "local.get", index: valLocal });
|
|
91249
|
+
return { kind: "externref" };
|
|
91250
|
+
}
|
|
91200
91251
|
function compilePropertyAssignment(ctx, fctx, target, value) {
|
|
91201
91252
|
const objType = ctx.checker.getTypeAtLocation(target.expression);
|
|
91202
91253
|
{
|
|
@@ -91377,6 +91428,14 @@ function compilePropertyAssignment(ctx, fctx, target, value) {
|
|
|
91377
91428
|
return ctx.fast ? { kind: "i32" } : { kind: "f64" };
|
|
91378
91429
|
}
|
|
91379
91430
|
}
|
|
91431
|
+
{
|
|
91432
|
+
const pinnedThis = target.expression.kind === ts.SyntaxKind.ThisKeyword && fctx.thisStructName !== void 0 ? fctx.thisStructName : void 0;
|
|
91433
|
+
const pinned = pinnedThis ?? resolveReceiverStruct(ctx, fctx, target.expression);
|
|
91434
|
+
if (pinned !== void 0) {
|
|
91435
|
+
const pinnedSet = tryEmitPinnedStructMemberSet(ctx, fctx, target, value);
|
|
91436
|
+
if (pinnedSet !== void 0) return pinnedSet;
|
|
91437
|
+
}
|
|
91438
|
+
}
|
|
91380
91439
|
{
|
|
91381
91440
|
const dynPropName = ts.isPrivateIdentifier(target.name) ? "__priv_" + target.name.text.slice(1) : target.name.text;
|
|
91382
91441
|
const dynSet = tryEmitDeleteAwareDynamicSet(ctx, fctx, target, value, objType, dynPropName);
|
|
@@ -93555,17 +93614,23 @@ function compilePropertyCompoundAssignmentExternref(ctx, fctx, target, rhs, op,
|
|
|
93555
93614
|
kind: "externref"
|
|
93556
93615
|
});
|
|
93557
93616
|
fctx.body.push({ op: "local.set", index: keyLocal });
|
|
93617
|
+
const pinnedCompound = target.expression.kind === ts.SyntaxKind.ThisKeyword && fctx.thisStructName !== void 0 || resolveReceiverStruct(ctx, fctx, target.expression) !== void 0;
|
|
93558
93618
|
fctx.body.push({ op: "local.get", index: objLocal });
|
|
93559
|
-
|
|
93560
|
-
|
|
93561
|
-
|
|
93562
|
-
|
|
93563
|
-
|
|
93564
|
-
|
|
93565
|
-
|
|
93566
|
-
|
|
93567
|
-
|
|
93568
|
-
|
|
93619
|
+
const getDispIdx = pinnedCompound ? reserveMemberGetDispatch(ctx, propName, fctx) : void 0;
|
|
93620
|
+
if (getDispIdx !== void 0) {
|
|
93621
|
+
fctx.body.push({ op: "call", funcIdx: getDispIdx });
|
|
93622
|
+
} else {
|
|
93623
|
+
fctx.body.push({ op: "local.get", index: keyLocal });
|
|
93624
|
+
const getIdx = ensureLateImport(
|
|
93625
|
+
ctx,
|
|
93626
|
+
"__extern_get",
|
|
93627
|
+
[{ kind: "externref" }, { kind: "externref" }],
|
|
93628
|
+
[{ kind: "externref" }]
|
|
93629
|
+
);
|
|
93630
|
+
flushLateImportShifts(ctx, fctx);
|
|
93631
|
+
if (getIdx === void 0) return null;
|
|
93632
|
+
fctx.body.push({ op: "call", funcIdx: getIdx });
|
|
93633
|
+
}
|
|
93569
93634
|
addUnionImports(ctx);
|
|
93570
93635
|
const unboxIdx = ctx.funcMap.get("__unbox_number");
|
|
93571
93636
|
if (unboxIdx === void 0) {
|
|
@@ -93598,7 +93663,7 @@ function compilePropertyCompoundAssignmentExternref(ctx, fctx, target, rhs, op,
|
|
|
93598
93663
|
[]
|
|
93599
93664
|
);
|
|
93600
93665
|
flushLateImportShifts(ctx, fctx);
|
|
93601
|
-
const cmpdDispatched = emitAlternateStructSetDispatch(
|
|
93666
|
+
const cmpdDispatched = pinnedCompound && emitAlternateStructSetDispatch(
|
|
93602
93667
|
ctx,
|
|
93603
93668
|
fctx,
|
|
93604
93669
|
objLocal,
|
|
@@ -98664,18 +98729,7 @@ function compileStringBinaryOp(ctx, fctx, expr, op) {
|
|
|
98664
98729
|
}
|
|
98665
98730
|
}
|
|
98666
98731
|
} else if (op === ts.SyntaxKind.PlusToken && leftType && (leftType.kind === "ref" || leftType.kind === "ref_null")) {
|
|
98667
|
-
|
|
98668
|
-
const toStrIdx = ensureLateImport$1(
|
|
98669
|
-
ctx,
|
|
98670
|
-
"__extern_to_string_default",
|
|
98671
|
-
[{ kind: "externref" }],
|
|
98672
|
-
[{ kind: "externref" }]
|
|
98673
|
-
);
|
|
98674
|
-
flushLateImportShifts$1(ctx, fctx);
|
|
98675
|
-
const finalIdx = ctx.funcMap.get("__extern_to_string_default") ?? toStrIdx;
|
|
98676
|
-
if (finalIdx !== void 0) {
|
|
98677
|
-
fctx.body.push({ op: "call", funcIdx: finalIdx });
|
|
98678
|
-
}
|
|
98732
|
+
emitToString(ctx, fctx, leftType, leftTsType, "default");
|
|
98679
98733
|
}
|
|
98680
98734
|
const isEqOrNeq = op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken || op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsEqualsToken;
|
|
98681
98735
|
const isLeftStringWrapper = (leftTsType.flags & ts.TypeFlags.Object) !== 0 && leftTsType.getSymbol()?.name === "String";
|
|
@@ -98721,18 +98775,7 @@ function compileStringBinaryOp(ctx, fctx, expr, op) {
|
|
|
98721
98775
|
}
|
|
98722
98776
|
}
|
|
98723
98777
|
} else if (op === ts.SyntaxKind.PlusToken && rightType && (rightType.kind === "ref" || rightType.kind === "ref_null")) {
|
|
98724
|
-
|
|
98725
|
-
const toStrIdx = ensureLateImport$1(
|
|
98726
|
-
ctx,
|
|
98727
|
-
"__extern_to_string_default",
|
|
98728
|
-
[{ kind: "externref" }],
|
|
98729
|
-
[{ kind: "externref" }]
|
|
98730
|
-
);
|
|
98731
|
-
flushLateImportShifts$1(ctx, fctx);
|
|
98732
|
-
const finalIdx = ctx.funcMap.get("__extern_to_string_default") ?? toStrIdx;
|
|
98733
|
-
if (finalIdx !== void 0) {
|
|
98734
|
-
fctx.body.push({ op: "call", funcIdx: finalIdx });
|
|
98735
|
-
}
|
|
98778
|
+
emitToString(ctx, fctx, rightType, rightTsType, "default");
|
|
98736
98779
|
}
|
|
98737
98780
|
const isRightStringWrapper = (rightTsType.flags & ts.TypeFlags.Object) !== 0 && rightTsType.getSymbol()?.name === "String";
|
|
98738
98781
|
if (isEqOrNeq && isRightStringWrapper && rightType?.kind === "externref") {
|
|
@@ -100276,174 +100319,6 @@ function emitSymbolToString(ctx, fctx) {
|
|
|
100276
100319
|
compileNativeStringLiteral(ctx, fctx, ")");
|
|
100277
100320
|
fctx.body.push({ op: "call", funcIdx: concatIdx });
|
|
100278
100321
|
}
|
|
100279
|
-
function dispatcherName$1(propName, strict) {
|
|
100280
|
-
return strict ? `__set_member_${propName}` : `__set_member_nonstrict_${propName}`;
|
|
100281
|
-
}
|
|
100282
|
-
function reserveMemberSetDispatch(ctx, propName, strict) {
|
|
100283
|
-
const name = dispatcherName$1(propName, strict);
|
|
100284
|
-
const existing = ctx.funcMap.get(name);
|
|
100285
|
-
if (existing !== void 0) return existing;
|
|
100286
|
-
const fallbackName = strict ? "__extern_set_strict" : "__extern_set";
|
|
100287
|
-
const setIdx = ensureLateImport$1(
|
|
100288
|
-
ctx,
|
|
100289
|
-
fallbackName,
|
|
100290
|
-
[{ kind: "externref" }, { kind: "externref" }, { kind: "externref" }],
|
|
100291
|
-
[]
|
|
100292
|
-
);
|
|
100293
|
-
if (setIdx === void 0) return void 0;
|
|
100294
|
-
addStringConstantGlobal(ctx, propName);
|
|
100295
|
-
addUnionImportsViaRegistry(ctx);
|
|
100296
|
-
const typeIdx = addFuncType(ctx, [{ kind: "externref" }, { kind: "externref" }], [], "$member_set_dispatch_type");
|
|
100297
|
-
const funcIdx = ctx.numImportFuncs + ctx.mod.functions.length;
|
|
100298
|
-
ctx.mod.functions.push({
|
|
100299
|
-
name,
|
|
100300
|
-
typeIdx,
|
|
100301
|
-
locals: [],
|
|
100302
|
-
// Placeholder; filled by fillMemberSetDispatch. `unreachable` keeps the stub
|
|
100303
|
-
// valid (no results) if the fill is ever skipped (it never is — the fill
|
|
100304
|
-
// iterates the same name set this reserve populates).
|
|
100305
|
-
body: [{ op: "unreachable" }],
|
|
100306
|
-
exported: false
|
|
100307
|
-
});
|
|
100308
|
-
ctx.funcMap.set(name, funcIdx);
|
|
100309
|
-
(ctx.memberSetDispatchNames ??= /* @__PURE__ */ new Set()).add(`${propName}\0${strict ? "S" : "N"}`);
|
|
100310
|
-
return funcIdx;
|
|
100311
|
-
}
|
|
100312
|
-
function fillMemberSetDispatch(ctx) {
|
|
100313
|
-
const mod = ctx.mod;
|
|
100314
|
-
for (const key of ctx.memberSetDispatchNames ?? []) {
|
|
100315
|
-
const sep = key.lastIndexOf("\0");
|
|
100316
|
-
const propName = sep >= 0 ? key.slice(0, sep) : key;
|
|
100317
|
-
const strict = sep >= 0 ? key.slice(sep + 1) === "S" : true;
|
|
100318
|
-
const dispIdx = ctx.funcMap.get(dispatcherName$1(propName, strict));
|
|
100319
|
-
if (dispIdx === void 0) continue;
|
|
100320
|
-
const dispFn = mod.functions[dispIdx - ctx.numImportFuncs];
|
|
100321
|
-
if (!dispFn) continue;
|
|
100322
|
-
const candidates = findAlternateStructsForField(ctx, propName, -1).filter((c) => c.mutable);
|
|
100323
|
-
const fallbackIdx = ctx.funcMap.get(strict ? "__extern_set_strict" : "__extern_set");
|
|
100324
|
-
const fallback = fallbackIdx !== void 0 ? [
|
|
100325
|
-
{ op: "local.get", index: 0 },
|
|
100326
|
-
// recv
|
|
100327
|
-
...stringConstantExternrefInstrs(ctx, propName),
|
|
100328
|
-
{ op: "local.get", index: 1 },
|
|
100329
|
-
// val
|
|
100330
|
-
{ op: "call", funcIdx: fallbackIdx }
|
|
100331
|
-
] : [];
|
|
100332
|
-
const buildSetDispatch = (idx) => {
|
|
100333
|
-
if (idx >= candidates.length) return fallback;
|
|
100334
|
-
const cand = candidates[idx];
|
|
100335
|
-
const coerce = coercionInstrs(ctx, { kind: "externref" }, cand.fieldType);
|
|
100336
|
-
const setFieldInstrs = [
|
|
100337
|
-
{ op: "local.get", index: 2 },
|
|
100338
|
-
// __any
|
|
100339
|
-
{ op: "ref.cast", typeIdx: cand.structTypeIdx },
|
|
100340
|
-
{ op: "local.get", index: 1 },
|
|
100341
|
-
// val (externref)
|
|
100342
|
-
...coerce,
|
|
100343
|
-
{ op: "struct.set", typeIdx: cand.structTypeIdx, fieldIdx: cand.fieldIdx }
|
|
100344
|
-
];
|
|
100345
|
-
return [
|
|
100346
|
-
{ op: "local.get", index: 2 },
|
|
100347
|
-
// __any
|
|
100348
|
-
{ op: "ref.test", typeIdx: cand.structTypeIdx },
|
|
100349
|
-
{
|
|
100350
|
-
op: "if",
|
|
100351
|
-
blockType: { kind: "empty" },
|
|
100352
|
-
then: setFieldInstrs,
|
|
100353
|
-
else: buildSetDispatch(idx + 1)
|
|
100354
|
-
}
|
|
100355
|
-
];
|
|
100356
|
-
};
|
|
100357
|
-
dispFn.locals = [{ name: "__any", type: { kind: "anyref" } }];
|
|
100358
|
-
dispFn.body = [
|
|
100359
|
-
{ op: "local.get", index: 0 },
|
|
100360
|
-
// recv (externref)
|
|
100361
|
-
{ op: "any.convert_extern" },
|
|
100362
|
-
{ op: "local.set", index: 2 },
|
|
100363
|
-
// __any
|
|
100364
|
-
...buildSetDispatch(0)
|
|
100365
|
-
];
|
|
100366
|
-
}
|
|
100367
|
-
}
|
|
100368
|
-
function dispatcherName(propName) {
|
|
100369
|
-
return `__get_member_${propName}`;
|
|
100370
|
-
}
|
|
100371
|
-
function reserveMemberGetDispatch(ctx, propName, fctx) {
|
|
100372
|
-
const name = dispatcherName(propName);
|
|
100373
|
-
const existing = ctx.funcMap.get(name);
|
|
100374
|
-
if (existing !== void 0) return existing;
|
|
100375
|
-
const getIdx = ensureLateImport$1(
|
|
100376
|
-
ctx,
|
|
100377
|
-
"__extern_get",
|
|
100378
|
-
[{ kind: "externref" }, { kind: "externref" }],
|
|
100379
|
-
[{ kind: "externref" }]
|
|
100380
|
-
);
|
|
100381
|
-
if (getIdx === void 0) return void 0;
|
|
100382
|
-
addStringConstantGlobal(ctx, propName);
|
|
100383
|
-
addUnionImportsViaRegistry(ctx);
|
|
100384
|
-
const typeIdx = addFuncType(ctx, [{ kind: "externref" }], [{ kind: "externref" }], "$member_get_dispatch_type");
|
|
100385
|
-
const funcIdx = ctx.numImportFuncs + ctx.mod.functions.length;
|
|
100386
|
-
ctx.mod.functions.push({
|
|
100387
|
-
name,
|
|
100388
|
-
typeIdx,
|
|
100389
|
-
locals: [],
|
|
100390
|
-
body: [{ op: "unreachable" }],
|
|
100391
|
-
exported: false
|
|
100392
|
-
});
|
|
100393
|
-
ctx.funcMap.set(name, funcIdx);
|
|
100394
|
-
(ctx.memberGetDispatchNames ??= /* @__PURE__ */ new Set()).add(propName);
|
|
100395
|
-
if (fctx) flushLateImportShifts$1(ctx, fctx);
|
|
100396
|
-
return funcIdx;
|
|
100397
|
-
}
|
|
100398
|
-
function fillMemberGetDispatch(ctx) {
|
|
100399
|
-
const mod = ctx.mod;
|
|
100400
|
-
const getIdx = ctx.funcMap.get("__extern_get");
|
|
100401
|
-
for (const propName of ctx.memberGetDispatchNames ?? []) {
|
|
100402
|
-
const dispIdx = ctx.funcMap.get(dispatcherName(propName));
|
|
100403
|
-
if (dispIdx === void 0) continue;
|
|
100404
|
-
const dispFn = mod.functions[dispIdx - ctx.numImportFuncs];
|
|
100405
|
-
if (!dispFn) continue;
|
|
100406
|
-
const candidates = findAlternateStructsForField(ctx, propName, -1);
|
|
100407
|
-
const fallback = getIdx !== void 0 ? [
|
|
100408
|
-
{ op: "local.get", index: 0 },
|
|
100409
|
-
// recv
|
|
100410
|
-
...stringConstantExternrefInstrs(ctx, propName),
|
|
100411
|
-
{ op: "call", funcIdx: getIdx }
|
|
100412
|
-
] : [{ op: "ref.null.extern" }];
|
|
100413
|
-
const buildGetDispatch = (idx) => {
|
|
100414
|
-
if (idx >= candidates.length) return fallback;
|
|
100415
|
-
const cand = candidates[idx];
|
|
100416
|
-
const box = coercionInstrs(ctx, cand.fieldType, { kind: "externref" });
|
|
100417
|
-
const readInstrs = [
|
|
100418
|
-
{ op: "local.get", index: 1 },
|
|
100419
|
-
// __any
|
|
100420
|
-
{ op: "ref.cast", typeIdx: cand.structTypeIdx },
|
|
100421
|
-
{ op: "struct.get", typeIdx: cand.structTypeIdx, fieldIdx: cand.fieldIdx },
|
|
100422
|
-
...box
|
|
100423
|
-
];
|
|
100424
|
-
return [
|
|
100425
|
-
{ op: "local.get", index: 1 },
|
|
100426
|
-
// __any
|
|
100427
|
-
{ op: "ref.test", typeIdx: cand.structTypeIdx },
|
|
100428
|
-
{
|
|
100429
|
-
op: "if",
|
|
100430
|
-
blockType: { kind: "val", type: { kind: "externref" } },
|
|
100431
|
-
then: readInstrs,
|
|
100432
|
-
else: buildGetDispatch(idx + 1)
|
|
100433
|
-
}
|
|
100434
|
-
];
|
|
100435
|
-
};
|
|
100436
|
-
dispFn.locals = [{ name: "__any", type: { kind: "anyref" } }];
|
|
100437
|
-
dispFn.body = [
|
|
100438
|
-
{ op: "local.get", index: 0 },
|
|
100439
|
-
// recv (externref)
|
|
100440
|
-
{ op: "any.convert_extern" },
|
|
100441
|
-
{ op: "local.set", index: 1 },
|
|
100442
|
-
// __any
|
|
100443
|
-
...buildGetDispatch(0)
|
|
100444
|
-
];
|
|
100445
|
-
}
|
|
100446
|
-
}
|
|
100447
100322
|
const BUILTIN_CTOR_NAMES = /* @__PURE__ */ new Set([
|
|
100448
100323
|
"Object",
|
|
100449
100324
|
"Array",
|
|
@@ -101136,7 +101011,7 @@ function emitNullCheckThrow(ctx, fctx, refType, node) {
|
|
|
101136
101011
|
releaseTempLocal(fctx, tmp);
|
|
101137
101012
|
}
|
|
101138
101013
|
function emitAlternateStructSetDispatch(ctx, fctx, recvExtLocal, valExtLocal, propName, strict) {
|
|
101139
|
-
const dispIdx = reserveMemberSetDispatch(ctx, propName, strict);
|
|
101014
|
+
const dispIdx = reserveMemberSetDispatch(ctx, propName, strict, fctx);
|
|
101140
101015
|
if (dispIdx === void 0) return false;
|
|
101141
101016
|
fctx.body.push({ op: "local.get", index: recvExtLocal });
|
|
101142
101017
|
fctx.body.push({ op: "local.get", index: valExtLocal });
|
|
@@ -101624,6 +101499,40 @@ function emitGuardedNativeStringLength(ctx, fctx, buildElseInstrs) {
|
|
|
101624
101499
|
else: buildElseInstrs(recvExtern)
|
|
101625
101500
|
});
|
|
101626
101501
|
}
|
|
101502
|
+
function tryEmitPinnedStructMemberGet(ctx, fctx, expr, propName) {
|
|
101503
|
+
if (propName === "length" || propName === "constructor" || propName === "__proto__" || propName === "prototype" || propName === "name") {
|
|
101504
|
+
return void 0;
|
|
101505
|
+
}
|
|
101506
|
+
const accessType = ctx.checker.getTypeAtLocation(expr);
|
|
101507
|
+
if (accessType.getCallSignatures && accessType.getCallSignatures().length > 0) return void 0;
|
|
101508
|
+
const objResult = compileExpression$1(ctx, fctx, expr.expression);
|
|
101509
|
+
if (objResult && objResult.kind !== "externref") {
|
|
101510
|
+
coerceType$2(ctx, fctx, objResult, { kind: "externref" });
|
|
101511
|
+
} else if (!objResult) {
|
|
101512
|
+
fctx.body.push({ op: "ref.null.extern" });
|
|
101513
|
+
}
|
|
101514
|
+
const getDispIdx = reserveMemberGetDispatch(ctx, propName, fctx);
|
|
101515
|
+
if (getDispIdx === void 0) {
|
|
101516
|
+
const getIdx = ensureLateImport$1(
|
|
101517
|
+
ctx,
|
|
101518
|
+
"__extern_get",
|
|
101519
|
+
[{ kind: "externref" }, { kind: "externref" }],
|
|
101520
|
+
[{ kind: "externref" }]
|
|
101521
|
+
);
|
|
101522
|
+
flushLateImportShifts$1(ctx, fctx);
|
|
101523
|
+
if (getIdx === void 0) {
|
|
101524
|
+
fctx.body.push({ op: "drop" });
|
|
101525
|
+
fctx.body.push({ op: "ref.null.extern" });
|
|
101526
|
+
return { kind: "externref" };
|
|
101527
|
+
}
|
|
101528
|
+
addStringConstantGlobal(ctx, propName);
|
|
101529
|
+
fctx.body.push(...stringConstantExternrefInstrs(ctx, propName));
|
|
101530
|
+
fctx.body.push({ op: "call", funcIdx: getIdx });
|
|
101531
|
+
return { kind: "externref" };
|
|
101532
|
+
}
|
|
101533
|
+
fctx.body.push({ op: "call", funcIdx: getDispIdx });
|
|
101534
|
+
return { kind: "externref" };
|
|
101535
|
+
}
|
|
101627
101536
|
function tryEmitDeleteAwareDynamicGet(ctx, fctx, expr, objType, propName) {
|
|
101628
101537
|
if (!ctx.moduleUsesDelete || ctx.standalone) return void 0;
|
|
101629
101538
|
const isAnyOrUnknown2 = (objType.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
|
|
@@ -101639,17 +101548,35 @@ function tryEmitDeleteAwareDynamicGet(ctx, fctx, expr, objType, propName) {
|
|
|
101639
101548
|
[{ kind: "externref" }, { kind: "externref" }],
|
|
101640
101549
|
[{ kind: "externref" }]
|
|
101641
101550
|
);
|
|
101642
|
-
flushLateImportShifts$1(ctx, fctx);
|
|
101643
101551
|
if (getIdx === void 0) return void 0;
|
|
101552
|
+
const getMemberIdx = ctx.wasi ? void 0 : reserveMemberGetDispatch(ctx, propName, fctx);
|
|
101553
|
+
addStringConstantGlobal(ctx, propName);
|
|
101554
|
+
flushLateImportShifts$1(ctx, fctx);
|
|
101644
101555
|
const objResult = compileExpression$1(ctx, fctx, expr.expression);
|
|
101645
101556
|
if (objResult && objResult.kind !== "externref") {
|
|
101646
101557
|
coerceType$2(ctx, fctx, objResult, { kind: "externref" });
|
|
101647
101558
|
} else if (!objResult) {
|
|
101648
101559
|
fctx.body.push({ op: "ref.null.extern" });
|
|
101649
101560
|
}
|
|
101650
|
-
|
|
101651
|
-
|
|
101652
|
-
|
|
101561
|
+
if (getMemberIdx === void 0) {
|
|
101562
|
+
fctx.body.push(...stringConstantExternrefInstrs(ctx, propName));
|
|
101563
|
+
fctx.body.push({ op: "call", funcIdx: getIdx });
|
|
101564
|
+
return { kind: "externref" };
|
|
101565
|
+
}
|
|
101566
|
+
const flagGet = recordInModuleInitFlagRead(ctx);
|
|
101567
|
+
const recvLocal = allocLocal(fctx, `__dadg_recv_${fctx.locals.length}`, { kind: "externref" });
|
|
101568
|
+
fctx.body.push({ op: "local.set", index: recvLocal });
|
|
101569
|
+
fctx.body.push(flagGet);
|
|
101570
|
+
fctx.body.push({
|
|
101571
|
+
op: "if",
|
|
101572
|
+
blockType: { kind: "val", type: { kind: "externref" } },
|
|
101573
|
+
then: [{ op: "local.get", index: recvLocal }, { op: "call", funcIdx: getMemberIdx }],
|
|
101574
|
+
else: [
|
|
101575
|
+
{ op: "local.get", index: recvLocal },
|
|
101576
|
+
...stringConstantExternrefInstrs(ctx, propName),
|
|
101577
|
+
{ op: "call", funcIdx: getIdx }
|
|
101578
|
+
]
|
|
101579
|
+
});
|
|
101653
101580
|
return { kind: "externref" };
|
|
101654
101581
|
}
|
|
101655
101582
|
function tryEmitDeleteAwareDynamicSet(ctx, fctx, target, value, objType, propName) {
|
|
@@ -101809,6 +101736,14 @@ function compilePropertyAccess(ctx, fctx, expr) {
|
|
|
101809
101736
|
const fnctorProto = tryEmitFnctorPrototypeRead(ctx, fctx, expr, propName);
|
|
101810
101737
|
if (fnctorProto !== void 0) return fnctorProto;
|
|
101811
101738
|
}
|
|
101739
|
+
{
|
|
101740
|
+
const pinnedThis = expr.expression.kind === ts.SyntaxKind.ThisKeyword && fctx.thisStructName !== void 0 ? fctx.thisStructName : void 0;
|
|
101741
|
+
const pinned = pinnedThis ?? resolveReceiverStruct(ctx, fctx, expr.expression);
|
|
101742
|
+
if (pinned !== void 0) {
|
|
101743
|
+
const routed = tryEmitPinnedStructMemberGet(ctx, fctx, expr, propName);
|
|
101744
|
+
if (routed !== void 0) return routed;
|
|
101745
|
+
}
|
|
101746
|
+
}
|
|
101812
101747
|
{
|
|
101813
101748
|
const dyn = tryEmitDeleteAwareDynamicGet(ctx, fctx, expr, objType, propName);
|
|
101814
101749
|
if (dyn !== void 0) return dyn;
|
|
@@ -103577,6 +103512,9 @@ function f1ElementBoxType(ctx, expr, elementType) {
|
|
|
103577
103512
|
if (valueParts.every((p) => (p.flags & ts.TypeFlags.BooleanLike) !== 0)) {
|
|
103578
103513
|
return { kind: "i32", boolean: true };
|
|
103579
103514
|
}
|
|
103515
|
+
if (!noJsHost(ctx) && valueParts.every((p) => (p.flags & (ts.TypeFlags.ESSymbol | ts.TypeFlags.UniqueESSymbol)) !== 0)) {
|
|
103516
|
+
return { kind: "i32", symbol: true };
|
|
103517
|
+
}
|
|
103580
103518
|
return null;
|
|
103581
103519
|
}
|
|
103582
103520
|
function emitPlainArrayUndefinedOobGet(ctx, fctx, arrTypeIdx, elementType, boxType = elementType) {
|
|
@@ -103608,6 +103546,41 @@ function emitPlainArrayUndefinedOobGet(ctx, fctx, arrTypeIdx, elementType, boxTy
|
|
|
103608
103546
|
else: [{ op: "local.get", index: undefLocal }]
|
|
103609
103547
|
});
|
|
103610
103548
|
}
|
|
103549
|
+
function emitTypedArrayUndefinedOobGet(ctx, fctx, arrTypeIdx, elementType, signedness) {
|
|
103550
|
+
const idxLocal = allocLocal(fctx, `__taoob_idx_${fctx.locals.length}`, { kind: "i32" });
|
|
103551
|
+
const arrLocal = allocLocal(fctx, `__taoob_arr_${fctx.locals.length}`, { kind: "ref", typeIdx: arrTypeIdx });
|
|
103552
|
+
fctx.body.push({ op: "local.set", index: idxLocal });
|
|
103553
|
+
fctx.body.push({ op: "local.set", index: arrLocal });
|
|
103554
|
+
const inBoundsLocal = allocLocal(fctx, `__taoob_in_${fctx.locals.length}`, { kind: "i32" });
|
|
103555
|
+
fctx.body.push({ op: "local.get", index: idxLocal });
|
|
103556
|
+
fctx.body.push({ op: "local.get", index: arrLocal });
|
|
103557
|
+
fctx.body.push({ op: "array.len" });
|
|
103558
|
+
fctx.body.push({ op: "i32.lt_u" });
|
|
103559
|
+
fctx.body.push({ op: "local.set", index: inBoundsLocal });
|
|
103560
|
+
fctx.body.push({ op: "local.get", index: arrLocal });
|
|
103561
|
+
fctx.body.push({ op: "local.get", index: idxLocal });
|
|
103562
|
+
emitBoundsCheckedArrayGet(fctx, arrTypeIdx, elementType, ctx, false, signedness);
|
|
103563
|
+
if (elementType.kind === "i8" || elementType.kind === "i16") {
|
|
103564
|
+
fctx.body.push({ op: "f64.convert_i32_s" });
|
|
103565
|
+
} else if (elementType.kind === "i32") {
|
|
103566
|
+
fctx.body.push({ op: signedness === "u" ? "f64.convert_i32_u" : "f64.convert_i32_s" });
|
|
103567
|
+
} else if (elementType.kind === "f32") {
|
|
103568
|
+
fctx.body.push({ op: "f64.promote_f32" });
|
|
103569
|
+
}
|
|
103570
|
+
coerceType$2(ctx, fctx, { kind: "f64" }, { kind: "externref" });
|
|
103571
|
+
const boxedLocal = allocLocal(fctx, `__taoob_box_${fctx.locals.length}`, { kind: "externref" });
|
|
103572
|
+
fctx.body.push({ op: "local.set", index: boxedLocal });
|
|
103573
|
+
emitUndefined(ctx, fctx);
|
|
103574
|
+
const undefLocal = allocLocal(fctx, `__taoob_undef_${fctx.locals.length}`, { kind: "externref" });
|
|
103575
|
+
fctx.body.push({ op: "local.set", index: undefLocal });
|
|
103576
|
+
fctx.body.push({ op: "local.get", index: inBoundsLocal });
|
|
103577
|
+
fctx.body.push({
|
|
103578
|
+
op: "if",
|
|
103579
|
+
blockType: { kind: "val", type: { kind: "externref" } },
|
|
103580
|
+
then: [{ op: "local.get", index: boxedLocal }],
|
|
103581
|
+
else: [{ op: "local.get", index: undefLocal }]
|
|
103582
|
+
});
|
|
103583
|
+
}
|
|
103611
103584
|
function emitThisReceiverGuardConvert(ctx, fctx, targetTypeIdxs, resultType, thenEmit, elseEmit) {
|
|
103612
103585
|
const externrefTmp = allocTempLocal(fctx, { kind: "externref" });
|
|
103613
103586
|
fctx.body.push({ op: "local.tee", index: externrefTmp });
|
|
@@ -103910,6 +103883,55 @@ function isNumericIndexExpression(ctx, index) {
|
|
|
103910
103883
|
}
|
|
103911
103884
|
function compileElementAccessBody(ctx, fctx, expr, objType, expectedType) {
|
|
103912
103885
|
if (objType.kind === "externref") {
|
|
103886
|
+
if (!ctx.standalone && ctx.vecTypeMap.size > 0 && isNumericIndexExpression(ctx, expr.argumentExpression)) {
|
|
103887
|
+
const vecGetIdx = ctx.funcMap.get("__vec_get");
|
|
103888
|
+
const extGetIdx = ensureLateImport$1(
|
|
103889
|
+
ctx,
|
|
103890
|
+
"__extern_get",
|
|
103891
|
+
[{ kind: "externref" }, { kind: "externref" }],
|
|
103892
|
+
[{ kind: "externref" }]
|
|
103893
|
+
);
|
|
103894
|
+
const boxNumIdx = ensureLateImport$1(ctx, "__box_number", [{ kind: "f64" }], [{ kind: "externref" }]);
|
|
103895
|
+
flushLateImportShifts$1(ctx, fctx);
|
|
103896
|
+
const vgIdx = vecGetIdx ?? reserveVecMethodHelper(ctx, "get");
|
|
103897
|
+
if (vgIdx !== void 0 && extGetIdx !== void 0 && boxNumIdx !== void 0) {
|
|
103898
|
+
const recvLocal = allocLocal(fctx, `__nve_recv_${fctx.locals.length}`, { kind: "externref" });
|
|
103899
|
+
fctx.body.push({ op: "local.set", index: recvLocal });
|
|
103900
|
+
compileExpression$1(ctx, fctx, expr.argumentExpression, { kind: "f64" });
|
|
103901
|
+
const idxLocal = allocLocal(fctx, `__nve_idx_${fctx.locals.length}`, { kind: "f64" });
|
|
103902
|
+
fctx.body.push({ op: "local.set", index: idxLocal });
|
|
103903
|
+
const anyTmp = allocLocal(fctx, `__nve_any_${fctx.locals.length}`, { kind: "anyref" });
|
|
103904
|
+
fctx.body.push({ op: "local.get", index: recvLocal });
|
|
103905
|
+
fctx.body.push({ op: "any.convert_extern" });
|
|
103906
|
+
fctx.body.push({ op: "local.set", index: anyTmp });
|
|
103907
|
+
let emitted = false;
|
|
103908
|
+
for (const vi of new Set(ctx.vecTypeMap.values())) {
|
|
103909
|
+
fctx.body.push({ op: "local.get", index: anyTmp });
|
|
103910
|
+
fctx.body.push({ op: "ref.test", typeIdx: vi });
|
|
103911
|
+
if (emitted) fctx.body.push({ op: "i32.or" });
|
|
103912
|
+
emitted = true;
|
|
103913
|
+
}
|
|
103914
|
+
const thenStart = fctx.body.length;
|
|
103915
|
+
fctx.body.push({ op: "local.get", index: recvLocal });
|
|
103916
|
+
fctx.body.push({ op: "local.get", index: idxLocal });
|
|
103917
|
+
fctx.body.push({ op: "i32.trunc_sat_f64_s" });
|
|
103918
|
+
fctx.body.push({ op: "call", funcIdx: vgIdx });
|
|
103919
|
+
const thenInstrs = fctx.body.splice(thenStart);
|
|
103920
|
+
const elseStart = fctx.body.length;
|
|
103921
|
+
fctx.body.push({ op: "local.get", index: recvLocal });
|
|
103922
|
+
fctx.body.push({ op: "local.get", index: idxLocal });
|
|
103923
|
+
fctx.body.push({ op: "call", funcIdx: boxNumIdx });
|
|
103924
|
+
fctx.body.push({ op: "call", funcIdx: extGetIdx });
|
|
103925
|
+
const elseInstrs = fctx.body.splice(elseStart);
|
|
103926
|
+
fctx.body.push({
|
|
103927
|
+
op: "if",
|
|
103928
|
+
blockType: { kind: "val", type: { kind: "externref" } },
|
|
103929
|
+
then: thenInstrs,
|
|
103930
|
+
else: elseInstrs
|
|
103931
|
+
});
|
|
103932
|
+
return { kind: "externref" };
|
|
103933
|
+
}
|
|
103934
|
+
}
|
|
103913
103935
|
if (ctx.standalone && isNumericIndexExpression(ctx, expr.argumentExpression)) {
|
|
103914
103936
|
compileExpression$1(ctx, fctx, expr.argumentExpression, { kind: "f64" });
|
|
103915
103937
|
const getIdxFn = ensureLateImport$1(
|
|
@@ -104154,7 +104176,9 @@ function compileElementAccessBody(ctx, fctx, expr, objType, expectedType) {
|
|
|
104154
104176
|
const taSignedness = typedArrayViewSignedness(ctx, expr.expression);
|
|
104155
104177
|
const isRegexMatchVec = typeDef.fields.length >= 4 && typeDef.fields[2]?.name === "index";
|
|
104156
104178
|
const numericHint = expectedType?.kind === "f64" || expectedType?.kind === "i32";
|
|
104157
|
-
const
|
|
104179
|
+
const taClass = classifyTypedArrayType(ctx.checker.getTypeAtLocation(expr.expression), ctx.checker);
|
|
104180
|
+
const oobUndefined = !numericHint && taClass === "other" && !isRegexMatchVec;
|
|
104181
|
+
const oobUndefinedTypedArray = !numericHint && taClass !== "other";
|
|
104158
104182
|
const f1BoxType = f1ElementBoxType(ctx, expr, arrDef.element);
|
|
104159
104183
|
fctx.body.push({ op: "struct.get", typeIdx, fieldIdx: 1 });
|
|
104160
104184
|
compileExpression$1(ctx, fctx, expr.argumentExpression, { kind: "i32" });
|
|
@@ -104166,6 +104190,9 @@ function compileElementAccessBody(ctx, fctx, expr, objType, expectedType) {
|
|
|
104166
104190
|
} else if (oobUndefined && f1BoxType !== null) {
|
|
104167
104191
|
emitPlainArrayUndefinedOobGet(ctx, fctx, arrTypeIdx, arrDef.element, f1BoxType);
|
|
104168
104192
|
return { kind: "externref" };
|
|
104193
|
+
} else if (oobUndefinedTypedArray) {
|
|
104194
|
+
emitTypedArrayUndefinedOobGet(ctx, fctx, arrTypeIdx, arrDef.element, taSignedness);
|
|
104195
|
+
return { kind: "externref" };
|
|
104169
104196
|
} else {
|
|
104170
104197
|
emitBoundsCheckedArrayGet(fctx, arrTypeIdx, arrDef.element, ctx, false, taSignedness);
|
|
104171
104198
|
}
|
|
@@ -104180,7 +104207,10 @@ function compileElementAccessBody(ctx, fctx, expr, objType, expectedType) {
|
|
|
104180
104207
|
return null;
|
|
104181
104208
|
}
|
|
104182
104209
|
const taSignednessArr = typedArrayViewSignedness(ctx, expr.expression);
|
|
104183
|
-
const
|
|
104210
|
+
const numericHintArr = expectedType?.kind === "f64" || expectedType?.kind === "i32";
|
|
104211
|
+
const taClassArr = classifyTypedArrayType(ctx.checker.getTypeAtLocation(expr.expression), ctx.checker);
|
|
104212
|
+
const oobUndefinedArr = !numericHintArr && taClassArr === "other";
|
|
104213
|
+
const oobUndefinedTypedArrayArr = !numericHintArr && taClassArr !== "other";
|
|
104184
104214
|
const f1BoxTypeArr = f1ElementBoxType(ctx, expr, typeDef.element);
|
|
104185
104215
|
compileExpression$1(ctx, fctx, expr.argumentExpression, { kind: "i32" });
|
|
104186
104216
|
const valueType = typeDef.element.kind === "i8" || typeDef.element.kind === "i16" ? { kind: "i32" } : typeDef.element;
|
|
@@ -104191,6 +104221,9 @@ function compileElementAccessBody(ctx, fctx, expr, objType, expectedType) {
|
|
|
104191
104221
|
} else if (oobUndefinedArr && f1BoxTypeArr !== null) {
|
|
104192
104222
|
emitPlainArrayUndefinedOobGet(ctx, fctx, typeIdx, typeDef.element, f1BoxTypeArr);
|
|
104193
104223
|
return { kind: "externref" };
|
|
104224
|
+
} else if (oobUndefinedTypedArrayArr) {
|
|
104225
|
+
emitTypedArrayUndefinedOobGet(ctx, fctx, typeIdx, typeDef.element, taSignednessArr);
|
|
104226
|
+
return { kind: "externref" };
|
|
104194
104227
|
} else {
|
|
104195
104228
|
emitBoundsCheckedArrayGet(fctx, typeIdx, typeDef.element, ctx, false, taSignednessArr);
|
|
104196
104229
|
}
|
|
@@ -104972,6 +105005,12 @@ function _hasRuntimeComputedKey(ctx, expr) {
|
|
|
104972
105005
|
}
|
|
104973
105006
|
return false;
|
|
104974
105007
|
}
|
|
105008
|
+
function objectLiteralSpreadTakesHostPath(ctx, expr) {
|
|
105009
|
+
if (expr.properties.length === 0) return false;
|
|
105010
|
+
if (!expr.properties.some((p) => ts.isSpreadAssignment(p))) return false;
|
|
105011
|
+
const spreadCtxType = ctx.checker.getContextualType(expr);
|
|
105012
|
+
return !spreadCtxType || (spreadCtxType.flags & ts.TypeFlags.Any) !== 0 || (spreadCtxType.flags & ts.TypeFlags.Unknown) !== 0 || (spreadCtxType.flags & ts.TypeFlags.NonPrimitive) !== 0 || spreadCtxType.getProperties().length === 0;
|
|
105013
|
+
}
|
|
104975
105014
|
function compileObjectLiteral(ctx, fctx, expr) {
|
|
104976
105015
|
if (expr.properties.length > 0 && (expr.properties.some((p) => ts.isGetAccessorDeclaration(p) || ts.isSetAccessorDeclaration(p)) || _hasDisposalMethod(expr) || _hasRuntimeComputedKey(ctx, expr))) {
|
|
104977
105016
|
return compileObjectLiteralWithAccessors(ctx, fctx, expr);
|
|
@@ -104979,12 +105018,8 @@ function compileObjectLiteral(ctx, fctx, expr) {
|
|
|
104979
105018
|
if (expr.properties.length > 0 && _hasAccessorSpreadSource(ctx, expr)) {
|
|
104980
105019
|
return compileObjectLiteralWithAccessors(ctx, fctx, expr);
|
|
104981
105020
|
}
|
|
104982
|
-
if (
|
|
104983
|
-
|
|
104984
|
-
const nonSpecificCtx = !spreadCtxType || (spreadCtxType.flags & ts.TypeFlags.Any) !== 0 || (spreadCtxType.flags & ts.TypeFlags.Unknown) !== 0 || (spreadCtxType.flags & ts.TypeFlags.NonPrimitive) !== 0 || spreadCtxType.getProperties().length === 0;
|
|
104985
|
-
if (nonSpecificCtx) {
|
|
104986
|
-
return compileObjectLiteralWithAccessors(ctx, fctx, expr);
|
|
104987
|
-
}
|
|
105021
|
+
if (objectLiteralSpreadTakesHostPath(ctx, expr)) {
|
|
105022
|
+
return compileObjectLiteralWithAccessors(ctx, fctx, expr);
|
|
104988
105023
|
}
|
|
104989
105024
|
if (expr.properties.length === 0 && ts.isVariableDeclaration(expr.parent) && ts.isIdentifier(expr.parent.name)) {
|
|
104990
105025
|
const widenedProps = ctx.widenedTypeProperties.get(expr.parent.name.text);
|
|
@@ -113961,7 +113996,7 @@ function buildLocalCallGraph(decls, localClasses) {
|
|
|
113961
113996
|
if (!fn.body) continue;
|
|
113962
113997
|
const localBindings = collectLocalClosureBindings(fn);
|
|
113963
113998
|
const visit = (node) => {
|
|
113964
|
-
if (node !== fn && isFunctionLike(node)) return;
|
|
113999
|
+
if (node !== fn && isFunctionLike$1(node)) return;
|
|
113965
114000
|
if (ts.isNewExpression(node)) {
|
|
113966
114001
|
if (ts.isIdentifier(node.expression) && (localClasses.has(node.expression.text) || isKnownExternClass(node.expression.text))) {
|
|
113967
114002
|
if (node.arguments) {
|
|
@@ -114016,7 +114051,7 @@ function collectLocalClosureBindings(fn) {
|
|
|
114016
114051
|
const names = /* @__PURE__ */ new Set();
|
|
114017
114052
|
if (!fn.body) return names;
|
|
114018
114053
|
const visit = (node) => {
|
|
114019
|
-
if (node !== fn && isFunctionLike(node)) return;
|
|
114054
|
+
if (node !== fn && isFunctionLike$1(node)) return;
|
|
114020
114055
|
if (ts.isFunctionDeclaration(node) && node !== fn && node.name) {
|
|
114021
114056
|
names.add(node.name.text);
|
|
114022
114057
|
}
|
|
@@ -114035,7 +114070,7 @@ function collectLocalClosureBindings(fn) {
|
|
|
114035
114070
|
forEachChild$1(fn.body, visit);
|
|
114036
114071
|
return names;
|
|
114037
114072
|
}
|
|
114038
|
-
function isFunctionLike(node) {
|
|
114073
|
+
function isFunctionLike$1(node) {
|
|
114039
114074
|
return ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node) || ts.isClassDeclaration(node) || ts.isClassExpression(node);
|
|
114040
114075
|
}
|
|
114041
114076
|
function lowerFunctionAstToIr(fn, options = {}) {
|
|
@@ -114394,8 +114429,9 @@ function lowerVarDecl(stmt, cx) {
|
|
|
114394
114429
|
}
|
|
114395
114430
|
}
|
|
114396
114431
|
if (!proveUnboxedNumberLocal(d.name, inferred, cx)) {
|
|
114432
|
+
const boundKind = asVal(inferred)?.kind === "i32" ? "i32" : "f64";
|
|
114397
114433
|
throw new Error(
|
|
114398
|
-
`ir/from-ast: local '${name}' is bound as an unboxed
|
|
114434
|
+
`ir/from-ast: local '${name}' is bound as an unboxed ${boundKind} but its TS type is not provably a pure number${boundKind === "i32" ? " or boolean" : ""} — keeping the no-box number representation is unsound (the ${boundKind} Wasm kind conflates number / boolean / any); demote to the SAFE boxed legacy lowering in ${cx.funcName} (#2782/#2790)`
|
|
114399
114435
|
);
|
|
114400
114436
|
}
|
|
114401
114437
|
if (!isConst && cx.mutatedLets.has(name)) {
|
|
@@ -116063,12 +116099,21 @@ function proveAdditiveOperand(node, cx) {
|
|
|
116063
116099
|
if (!checker) return "no-checker";
|
|
116064
116100
|
return classifyPrimitiveProof(checker.getTypeAtLocation(node));
|
|
116065
116101
|
}
|
|
116102
|
+
function isProvablyBoolean(t) {
|
|
116103
|
+
if (t.isUnion()) {
|
|
116104
|
+
return t.types.length > 0 && t.types.every(isProvablyBoolean);
|
|
116105
|
+
}
|
|
116106
|
+
return (t.flags & ts.TypeFlags.BooleanLike) !== 0;
|
|
116107
|
+
}
|
|
116066
116108
|
function proveUnboxedNumberLocal(name, boundType, cx) {
|
|
116067
116109
|
const bv = asVal(boundType);
|
|
116068
|
-
if (!bv || bv.kind !== "f64") return true;
|
|
116110
|
+
if (!bv || bv.kind !== "f64" && bv.kind !== "i32") return true;
|
|
116069
116111
|
const checker = cx.checker;
|
|
116070
116112
|
if (!checker) return true;
|
|
116071
|
-
|
|
116113
|
+
const tsType = checker.getTypeAtLocation(name);
|
|
116114
|
+
if (classifyPrimitiveProof(tsType) === "number") return true;
|
|
116115
|
+
if (bv.kind === "f64") return false;
|
|
116116
|
+
return isProvablyBoolean(tsType);
|
|
116072
116117
|
}
|
|
116073
116118
|
function lowerBinary(expr, cx, hint) {
|
|
116074
116119
|
const op = expr.operatorToken.kind;
|
|
@@ -124027,6 +124072,7 @@ function walkBodyForReturns(body, paramScope, entries, cb) {
|
|
|
124027
124072
|
function createCodegenContext(mod, checker, options) {
|
|
124028
124073
|
const strictNoHostImports = options?.strictNoHostImports ?? options?.wasi ?? false;
|
|
124029
124074
|
const nativeStrings = options?.nativeStrings ?? !!(options?.fast || options?.wasi || options?.standalone || strictNoHostImports || options?.utf8Storage);
|
|
124075
|
+
const linkedNamespaces = new Set(options?.wasi ? options?.link ?? [] : []);
|
|
124030
124076
|
const ctx = {
|
|
124031
124077
|
mod,
|
|
124032
124078
|
checker,
|
|
@@ -124090,6 +124136,10 @@ function createCodegenContext(mod, checker, options) {
|
|
|
124090
124136
|
// (#2001 S1) $Hole struct type; lazily registered
|
|
124091
124137
|
holeGlobalIdx: void 0,
|
|
124092
124138
|
// (#2001 S1) $__hole singleton global
|
|
124139
|
+
inModuleInitFlagReads: void 0,
|
|
124140
|
+
// (#2800) recorded __in_module_init flag reads
|
|
124141
|
+
inModuleInitGlobalIdx: void 0,
|
|
124142
|
+
// (#2800) __in_module_init flag global (set at finalize)
|
|
124093
124143
|
usesDynRead: false,
|
|
124094
124144
|
// (#2580 M0) set by a __dyn_has/__dyn_get call site (M1+); M0 adds none
|
|
124095
124145
|
dynReadHelpersEmitted: false,
|
|
@@ -124235,11 +124285,17 @@ function createCodegenContext(mod, checker, options) {
|
|
|
124235
124285
|
// (#2025)
|
|
124236
124286
|
funcClosureGlobals: /* @__PURE__ */ new Map(),
|
|
124237
124287
|
wasi: options?.wasi ?? false,
|
|
124238
|
-
// #
|
|
124239
|
-
|
|
124288
|
+
// #2783 — namespaces left as link-time imports (WASI-gated above).
|
|
124289
|
+
linkedNamespaces,
|
|
124290
|
+
// #2625/#2783 — the linkable js2wasm:node-<mod> std-IO path only applies under
|
|
124291
|
+
// WASI; derived from `node:fs` membership in the (already WASI-gated) link set.
|
|
124292
|
+
linkNodeShims: linkedNamespaces.has("node:fs"),
|
|
124240
124293
|
nodeFsReadSyncIdx: -1,
|
|
124241
124294
|
nodeFsWriteSyncIdx: -1,
|
|
124242
124295
|
standalone: options?.standalone ?? false,
|
|
124296
|
+
// (#2796) Diff-test-harness fidelity — export __module_init + skip the wasm
|
|
124297
|
+
// start section so the host runs top-level code after setExports.
|
|
124298
|
+
deferTopLevelInit: options?.deferTopLevelInit ?? false,
|
|
124243
124299
|
// #682 — native standalone RegExp engine hook. Standalone mode enables the
|
|
124244
124300
|
// reduced literal-substring backend; broader QuickJS libregexp ABI linking
|
|
124245
124301
|
// remains the follow-up path for near-JS parity.
|
|
@@ -130319,9 +130375,14 @@ function isI32SafeExprForArray(expr, i32Locals, depth = 0) {
|
|
|
130319
130375
|
}
|
|
130320
130376
|
if (ts.isPrefixUnaryExpression(expr)) {
|
|
130321
130377
|
const op = expr.operator;
|
|
130322
|
-
if (op === ts.SyntaxKind.PlusToken || op === ts.SyntaxKind.
|
|
130378
|
+
if (op === ts.SyntaxKind.PlusToken || op === ts.SyntaxKind.TildeToken) {
|
|
130323
130379
|
return isI32SafeExprForArray(expr.operand, i32Locals, depth + 1);
|
|
130324
130380
|
}
|
|
130381
|
+
if (op === ts.SyntaxKind.MinusToken) {
|
|
130382
|
+
if (!ts.isNumericLiteral(expr.operand)) return false;
|
|
130383
|
+
if (!isI32SafeExprForArray(expr.operand, i32Locals, depth + 1)) return false;
|
|
130384
|
+
return Number(expr.operand.text.replace(/_/g, "")) !== 0;
|
|
130385
|
+
}
|
|
130325
130386
|
return false;
|
|
130326
130387
|
}
|
|
130327
130388
|
if (ts.isBinaryExpression(expr)) {
|
|
@@ -130333,7 +130394,7 @@ function isI32SafeExprForArray(expr, i32Locals, depth = 0) {
|
|
|
130333
130394
|
return true;
|
|
130334
130395
|
}
|
|
130335
130396
|
if (op === ts.SyntaxKind.PlusToken || op === ts.SyntaxKind.MinusToken || op === ts.SyntaxKind.AsteriskToken) {
|
|
130336
|
-
return
|
|
130397
|
+
return false;
|
|
130337
130398
|
}
|
|
130338
130399
|
return false;
|
|
130339
130400
|
}
|
|
@@ -130439,7 +130500,7 @@ function collectI32SpecializedArrays(decl, i32CoercedLocals) {
|
|
|
130439
130500
|
if (ts.isBinaryExpression(node) && node.operatorToken.kind !== ts.SyntaxKind.EqualsToken && isCompoundAssignment(node.operatorToken.kind) && ts.isElementAccessExpression(node.left) && ts.isIdentifier(node.left.expression) && candidates.has(node.left.expression.text)) {
|
|
130440
130501
|
const arrName = node.left.expression.text;
|
|
130441
130502
|
const isBitwiseCompound = node.operatorToken.kind === ts.SyntaxKind.BarEqualsToken || node.operatorToken.kind === ts.SyntaxKind.AmpersandEqualsToken || node.operatorToken.kind === ts.SyntaxKind.CaretEqualsToken || node.operatorToken.kind === ts.SyntaxKind.LessThanLessThanEqualsToken || node.operatorToken.kind === ts.SyntaxKind.GreaterThanGreaterThanEqualsToken;
|
|
130442
|
-
if (!isBitwiseCompound
|
|
130503
|
+
if (!isBitwiseCompound) {
|
|
130443
130504
|
disqualified.add(arrName);
|
|
130444
130505
|
}
|
|
130445
130506
|
}
|
|
@@ -132693,9 +132754,52 @@ function inferNumericReturnTypes(ctx, sourceFile) {
|
|
|
132693
132754
|
}
|
|
132694
132755
|
}
|
|
132695
132756
|
}
|
|
132757
|
+
const isBooleanExpr = (expr, depth = 0) => {
|
|
132758
|
+
if (depth > MAX_NUMERIC_DEPTH) return false;
|
|
132759
|
+
if (ts.isParenthesizedExpression(expr)) return isBooleanExpr(expr.expression, depth + 1);
|
|
132760
|
+
if (ts.isAsExpression(expr) || ts.isTypeAssertionExpression(expr) || ts.isNonNullExpression(expr)) {
|
|
132761
|
+
return isBooleanExpr(expr.expression, depth + 1);
|
|
132762
|
+
}
|
|
132763
|
+
if (expr.kind === ts.SyntaxKind.TrueKeyword || expr.kind === ts.SyntaxKind.FalseKeyword) return true;
|
|
132764
|
+
if (ts.isPrefixUnaryExpression(expr)) {
|
|
132765
|
+
return expr.operator === ts.SyntaxKind.ExclamationToken;
|
|
132766
|
+
}
|
|
132767
|
+
if (ts.isBinaryExpression(expr)) {
|
|
132768
|
+
const op = expr.operatorToken.kind;
|
|
132769
|
+
if (op === ts.SyntaxKind.LessThanToken || op === ts.SyntaxKind.LessThanEqualsToken || op === ts.SyntaxKind.GreaterThanToken || op === ts.SyntaxKind.GreaterThanEqualsToken || op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsToken || op === ts.SyntaxKind.EqualsEqualsEqualsToken || op === ts.SyntaxKind.ExclamationEqualsEqualsToken || op === ts.SyntaxKind.InstanceOfKeyword || op === ts.SyntaxKind.InKeyword) {
|
|
132770
|
+
return true;
|
|
132771
|
+
}
|
|
132772
|
+
if (op === ts.SyntaxKind.AmpersandAmpersandToken || op === ts.SyntaxKind.BarBarToken) {
|
|
132773
|
+
return isBooleanExpr(expr.left, depth + 1) && isBooleanExpr(expr.right, depth + 1);
|
|
132774
|
+
}
|
|
132775
|
+
return false;
|
|
132776
|
+
}
|
|
132777
|
+
if (ts.isConditionalExpression(expr)) {
|
|
132778
|
+
return isBooleanExpr(expr.whenTrue, depth + 1) && isBooleanExpr(expr.whenFalse, depth + 1);
|
|
132779
|
+
}
|
|
132780
|
+
if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression)) {
|
|
132781
|
+
if (boolean.has(expr.expression.text)) return true;
|
|
132782
|
+
if (expr.expression.text === "Boolean") return true;
|
|
132783
|
+
return false;
|
|
132784
|
+
}
|
|
132785
|
+
return false;
|
|
132786
|
+
};
|
|
132787
|
+
const boolean = new Set(numeric);
|
|
132788
|
+
let bChanged = true;
|
|
132789
|
+
let bSafety = boolean.size + 1;
|
|
132790
|
+
while (bChanged && bSafety-- > 0) {
|
|
132791
|
+
bChanged = false;
|
|
132792
|
+
for (const fnName of [...boolean]) {
|
|
132793
|
+
const info = fnInfo.get(fnName);
|
|
132794
|
+
if (!info.returns.every((r) => isBooleanExpr(r))) {
|
|
132795
|
+
boolean.delete(fnName);
|
|
132796
|
+
bChanged = true;
|
|
132797
|
+
}
|
|
132798
|
+
}
|
|
132799
|
+
}
|
|
132696
132800
|
const result = /* @__PURE__ */ new Map();
|
|
132697
132801
|
for (const fnName of numeric) {
|
|
132698
|
-
result.set(fnName, { kind: "f64" });
|
|
132802
|
+
result.set(fnName, boolean.has(fnName) ? { kind: "i32", boolean: true } : { kind: "f64" });
|
|
132699
132803
|
}
|
|
132700
132804
|
return result;
|
|
132701
132805
|
}
|
|
@@ -133715,6 +133819,12 @@ function collectDeclarations(ctx, sourceFile, isEntryFile = true) {
|
|
|
133715
133819
|
}
|
|
133716
133820
|
}
|
|
133717
133821
|
}
|
|
133822
|
+
if (decl.initializer.properties.some((p) => ts.isSpreadAssignment(p))) {
|
|
133823
|
+
const spreadCtxType = ctx.checker.getContextualType(decl.initializer);
|
|
133824
|
+
if (!spreadCtxType || (spreadCtxType.flags & ts.TypeFlags.Any) !== 0 || (spreadCtxType.flags & ts.TypeFlags.Unknown) !== 0 || (spreadCtxType.flags & ts.TypeFlags.NonPrimitive) !== 0 || spreadCtxType.getProperties().length === 0) {
|
|
133825
|
+
return true;
|
|
133826
|
+
}
|
|
133827
|
+
}
|
|
133718
133828
|
return false;
|
|
133719
133829
|
}
|
|
133720
133830
|
function moduleGlobalWasmType(decl, varType) {
|
|
@@ -134256,6 +134366,7 @@ function compileDeclarations(ctx, sourceFile) {
|
|
|
134256
134366
|
ctx.pendingInitBody = null;
|
|
134257
134367
|
if (compiledInitFctx && compiledInitFctx.body.length > 0) {
|
|
134258
134368
|
ctx.mod.hasTopLevelStatements = true;
|
|
134369
|
+
const exportModuleInit = ctx.deferTopLevelInit && !ctx.wasi;
|
|
134259
134370
|
const initTypeIdx = addFuncType(ctx, [], [], "__module_init_type");
|
|
134260
134371
|
const initFuncIdx = ctx.numImportFuncs + ctx.mod.functions.length;
|
|
134261
134372
|
ctx.mod.functions.push({
|
|
@@ -134263,9 +134374,15 @@ function compileDeclarations(ctx, sourceFile) {
|
|
|
134263
134374
|
typeIdx: initTypeIdx,
|
|
134264
134375
|
locals: compiledInitFctx.locals,
|
|
134265
134376
|
body: compiledInitFctx.body,
|
|
134266
|
-
exported:
|
|
134377
|
+
exported: exportModuleInit
|
|
134267
134378
|
});
|
|
134268
|
-
if (
|
|
134379
|
+
if (exportModuleInit) {
|
|
134380
|
+
ctx.mod.exports.push({
|
|
134381
|
+
name: "__module_init",
|
|
134382
|
+
desc: { kind: "func", index: initFuncIdx }
|
|
134383
|
+
});
|
|
134384
|
+
}
|
|
134385
|
+
if (!ctx.wasi && !exportModuleInit) {
|
|
134269
134386
|
ctx.mod.startFuncIdx = initFuncIdx;
|
|
134270
134387
|
}
|
|
134271
134388
|
}
|
|
@@ -134976,6 +135093,7 @@ function generateModule(ast, options) {
|
|
|
134976
135093
|
fillExternGetIdxVecArms(ctx);
|
|
134977
135094
|
fillArrayToPrimitive(ctx);
|
|
134978
135095
|
emitIsClosureExport(ctx);
|
|
135096
|
+
emitIsDataStructExport(ctx);
|
|
134979
135097
|
fillStandaloneTypeofClosureArms(ctx);
|
|
134980
135098
|
emitToPrimitiveMethodExports(ctx);
|
|
134981
135099
|
fillClassToPrimitive(ctx);
|
|
@@ -134991,6 +135109,7 @@ function generateModule(ast, options) {
|
|
|
134991
135109
|
});
|
|
134992
135110
|
}
|
|
134993
135111
|
ensureDynReadHelpers(ctx);
|
|
135112
|
+
finalizeInModuleInitFlag(ctx);
|
|
134994
135113
|
markLeafStructsFinal(mod, ctx.wasi);
|
|
134995
135114
|
eliminateDeadImports(mod, ctx);
|
|
134996
135115
|
repairStructTypeMismatches(mod);
|
|
@@ -135012,7 +135131,7 @@ function generateModule(ast, options) {
|
|
|
135012
135131
|
}
|
|
135013
135132
|
function assertNoLeakedHostImports(ctx, mod) {
|
|
135014
135133
|
if (!ctx.strictNoHostImports) return;
|
|
135015
|
-
const leaks = scanForLeakedHostImports(mod.imports);
|
|
135134
|
+
const leaks = scanForLeakedHostImports(mod.imports, ctx.linkedNamespaces);
|
|
135016
135135
|
for (const leak of leaks) {
|
|
135017
135136
|
reportErrorNoNode(ctx, buildLeakedHostImportError(leak));
|
|
135018
135137
|
}
|
|
@@ -135029,6 +135148,35 @@ function drainStackBalanceTelemetry(ctx, fileLabel) {
|
|
|
135029
135148
|
ctx.errors.push({ message: diag.message, line: diag.line, column: diag.column, severity: diag.severity });
|
|
135030
135149
|
}
|
|
135031
135150
|
}
|
|
135151
|
+
function finalizeInModuleInitFlag(ctx) {
|
|
135152
|
+
const reads = ctx.inModuleInitFlagReads;
|
|
135153
|
+
if (!reads || reads.length === 0) return;
|
|
135154
|
+
const flagIdx = ctx.numImportGlobals + ctx.mod.globals.length;
|
|
135155
|
+
ctx.mod.globals.push({
|
|
135156
|
+
name: "__in_module_init",
|
|
135157
|
+
type: { kind: "i32" },
|
|
135158
|
+
mutable: true,
|
|
135159
|
+
init: [{ op: "i32.const", value: 0 }]
|
|
135160
|
+
});
|
|
135161
|
+
ctx.inModuleInitGlobalIdx = flagIdx;
|
|
135162
|
+
for (const r of reads) r.index = flagIdx;
|
|
135163
|
+
let initArrayIdx = -1;
|
|
135164
|
+
for (let i = 0; i < ctx.mod.functions.length; i++) {
|
|
135165
|
+
if (ctx.mod.functions[i].name === "__module_init") {
|
|
135166
|
+
initArrayIdx = i;
|
|
135167
|
+
break;
|
|
135168
|
+
}
|
|
135169
|
+
}
|
|
135170
|
+
if (initArrayIdx < 0) return;
|
|
135171
|
+
const initFn = ctx.mod.functions[initArrayIdx];
|
|
135172
|
+
initFn.body = [
|
|
135173
|
+
{ op: "i32.const", value: 1 },
|
|
135174
|
+
{ op: "global.set", index: flagIdx },
|
|
135175
|
+
...initFn.body,
|
|
135176
|
+
{ op: "i32.const", value: 0 },
|
|
135177
|
+
{ op: "global.set", index: flagIdx }
|
|
135178
|
+
];
|
|
135179
|
+
}
|
|
135032
135180
|
function applyModuleInitGuard(ctx) {
|
|
135033
135181
|
if (ctx.moduleInitGuardApplied) return;
|
|
135034
135182
|
let initArrayIdx = -1;
|
|
@@ -136196,6 +136344,50 @@ function emitIsClosureExport(ctx) {
|
|
|
136196
136344
|
desc: { kind: "func", index: funcIdx }
|
|
136197
136345
|
});
|
|
136198
136346
|
}
|
|
136347
|
+
function emitIsDataStructExport(ctx) {
|
|
136348
|
+
const mod = ctx.mod;
|
|
136349
|
+
const dataTypeIdxs = [];
|
|
136350
|
+
const seen = /* @__PURE__ */ new Set();
|
|
136351
|
+
for (const [structName] of ctx.structFields) {
|
|
136352
|
+
if (structName.startsWith("Wrapper") || structName === "$AnyValue" || structName.startsWith("__vec_") || structName.startsWith("__arr_"))
|
|
136353
|
+
continue;
|
|
136354
|
+
const typeIdx = ctx.structMap.get(structName);
|
|
136355
|
+
if (typeIdx === void 0 || seen.has(typeIdx)) continue;
|
|
136356
|
+
const typeDef = mod.types[typeIdx];
|
|
136357
|
+
if (!typeDef || typeDef.kind !== "struct") continue;
|
|
136358
|
+
seen.add(typeIdx);
|
|
136359
|
+
dataTypeIdxs.push(typeIdx);
|
|
136360
|
+
}
|
|
136361
|
+
if (dataTypeIdxs.length === 0) return;
|
|
136362
|
+
const isDataTypeIdx = addFuncType(ctx, [{ kind: "externref" }], [{ kind: "i32" }], "$is_data_struct_type");
|
|
136363
|
+
const funcIdx = ctx.numImportFuncs + mod.functions.length;
|
|
136364
|
+
const body = [
|
|
136365
|
+
{ op: "local.get", index: 0 },
|
|
136366
|
+
{ op: "any.convert_extern" },
|
|
136367
|
+
{ op: "local.set", index: 1 }
|
|
136368
|
+
];
|
|
136369
|
+
for (const dataType of dataTypeIdxs) {
|
|
136370
|
+
body.push({ op: "local.get", index: 1 });
|
|
136371
|
+
body.push({ op: "ref.test", typeIdx: dataType });
|
|
136372
|
+
body.push({
|
|
136373
|
+
op: "if",
|
|
136374
|
+
blockType: { kind: "empty" },
|
|
136375
|
+
then: [{ op: "i32.const", value: 1 }, { op: "return" }]
|
|
136376
|
+
});
|
|
136377
|
+
}
|
|
136378
|
+
body.push({ op: "i32.const", value: 0 });
|
|
136379
|
+
mod.functions.push({
|
|
136380
|
+
name: "__is_data_struct",
|
|
136381
|
+
typeIdx: isDataTypeIdx,
|
|
136382
|
+
locals: [{ name: "__any", type: { kind: "anyref" } }],
|
|
136383
|
+
body,
|
|
136384
|
+
exported: true
|
|
136385
|
+
});
|
|
136386
|
+
mod.exports.push({
|
|
136387
|
+
name: "__is_data_struct",
|
|
136388
|
+
desc: { kind: "func", index: funcIdx }
|
|
136389
|
+
});
|
|
136390
|
+
}
|
|
136199
136391
|
function fillStandaloneTypeofClosureArms(ctx) {
|
|
136200
136392
|
if (!ctx.nativeStrings) return;
|
|
136201
136393
|
const baseTypeIdxs = collectClosureBaseWrapperTypeIdxs(ctx);
|
|
@@ -136449,6 +136641,19 @@ function emitToPrimitiveMethodExports(ctx) {
|
|
|
136449
136641
|
emitDispatchForMethod("toString", "__call_toString");
|
|
136450
136642
|
emitDispatchForMethod("valueOf", "__call_valueOf");
|
|
136451
136643
|
}
|
|
136644
|
+
function reserveVecMethodHelper(ctx, kind) {
|
|
136645
|
+
const name = kind === "push" ? "__vec_push" : kind === "pop" ? "__vec_pop" : "__vec_get";
|
|
136646
|
+
const existing = ctx.funcMap.get(name);
|
|
136647
|
+
if (existing !== void 0) return existing;
|
|
136648
|
+
const typeIdx = kind === "push" ? addFuncType(ctx, [{ kind: "externref" }, { kind: "externref" }], [{ kind: "i32" }], "$__vec_push_type") : kind === "pop" ? addFuncType(ctx, [{ kind: "externref" }], [{ kind: "externref" }], "$__vec_pop_type") : addFuncType(ctx, [{ kind: "externref" }, { kind: "i32" }], [{ kind: "externref" }], "$__vec_get_type");
|
|
136649
|
+
const idx = ctx.numImportFuncs + ctx.mod.functions.length;
|
|
136650
|
+
const placeholder = kind === "push" ? [{ op: "i32.const", value: 0 }] : [{ op: "ref.null.extern" }];
|
|
136651
|
+
ctx.mod.functions.push({ name, typeIdx, locals: [], body: placeholder, exported: true });
|
|
136652
|
+
ctx.mod.exports.push({ name, desc: { kind: "func", index: idx } });
|
|
136653
|
+
ctx.funcMap.set(name, idx);
|
|
136654
|
+
ctx.usesVecValue = true;
|
|
136655
|
+
return idx;
|
|
136656
|
+
}
|
|
136452
136657
|
function emitVecAccessExports(ctx) {
|
|
136453
136658
|
if (!ctx.funcMap.has("__iterator") && !ctx.funcMap.has("JSON_stringify") && !ctx.funcMap.has("__make_iterable") && !ctx.funcMap.has("Promise_all") && !ctx.funcMap.has("Promise_race") && !ctx.funcMap.has("Promise_allSettled") && !ctx.funcMap.has("Promise_any") && !ctx.funcMap.has("__crypto_get_random_values") && // (#1503)
|
|
136454
136659
|
!ctx.funcMap.has("__extern_get") && !ctx.usesVecValue) {
|
|
@@ -136609,24 +136814,29 @@ function _emitVecAccessExportsInner(ctx) {
|
|
|
136609
136814
|
];
|
|
136610
136815
|
}
|
|
136611
136816
|
body.push(...current);
|
|
136612
|
-
|
|
136613
|
-
name: "
|
|
136614
|
-
|
|
136615
|
-
|
|
136616
|
-
|
|
136617
|
-
|
|
136618
|
-
|
|
136619
|
-
locals
|
|
136620
|
-
|
|
136621
|
-
|
|
136622
|
-
|
|
136623
|
-
|
|
136624
|
-
|
|
136625
|
-
|
|
136626
|
-
|
|
136627
|
-
|
|
136628
|
-
|
|
136629
|
-
|
|
136817
|
+
const getLocals = holeMapInVecGet ? [
|
|
136818
|
+
{ name: "__any", type: { kind: "anyref" } },
|
|
136819
|
+
{ name: "__hole_scratch", type: { kind: "externref" } }
|
|
136820
|
+
] : [{ name: "__any", type: { kind: "anyref" } }];
|
|
136821
|
+
const reservedGet = ctx.funcMap.get("__vec_get");
|
|
136822
|
+
if (reservedGet !== void 0) {
|
|
136823
|
+
const fn = mod.functions[reservedGet - ctx.numImportFuncs];
|
|
136824
|
+
fn.locals = getLocals;
|
|
136825
|
+
fn.body = body;
|
|
136826
|
+
} else {
|
|
136827
|
+
mod.functions.push({
|
|
136828
|
+
name: "__vec_get",
|
|
136829
|
+
typeIdx: getTypeIdx,
|
|
136830
|
+
locals: getLocals,
|
|
136831
|
+
body,
|
|
136832
|
+
exported: true
|
|
136833
|
+
});
|
|
136834
|
+
mod.exports.push({
|
|
136835
|
+
name: "__vec_get",
|
|
136836
|
+
desc: { kind: "func", index: getFuncIdx }
|
|
136837
|
+
});
|
|
136838
|
+
ctx.funcMap.set("__vec_get", getFuncIdx);
|
|
136839
|
+
}
|
|
136630
136840
|
}
|
|
136631
136841
|
const unboxNumIdx = ctx.funcMap.get("__unbox_number");
|
|
136632
136842
|
const boxNumIdx2 = ctx.funcMap.get("__box_number");
|
|
@@ -136820,14 +137030,22 @@ function _emitVecAccessExportsInner(ctx) {
|
|
|
136820
137030
|
];
|
|
136821
137031
|
}
|
|
136822
137032
|
body.push(...current);
|
|
136823
|
-
|
|
136824
|
-
|
|
136825
|
-
|
|
136826
|
-
locals
|
|
136827
|
-
body
|
|
136828
|
-
|
|
136829
|
-
|
|
136830
|
-
|
|
137033
|
+
const reservedPush = ctx.funcMap.get("__vec_push");
|
|
137034
|
+
if (reservedPush !== void 0) {
|
|
137035
|
+
const fn = mod.functions[reservedPush - ctx.numImportFuncs];
|
|
137036
|
+
fn.locals = locals;
|
|
137037
|
+
fn.body = body;
|
|
137038
|
+
} else {
|
|
137039
|
+
mod.functions.push({
|
|
137040
|
+
name: "__vec_push",
|
|
137041
|
+
typeIdx: pushTypeIdx,
|
|
137042
|
+
locals,
|
|
137043
|
+
body,
|
|
137044
|
+
exported: true
|
|
137045
|
+
});
|
|
137046
|
+
mod.exports.push({ name: "__vec_push", desc: { kind: "func", index: pushFuncIdx } });
|
|
137047
|
+
ctx.funcMap.set("__vec_push", pushFuncIdx);
|
|
137048
|
+
}
|
|
136831
137049
|
}
|
|
136832
137050
|
{
|
|
136833
137051
|
const popTypeIdx = addFuncType(ctx, [{ kind: "externref" }], [{ kind: "externref" }], "$__vec_pop_type");
|
|
@@ -136895,14 +137113,22 @@ function _emitVecAccessExportsInner(ctx) {
|
|
|
136895
137113
|
];
|
|
136896
137114
|
}
|
|
136897
137115
|
body.push(...current);
|
|
136898
|
-
|
|
136899
|
-
|
|
136900
|
-
|
|
136901
|
-
locals
|
|
136902
|
-
body
|
|
136903
|
-
|
|
136904
|
-
|
|
136905
|
-
|
|
137116
|
+
const reservedPop = ctx.funcMap.get("__vec_pop");
|
|
137117
|
+
if (reservedPop !== void 0) {
|
|
137118
|
+
const fn = mod.functions[reservedPop - ctx.numImportFuncs];
|
|
137119
|
+
fn.locals = locals;
|
|
137120
|
+
fn.body = body;
|
|
137121
|
+
} else {
|
|
137122
|
+
mod.functions.push({
|
|
137123
|
+
name: "__vec_pop",
|
|
137124
|
+
typeIdx: popTypeIdx,
|
|
137125
|
+
locals,
|
|
137126
|
+
body,
|
|
137127
|
+
exported: true
|
|
137128
|
+
});
|
|
137129
|
+
mod.exports.push({ name: "__vec_pop", desc: { kind: "func", index: popFuncIdx } });
|
|
137130
|
+
ctx.funcMap.set("__vec_pop", popFuncIdx);
|
|
137131
|
+
}
|
|
136906
137132
|
}
|
|
136907
137133
|
}
|
|
136908
137134
|
function emitVecSetByteExport(ctx) {
|
|
@@ -137371,6 +137597,7 @@ function generateMultiModule(multiAst, options) {
|
|
|
137371
137597
|
emitClosureCallExport(ctx);
|
|
137372
137598
|
emitClosureCallExport1(ctx);
|
|
137373
137599
|
emitIsClosureExport(ctx);
|
|
137600
|
+
emitIsDataStructExport(ctx);
|
|
137374
137601
|
fillStandaloneTypeofClosureArms(ctx);
|
|
137375
137602
|
emitToPrimitiveMethodExports(ctx);
|
|
137376
137603
|
emitToPrimitiveMethodExport(ctx);
|
|
@@ -137386,6 +137613,7 @@ function generateMultiModule(multiAst, options) {
|
|
|
137386
137613
|
});
|
|
137387
137614
|
}
|
|
137388
137615
|
ensureDynReadHelpers(ctx);
|
|
137616
|
+
finalizeInModuleInitFlag(ctx);
|
|
137389
137617
|
markLeafStructsFinal(mod, ctx.wasi);
|
|
137390
137618
|
eliminateDeadImports(mod, ctx);
|
|
137391
137619
|
repairStructTypeMismatches(mod);
|
|
@@ -139117,6 +139345,10 @@ function addUnionImports(ctx) {
|
|
|
139117
139345
|
kind: "func",
|
|
139118
139346
|
typeIdx: boxBoolType
|
|
139119
139347
|
});
|
|
139348
|
+
addImport(ctx, "env", "__box_symbol", {
|
|
139349
|
+
kind: "func",
|
|
139350
|
+
typeIdx: boxBoolType
|
|
139351
|
+
});
|
|
139120
139352
|
const boxBigType = addFuncType(ctx, [{ kind: "i64" }], [{ kind: "externref" }]);
|
|
139121
139353
|
addImport(ctx, "env", "__box_bigint", { kind: "func", typeIdx: boxBigType });
|
|
139122
139354
|
const toBigType = addFuncType(ctx, [{ kind: "externref" }], [{ kind: "i64" }]);
|
|
@@ -139165,6 +139397,7 @@ function addUnionImports(ctx) {
|
|
|
139165
139397
|
"__unbox_boolean",
|
|
139166
139398
|
"__box_number",
|
|
139167
139399
|
"__box_boolean",
|
|
139400
|
+
"__box_symbol",
|
|
139168
139401
|
"__box_bigint",
|
|
139169
139402
|
"__to_bigint",
|
|
139170
139403
|
"__bigint_ctor",
|
|
@@ -140763,7 +140996,7 @@ function collectExternClass(ctx, decl, namespacePath) {
|
|
|
140763
140996
|
if (!p.questionToken && !p.initializer) requiredParams++;
|
|
140764
140997
|
}
|
|
140765
140998
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
140766
|
-
const results = isVoidType(retType) ? [] : [mapTsTypeToWasm(retType, ctx.checker)];
|
|
140999
|
+
const results = isVoidType(retType) ? [] : [brandExternMethodResult(ctx, retType, mapTsTypeToWasm(retType, ctx.checker))];
|
|
140767
141000
|
info.methods.set(methodName, { params, results, requiredParams });
|
|
140768
141001
|
}
|
|
140769
141002
|
}
|
|
@@ -140877,7 +141110,7 @@ function collectInterfaceMembers(ctx, iface, info, locationNode) {
|
|
|
140877
141110
|
if (!p.questionToken && !p.initializer) requiredParams++;
|
|
140878
141111
|
}
|
|
140879
141112
|
const retType = ctx.checker.getReturnTypeOfSignature(sig);
|
|
140880
|
-
const results = isVoidType(retType) ? [] : [mapTsTypeToWasm(retType, ctx.checker)];
|
|
141113
|
+
const results = isVoidType(retType) ? [] : [brandExternMethodResult(ctx, retType, mapTsTypeToWasm(retType, ctx.checker))];
|
|
140881
141114
|
info.methods.set(methodName, { params, results, requiredParams });
|
|
140882
141115
|
}
|
|
140883
141116
|
}
|
|
@@ -141421,6 +141654,11 @@ function hoistVarDecl(ctx, fctx, decl) {
|
|
|
141421
141654
|
}
|
|
141422
141655
|
}
|
|
141423
141656
|
}
|
|
141657
|
+
if (!initForcesExternref && decl.initializer.properties.some((p) => ts.isSpreadAssignment(p))) {
|
|
141658
|
+
const spreadCtxType = ctx.checker.getContextualType(decl.initializer);
|
|
141659
|
+
const nonSpecificCtx = !spreadCtxType || (spreadCtxType.flags & ts.TypeFlags.Any) !== 0 || (spreadCtxType.flags & ts.TypeFlags.Unknown) !== 0 || (spreadCtxType.flags & ts.TypeFlags.NonPrimitive) !== 0 || spreadCtxType.getProperties().length === 0;
|
|
141660
|
+
if (nonSpecificCtx) initForcesExternref = true;
|
|
141661
|
+
}
|
|
141424
141662
|
}
|
|
141425
141663
|
const wasmType = initForcesExternref || isNullablePrimitiveType(varType) ? { kind: "externref" } : resolveWasmType(ctx, varType);
|
|
141426
141664
|
if (initForcesExternref) ctx.externrefAccessorVars.add(name);
|
|
@@ -141728,10 +141966,15 @@ function walkStmtForLetConst(ctx, fctx, stmt) {
|
|
|
141728
141966
|
const varType = ctx.checker.getTypeAtLocation(decl);
|
|
141729
141967
|
const isI32Coerced = fctx.i32CoercedLocals?.has(name) === true && (varType.flags & ts.TypeFlags.NumberLike) !== 0;
|
|
141730
141968
|
const initIsAccessorLiteral = decl.initializer !== void 0 && ts.isObjectLiteralExpression(decl.initializer) && decl.initializer.properties.some((p) => ts.isGetAccessorDeclaration(p) || ts.isSetAccessorDeclaration(p));
|
|
141731
|
-
|
|
141969
|
+
let initIsHostSpreadLiteral = false;
|
|
141970
|
+
if (!initIsAccessorLiteral && decl.initializer !== void 0 && ts.isObjectLiteralExpression(decl.initializer) && decl.initializer.properties.some((p) => ts.isSpreadAssignment(p))) {
|
|
141971
|
+
const spreadCtxType = ctx.checker.getContextualType(decl.initializer);
|
|
141972
|
+
initIsHostSpreadLiteral = !spreadCtxType || (spreadCtxType.flags & ts.TypeFlags.Any) !== 0 || (spreadCtxType.flags & ts.TypeFlags.Unknown) !== 0 || (spreadCtxType.flags & ts.TypeFlags.NonPrimitive) !== 0 || spreadCtxType.getProperties().length === 0;
|
|
141973
|
+
}
|
|
141974
|
+
if (initIsAccessorLiteral || initIsHostSpreadLiteral) {
|
|
141732
141975
|
ctx.externrefAccessorVars.add(name);
|
|
141733
141976
|
}
|
|
141734
|
-
const wasmType = initIsAccessorLiteral ? { kind: "externref" } : isI32Coerced ? { kind: "i32" } : isNullablePrimitiveType(varType) ? { kind: "externref" } : inferLetConstInitializerWasmType(ctx, fctx, decl.initializer) ?? resolveWasmType(ctx, varType);
|
|
141977
|
+
const wasmType = initIsAccessorLiteral || initIsHostSpreadLiteral ? { kind: "externref" } : isI32Coerced ? { kind: "i32" } : isNullablePrimitiveType(varType) ? { kind: "externref" } : inferLetConstInitializerWasmType(ctx, fctx, decl.initializer) ?? resolveWasmType(ctx, varType);
|
|
141735
141978
|
allocLocal(fctx, name, wasmType);
|
|
141736
141979
|
if (needsTdzFlag(ctx, decl)) {
|
|
141737
141980
|
if (!fctx.tdzFlagLocals) fctx.tdzFlagLocals = /* @__PURE__ */ new Map();
|
|
@@ -141894,6 +142137,448 @@ function ensureI32Condition(fctx, condType, ctx) {
|
|
|
141894
142137
|
fctx.body.push({ op: "i32.eqz" });
|
|
141895
142138
|
}
|
|
141896
142139
|
}
|
|
142140
|
+
const EMPTY_RESULT = {
|
|
142141
|
+
sites: /* @__PURE__ */ new Map(),
|
|
142142
|
+
approved: /* @__PURE__ */ new Set(),
|
|
142143
|
+
approvedNames: /* @__PURE__ */ new Set(),
|
|
142144
|
+
receiverStruct: /* @__PURE__ */ new Map(),
|
|
142145
|
+
newThisOwnerNames: /* @__PURE__ */ new Set(),
|
|
142146
|
+
ctorDeclByName: /* @__PURE__ */ new Map()
|
|
142147
|
+
};
|
|
142148
|
+
function fnctorDeclFromSymbol(sym) {
|
|
142149
|
+
for (const decl of sym.getDeclarations() ?? []) {
|
|
142150
|
+
if (ts.isFunctionDeclaration(decl) && decl.body) return decl;
|
|
142151
|
+
if (ts.isFunctionExpression(decl) && decl.body) return decl;
|
|
142152
|
+
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
142153
|
+
let init = decl.initializer;
|
|
142154
|
+
while (ts.isParenthesizedExpression(init)) init = init.expression;
|
|
142155
|
+
if (ts.isFunctionExpression(init) && init.body) return init;
|
|
142156
|
+
}
|
|
142157
|
+
}
|
|
142158
|
+
return void 0;
|
|
142159
|
+
}
|
|
142160
|
+
const RETURN_INFER_MAX_DEPTH = 6;
|
|
142161
|
+
const GENERIC_METHOD_CALL = /* @__PURE__ */ new Set(["call", "apply", "bind"]);
|
|
142162
|
+
function resolveFnctorSymbol(checker, calleeExpr) {
|
|
142163
|
+
let e = calleeExpr;
|
|
142164
|
+
while (ts.isParenthesizedExpression(e) || ts.isAsExpression(e) || ts.isNonNullExpression(e)) {
|
|
142165
|
+
e = e.expression;
|
|
142166
|
+
}
|
|
142167
|
+
if (!ts.isIdentifier(e)) return void 0;
|
|
142168
|
+
const sym = checker.getSymbolAtLocation(e);
|
|
142169
|
+
const decls = sym?.getDeclarations();
|
|
142170
|
+
if (!sym || !decls) return void 0;
|
|
142171
|
+
for (const decl of decls) {
|
|
142172
|
+
if (ts.isClassDeclaration(decl) || ts.isClassExpression(decl)) return void 0;
|
|
142173
|
+
if (ts.isFunctionDeclaration(decl) && decl.body) return sym;
|
|
142174
|
+
if (ts.isFunctionExpression(decl) && decl.body) return sym;
|
|
142175
|
+
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
142176
|
+
let init = decl.initializer;
|
|
142177
|
+
while (ts.isParenthesizedExpression(init)) init = init.expression;
|
|
142178
|
+
if (ts.isFunctionExpression(init) && init.body) return sym;
|
|
142179
|
+
if (ts.isArrowFunction(init)) return void 0;
|
|
142180
|
+
}
|
|
142181
|
+
}
|
|
142182
|
+
return void 0;
|
|
142183
|
+
}
|
|
142184
|
+
function resolveEnclosingFnctorOwner(checker, node) {
|
|
142185
|
+
let fn = node;
|
|
142186
|
+
while (fn && !ts.isFunctionExpression(fn) && !ts.isFunctionDeclaration(fn)) {
|
|
142187
|
+
fn = fn.parent;
|
|
142188
|
+
}
|
|
142189
|
+
if (!fn) return void 0;
|
|
142190
|
+
const assign = fn.parent;
|
|
142191
|
+
if (!ts.isBinaryExpression(assign) || assign.operatorToken.kind !== ts.SyntaxKind.EqualsToken || assign.right !== fn || !ts.isPropertyAccessExpression(assign.left)) {
|
|
142192
|
+
return void 0;
|
|
142193
|
+
}
|
|
142194
|
+
const left = assign.left;
|
|
142195
|
+
if (ts.isPropertyAccessExpression(left.expression) && ts.isIdentifier(left.expression.name) && left.expression.name.text === "prototype") {
|
|
142196
|
+
const sym = resolveFnctorSymbol(checker, left.expression.expression);
|
|
142197
|
+
if (sym) return { name: sym.name, sym, viaPrototype: true };
|
|
142198
|
+
return void 0;
|
|
142199
|
+
}
|
|
142200
|
+
const holder = left.expression;
|
|
142201
|
+
const direct = resolveFnctorSymbol(checker, holder);
|
|
142202
|
+
if (direct) return { name: direct.name, sym: direct, viaPrototype: false };
|
|
142203
|
+
if (ts.isIdentifier(holder)) {
|
|
142204
|
+
const hsym = checker.getSymbolAtLocation(holder);
|
|
142205
|
+
for (const decl of hsym?.getDeclarations() ?? []) {
|
|
142206
|
+
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
142207
|
+
let init = decl.initializer;
|
|
142208
|
+
while (ts.isParenthesizedExpression(init)) init = init.expression;
|
|
142209
|
+
if (ts.isPropertyAccessExpression(init) && ts.isIdentifier(init.name) && init.name.text === "prototype") {
|
|
142210
|
+
const fsym = resolveFnctorSymbol(checker, init.expression);
|
|
142211
|
+
if (fsym) return { name: fsym.name, sym: fsym, viaPrototype: true };
|
|
142212
|
+
}
|
|
142213
|
+
}
|
|
142214
|
+
}
|
|
142215
|
+
}
|
|
142216
|
+
return void 0;
|
|
142217
|
+
}
|
|
142218
|
+
function resolveLiftedMethodThisStruct(ctx, fn) {
|
|
142219
|
+
const owner = resolveEnclosingFnctorOwner(ctx.checker, fn);
|
|
142220
|
+
if (!owner || !owner.viaPrototype) return void 0;
|
|
142221
|
+
if (!ctx.fnctorEscapeGate?.approvedNames.has(owner.name)) return void 0;
|
|
142222
|
+
return `__fnctor_${owner.name}`;
|
|
142223
|
+
}
|
|
142224
|
+
function collectFnctorOwnFields(ctorSym) {
|
|
142225
|
+
const fields = /* @__PURE__ */ new Set();
|
|
142226
|
+
const decls = ctorSym.getDeclarations() ?? [];
|
|
142227
|
+
for (const decl of decls) {
|
|
142228
|
+
let body;
|
|
142229
|
+
if ((ts.isFunctionDeclaration(decl) || ts.isFunctionExpression(decl)) && decl.body) body = decl.body;
|
|
142230
|
+
else if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
142231
|
+
let init = decl.initializer;
|
|
142232
|
+
while (ts.isParenthesizedExpression(init)) init = init.expression;
|
|
142233
|
+
if (ts.isFunctionExpression(init) && init.body) body = init.body;
|
|
142234
|
+
}
|
|
142235
|
+
if (!body) continue;
|
|
142236
|
+
const walk = (node) => {
|
|
142237
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(node.left) && node.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
142238
|
+
fields.add(node.left.name.text);
|
|
142239
|
+
}
|
|
142240
|
+
forEachChild$1(node, walk);
|
|
142241
|
+
};
|
|
142242
|
+
walk(body);
|
|
142243
|
+
}
|
|
142244
|
+
return fields;
|
|
142245
|
+
}
|
|
142246
|
+
function classifyUse(checker, idNode, ownFields) {
|
|
142247
|
+
const parent = idNode.parent;
|
|
142248
|
+
if (ts.isPropertyAccessExpression(parent) && parent.expression === idNode) {
|
|
142249
|
+
const name = parent.name.text;
|
|
142250
|
+
if (ownFields.has(name)) return "typed";
|
|
142251
|
+
return "dynamic";
|
|
142252
|
+
}
|
|
142253
|
+
if (ts.isElementAccessExpression(parent) && parent.expression === idNode) {
|
|
142254
|
+
return "dynamic";
|
|
142255
|
+
}
|
|
142256
|
+
if (ts.isCallExpression(parent) && parent.arguments.length > 0 && parent.arguments[0] === idNode) {
|
|
142257
|
+
const callee = parent.expression;
|
|
142258
|
+
if (ts.isPropertyAccessExpression(callee) && GENERIC_METHOD_CALL.has(callee.name.text)) {
|
|
142259
|
+
return "dynamic";
|
|
142260
|
+
}
|
|
142261
|
+
}
|
|
142262
|
+
if (ts.isCallExpression(parent)) {
|
|
142263
|
+
const argIdx = parent.arguments.indexOf(idNode);
|
|
142264
|
+
if (argIdx >= 0) {
|
|
142265
|
+
const sig = checker.getResolvedSignature(parent);
|
|
142266
|
+
const paramSym = sig?.parameters[argIdx];
|
|
142267
|
+
if (paramSym) {
|
|
142268
|
+
const pType = checker.getTypeOfSymbolAtLocation(paramSym, idNode);
|
|
142269
|
+
if (isAnyOrUnknown(pType)) return "dynamic";
|
|
142270
|
+
}
|
|
142271
|
+
return "neutral";
|
|
142272
|
+
}
|
|
142273
|
+
}
|
|
142274
|
+
if (ts.isReturnStatement(parent)) {
|
|
142275
|
+
return "neutral";
|
|
142276
|
+
}
|
|
142277
|
+
return "neutral";
|
|
142278
|
+
}
|
|
142279
|
+
function isAnyOrUnknown(t) {
|
|
142280
|
+
return (t.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0;
|
|
142281
|
+
}
|
|
142282
|
+
function bindingOf(newExpr) {
|
|
142283
|
+
const parent = newExpr.parent;
|
|
142284
|
+
if (ts.isVariableDeclaration(parent) && parent.initializer === newExpr && ts.isIdentifier(parent.name)) {
|
|
142285
|
+
return parent.name;
|
|
142286
|
+
}
|
|
142287
|
+
return void 0;
|
|
142288
|
+
}
|
|
142289
|
+
function unwrapExpr(e) {
|
|
142290
|
+
let cur = e;
|
|
142291
|
+
while (ts.isParenthesizedExpression(cur) || ts.isAsExpression(cur) || ts.isNonNullExpression(cur)) {
|
|
142292
|
+
cur = cur.expression;
|
|
142293
|
+
}
|
|
142294
|
+
return cur;
|
|
142295
|
+
}
|
|
142296
|
+
function isFunctionLike(node) {
|
|
142297
|
+
return ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node);
|
|
142298
|
+
}
|
|
142299
|
+
function buildProtoMethodIndex(sourceFile) {
|
|
142300
|
+
const idx = /* @__PURE__ */ new Map();
|
|
142301
|
+
const walk = (n) => {
|
|
142302
|
+
if (ts.isBinaryExpression(n) && n.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(n.left)) {
|
|
142303
|
+
const rhs = unwrapExpr(n.right);
|
|
142304
|
+
if (isFunctionLike(rhs)) {
|
|
142305
|
+
const name = n.left.name.text;
|
|
142306
|
+
const arr = idx.get(name);
|
|
142307
|
+
if (arr) arr.push(rhs);
|
|
142308
|
+
else idx.set(name, [rhs]);
|
|
142309
|
+
}
|
|
142310
|
+
}
|
|
142311
|
+
forEachChild$1(n, walk);
|
|
142312
|
+
};
|
|
142313
|
+
walk(sourceFile);
|
|
142314
|
+
return idx;
|
|
142315
|
+
}
|
|
142316
|
+
function resolveCalleeFunction(checker, callExpr, protoIndex) {
|
|
142317
|
+
const callee = unwrapExpr(callExpr.expression);
|
|
142318
|
+
let sym;
|
|
142319
|
+
if (ts.isPropertyAccessExpression(callee)) {
|
|
142320
|
+
sym = checker.getSymbolAtLocation(callee.name) ?? checker.getSymbolAtLocation(callee);
|
|
142321
|
+
} else if (ts.isIdentifier(callee)) {
|
|
142322
|
+
sym = checker.getSymbolAtLocation(callee);
|
|
142323
|
+
}
|
|
142324
|
+
if (sym) {
|
|
142325
|
+
for (const decl of sym.getDeclarations() ?? []) {
|
|
142326
|
+
const fn = functionFromDeclaration(decl);
|
|
142327
|
+
if (fn?.body) return fn;
|
|
142328
|
+
}
|
|
142329
|
+
}
|
|
142330
|
+
if (ts.isPropertyAccessExpression(callee)) {
|
|
142331
|
+
const cands = protoIndex.get(callee.name.text);
|
|
142332
|
+
if (cands && cands.length === 1 && cands[0].body) return cands[0];
|
|
142333
|
+
}
|
|
142334
|
+
return void 0;
|
|
142335
|
+
}
|
|
142336
|
+
function functionFromDeclaration(decl) {
|
|
142337
|
+
if (isFunctionLike(decl)) return decl;
|
|
142338
|
+
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
142339
|
+
const init = unwrapExpr(decl.initializer);
|
|
142340
|
+
if (isFunctionLike(init)) return init;
|
|
142341
|
+
return void 0;
|
|
142342
|
+
}
|
|
142343
|
+
if (ts.isPropertyAssignment(decl)) {
|
|
142344
|
+
const init = unwrapExpr(decl.initializer);
|
|
142345
|
+
if (isFunctionLike(init)) return init;
|
|
142346
|
+
return void 0;
|
|
142347
|
+
}
|
|
142348
|
+
if (ts.isMethodDeclaration(decl)) return decl;
|
|
142349
|
+
if (ts.isPropertyAccessExpression(decl) || ts.isElementAccessExpression(decl)) {
|
|
142350
|
+
const parent = decl.parent;
|
|
142351
|
+
if (ts.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && parent.left === decl) {
|
|
142352
|
+
const rhs = unwrapExpr(parent.right);
|
|
142353
|
+
if (isFunctionLike(rhs)) return rhs;
|
|
142354
|
+
}
|
|
142355
|
+
}
|
|
142356
|
+
return void 0;
|
|
142357
|
+
}
|
|
142358
|
+
function singleReturnExpr(fn) {
|
|
142359
|
+
const body = fn.body;
|
|
142360
|
+
if (!body) return void 0;
|
|
142361
|
+
if (!ts.isBlock(body)) return body;
|
|
142362
|
+
const returns = [];
|
|
142363
|
+
const walk = (n) => {
|
|
142364
|
+
if (ts.isReturnStatement(n)) {
|
|
142365
|
+
if (n.expression) returns.push(n.expression);
|
|
142366
|
+
return;
|
|
142367
|
+
}
|
|
142368
|
+
if (isFunctionLike(n)) return;
|
|
142369
|
+
forEachChild$1(n, walk);
|
|
142370
|
+
};
|
|
142371
|
+
walk(body);
|
|
142372
|
+
return returns.length === 1 ? returns[0] : void 0;
|
|
142373
|
+
}
|
|
142374
|
+
function inferReturnStruct(checker, fn, depth, memo, protoIndex) {
|
|
142375
|
+
if (memo.has(fn)) return memo.get(fn);
|
|
142376
|
+
if (depth <= 0) return void 0;
|
|
142377
|
+
memo.set(fn, void 0);
|
|
142378
|
+
const ret2 = singleReturnExpr(fn);
|
|
142379
|
+
let result;
|
|
142380
|
+
if (ret2) {
|
|
142381
|
+
const r = unwrapExpr(ret2);
|
|
142382
|
+
if (ts.isNewExpression(r)) {
|
|
142383
|
+
let ctorSym = resolveFnctorSymbol(checker, r.expression);
|
|
142384
|
+
if (!ctorSym && r.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
142385
|
+
ctorSym = resolveEnclosingFnctorOwner(checker, r)?.sym;
|
|
142386
|
+
}
|
|
142387
|
+
if (ctorSym) result = `__fnctor_${ctorSym.name}`;
|
|
142388
|
+
} else if (ts.isCallExpression(r)) {
|
|
142389
|
+
const callee = resolveCalleeFunction(checker, r, protoIndex);
|
|
142390
|
+
if (callee) result = inferReturnStruct(checker, callee, depth - 1, memo, protoIndex);
|
|
142391
|
+
}
|
|
142392
|
+
}
|
|
142393
|
+
memo.set(fn, result);
|
|
142394
|
+
return result;
|
|
142395
|
+
}
|
|
142396
|
+
function buildReceiverStructMap(checker, sourceFile, usesBySymbol) {
|
|
142397
|
+
const map = /* @__PURE__ */ new Map();
|
|
142398
|
+
const memo = /* @__PURE__ */ new Map();
|
|
142399
|
+
const protoIndex = buildProtoMethodIndex(sourceFile);
|
|
142400
|
+
const visit = (node) => {
|
|
142401
|
+
if (ts.isVariableDeclaration(node) && node.initializer && ts.isIdentifier(node.name)) {
|
|
142402
|
+
const init = unwrapExpr(node.initializer);
|
|
142403
|
+
let struct;
|
|
142404
|
+
if (ts.isCallExpression(init)) {
|
|
142405
|
+
const callee = resolveCalleeFunction(checker, init, protoIndex);
|
|
142406
|
+
struct = callee ? inferReturnStruct(checker, callee, RETURN_INFER_MAX_DEPTH, memo, protoIndex) : void 0;
|
|
142407
|
+
} else if (ts.isNewExpression(init)) {
|
|
142408
|
+
let ctorSym = resolveFnctorSymbol(checker, init.expression);
|
|
142409
|
+
if (!ctorSym && init.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
142410
|
+
ctorSym = resolveEnclosingFnctorOwner(checker, init)?.sym;
|
|
142411
|
+
}
|
|
142412
|
+
struct = ctorSym ? `__fnctor_${ctorSym.name}` : void 0;
|
|
142413
|
+
}
|
|
142414
|
+
if (struct) {
|
|
142415
|
+
const bindSym = checker.getSymbolAtLocation(node.name);
|
|
142416
|
+
const uses = bindSym ? usesBySymbol.get(bindSym) ?? [] : [];
|
|
142417
|
+
for (const use of uses) {
|
|
142418
|
+
if (use === node.name) continue;
|
|
142419
|
+
map.set(use, struct);
|
|
142420
|
+
}
|
|
142421
|
+
}
|
|
142422
|
+
}
|
|
142423
|
+
forEachChild$1(node, visit);
|
|
142424
|
+
};
|
|
142425
|
+
visit(sourceFile);
|
|
142426
|
+
return map;
|
|
142427
|
+
}
|
|
142428
|
+
function resolveReceiverStruct(ctx, fctx, recvExpr) {
|
|
142429
|
+
const recv = unwrapExpr(recvExpr);
|
|
142430
|
+
let name;
|
|
142431
|
+
if (recv.kind === ts.SyntaxKind.ThisKeyword) {
|
|
142432
|
+
name = fctx.thisStructName;
|
|
142433
|
+
} else {
|
|
142434
|
+
name = ctx.fnctorEscapeGate?.receiverStruct.get(recv);
|
|
142435
|
+
}
|
|
142436
|
+
if (name !== void 0 && ctx.structMap.has(name)) return name;
|
|
142437
|
+
return void 0;
|
|
142438
|
+
}
|
|
142439
|
+
function analyzeFnctorEscapeGate(checker, sourceFile) {
|
|
142440
|
+
const sites = /* @__PURE__ */ new Map();
|
|
142441
|
+
const approved = /* @__PURE__ */ new Set();
|
|
142442
|
+
const approvedNames = /* @__PURE__ */ new Set();
|
|
142443
|
+
const newSites = [];
|
|
142444
|
+
const newThisSites = /* @__PURE__ */ new Set();
|
|
142445
|
+
const collect = (node) => {
|
|
142446
|
+
if (ts.isNewExpression(node)) {
|
|
142447
|
+
let ctorSym = resolveFnctorSymbol(checker, node.expression);
|
|
142448
|
+
if (!ctorSym && node.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
142449
|
+
const owner = resolveEnclosingFnctorOwner(checker, node);
|
|
142450
|
+
if (owner) {
|
|
142451
|
+
ctorSym = owner.sym;
|
|
142452
|
+
newThisSites.add(node);
|
|
142453
|
+
}
|
|
142454
|
+
}
|
|
142455
|
+
if (ctorSym) newSites.push({ newExpr: node, ctorSym });
|
|
142456
|
+
}
|
|
142457
|
+
forEachChild$1(node, collect);
|
|
142458
|
+
};
|
|
142459
|
+
collect(sourceFile);
|
|
142460
|
+
if (newSites.length === 0) return EMPTY_RESULT;
|
|
142461
|
+
const ctorDeclByName = /* @__PURE__ */ new Map();
|
|
142462
|
+
for (const { ctorSym } of newSites) {
|
|
142463
|
+
if (ctorDeclByName.has(ctorSym.name)) continue;
|
|
142464
|
+
const decl = fnctorDeclFromSymbol(ctorSym);
|
|
142465
|
+
if (decl) ctorDeclByName.set(ctorSym.name, decl);
|
|
142466
|
+
}
|
|
142467
|
+
const usesBySymbol = /* @__PURE__ */ new Map();
|
|
142468
|
+
const indexUses = (node) => {
|
|
142469
|
+
if (ts.isIdentifier(node)) {
|
|
142470
|
+
const sym = checker.getSymbolAtLocation(node);
|
|
142471
|
+
if (sym) {
|
|
142472
|
+
const arr = usesBySymbol.get(sym);
|
|
142473
|
+
if (arr) arr.push(node);
|
|
142474
|
+
else usesBySymbol.set(sym, [node]);
|
|
142475
|
+
}
|
|
142476
|
+
}
|
|
142477
|
+
forEachChild$1(node, indexUses);
|
|
142478
|
+
};
|
|
142479
|
+
indexUses(sourceFile);
|
|
142480
|
+
const newThisOwnerNames = /* @__PURE__ */ new Set();
|
|
142481
|
+
for (const { newExpr, ctorSym } of newSites) {
|
|
142482
|
+
const ownFields = collectFnctorOwnFields(ctorSym);
|
|
142483
|
+
let sawDynamic = false;
|
|
142484
|
+
let sawTyped = false;
|
|
142485
|
+
const bind = bindingOf(newExpr);
|
|
142486
|
+
if (bind) {
|
|
142487
|
+
const bindSym = checker.getSymbolAtLocation(bind);
|
|
142488
|
+
const uses = bindSym ? usesBySymbol.get(bindSym) ?? [] : [];
|
|
142489
|
+
for (const use of uses) {
|
|
142490
|
+
if (use === bind) continue;
|
|
142491
|
+
const c = classifyUse(checker, use, ownFields);
|
|
142492
|
+
if (c === "typed") sawTyped = true;
|
|
142493
|
+
else if (c === "dynamic") sawDynamic = true;
|
|
142494
|
+
}
|
|
142495
|
+
} else {
|
|
142496
|
+
let inner = newExpr;
|
|
142497
|
+
let parent = inner.parent;
|
|
142498
|
+
while (ts.isParenthesizedExpression(parent) || ts.isAsExpression(parent) || ts.isNonNullExpression(parent)) {
|
|
142499
|
+
inner = parent;
|
|
142500
|
+
parent = parent.parent;
|
|
142501
|
+
}
|
|
142502
|
+
if (ts.isPropertyAccessExpression(parent) && parent.expression === inner) {
|
|
142503
|
+
if (ownFields.has(parent.name.text)) sawTyped = true;
|
|
142504
|
+
else sawDynamic = true;
|
|
142505
|
+
} else if (ts.isElementAccessExpression(parent) && parent.expression === inner) {
|
|
142506
|
+
sawDynamic = true;
|
|
142507
|
+
} else if (ts.isCallExpression(parent) && parent.arguments.length > 0 && parent.arguments[0] === inner && ts.isPropertyAccessExpression(parent.expression) && GENERIC_METHOD_CALL.has(parent.expression.name.text)) {
|
|
142508
|
+
sawDynamic = true;
|
|
142509
|
+
}
|
|
142510
|
+
}
|
|
142511
|
+
let cls;
|
|
142512
|
+
if (newThisSites.has(newExpr)) cls = "reconstruct";
|
|
142513
|
+
else if (sawTyped) cls = "keep-typed";
|
|
142514
|
+
else if (sawDynamic) cls = "reconstruct";
|
|
142515
|
+
else cls = "keep-static";
|
|
142516
|
+
sites.set(newExpr, cls);
|
|
142517
|
+
if (cls === "reconstruct") {
|
|
142518
|
+
approved.add(newExpr);
|
|
142519
|
+
approvedNames.add(ctorSym.name);
|
|
142520
|
+
if (newThisSites.has(newExpr)) newThisOwnerNames.add(ctorSym.name);
|
|
142521
|
+
}
|
|
142522
|
+
}
|
|
142523
|
+
const receiverStruct = buildReceiverStructMap(checker, sourceFile, usesBySymbol);
|
|
142524
|
+
if (process.env.JS2WASM_LOG_FNCTOR_GATE === "1" && (sites.size > 0 || receiverStruct.size > 0)) {
|
|
142525
|
+
const counts = { reconstruct: 0, "keep-typed": 0, "keep-static": 0 };
|
|
142526
|
+
for (const c of sites.values()) counts[c]++;
|
|
142527
|
+
console.error(
|
|
142528
|
+
`[#2660 fnctor-escape-gate] ${sites.size} new F() site(s): reconstruct=${counts.reconstruct} keep-typed=${counts["keep-typed"]} keep-static=${counts["keep-static"]}; receiverStruct flow-map entries=${receiverStruct.size}`
|
|
142529
|
+
);
|
|
142530
|
+
}
|
|
142531
|
+
return { sites, approved, approvedNames, receiverStruct, newThisOwnerNames, ctorDeclByName };
|
|
142532
|
+
}
|
|
142533
|
+
function deriveFnctorFields(ctx, funcDecl) {
|
|
142534
|
+
const body = funcDecl.body;
|
|
142535
|
+
if (!body) return [];
|
|
142536
|
+
const fields = [];
|
|
142537
|
+
function recordThisField(lhs, valueExpr) {
|
|
142538
|
+
const fieldName = lhs.name.text;
|
|
142539
|
+
if (fields.some((f) => f.name === fieldName)) return;
|
|
142540
|
+
const lhsType = ctx.checker.getTypeAtLocation(lhs);
|
|
142541
|
+
const rhsType = ctx.checker.getTypeAtLocation(valueExpr);
|
|
142542
|
+
const lhsWasm = resolveWasmType(ctx, lhsType);
|
|
142543
|
+
const rhsWasm = resolveWasmType(ctx, rhsType);
|
|
142544
|
+
const fieldType = lhsWasm.kind === "externref" ? rhsWasm : lhsWasm;
|
|
142545
|
+
fields.push({ name: fieldName, type: fieldType, mutable: true });
|
|
142546
|
+
}
|
|
142547
|
+
function collectAssignmentChain(expr) {
|
|
142548
|
+
if (ts.isBinaryExpression(expr) && expr.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(expr.left) && expr.left.expression.kind === ts.SyntaxKind.ThisKeyword) {
|
|
142549
|
+
recordThisField(expr.left, expr.right);
|
|
142550
|
+
collectAssignmentChain(expr.right);
|
|
142551
|
+
}
|
|
142552
|
+
}
|
|
142553
|
+
function collectThisAssignments(stmts) {
|
|
142554
|
+
for (const stmt of stmts) {
|
|
142555
|
+
if (ts.isExpressionStatement(stmt) && ts.isBinaryExpression(stmt.expression)) {
|
|
142556
|
+
collectAssignmentChain(stmt.expression);
|
|
142557
|
+
}
|
|
142558
|
+
if (ts.isIfStatement(stmt)) {
|
|
142559
|
+
if (ts.isBlock(stmt.thenStatement)) {
|
|
142560
|
+
collectThisAssignments(stmt.thenStatement.statements);
|
|
142561
|
+
}
|
|
142562
|
+
if (stmt.elseStatement && ts.isBlock(stmt.elseStatement)) {
|
|
142563
|
+
collectThisAssignments(stmt.elseStatement.statements);
|
|
142564
|
+
}
|
|
142565
|
+
}
|
|
142566
|
+
if ((ts.isForStatement(stmt) || ts.isForInStatement(stmt) || ts.isForOfStatement(stmt) || ts.isWhileStatement(stmt) || ts.isDoStatement(stmt)) && ts.isBlock(stmt.statement)) {
|
|
142567
|
+
collectThisAssignments(stmt.statement.statements);
|
|
142568
|
+
}
|
|
142569
|
+
}
|
|
142570
|
+
}
|
|
142571
|
+
collectThisAssignments(body.statements);
|
|
142572
|
+
for (const field of fields) {
|
|
142573
|
+
if (field.type.kind === "ref") {
|
|
142574
|
+
field.type = {
|
|
142575
|
+
kind: "ref_null",
|
|
142576
|
+
typeIdx: field.type.typeIdx
|
|
142577
|
+
};
|
|
142578
|
+
}
|
|
142579
|
+
}
|
|
142580
|
+
return fields;
|
|
142581
|
+
}
|
|
141897
142582
|
function isFunctionScopeBoundary(node) {
|
|
141898
142583
|
return ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node) || ts.isConstructorDeclaration(node);
|
|
141899
142584
|
}
|
|
@@ -142999,7 +143684,15 @@ function compileArrowAsClosure(ctx, fctx, arrow) {
|
|
|
142999
143684
|
// which installs the host receiver into `__current_this`. Allow `this`
|
|
143000
143685
|
// (with no other binding) to read that global. Named functions / methods
|
|
143001
143686
|
// are NOT lifted here and keep `undefined`/globalObject `this`.
|
|
143002
|
-
readsCurrentThis: true
|
|
143687
|
+
readsCurrentThis: true,
|
|
143688
|
+
// (#2681/#2686 A3) When this lifted closure is a fnctor PROTOTYPE method of an
|
|
143689
|
+
// approved-for-reconstruction fnctor (`F.prototype.m = fn` / aliased `var pp =
|
|
143690
|
+
// F.prototype; pp.m = fn`), pin its `this` receiver to `__fnctor_F` so the
|
|
143691
|
+
// dynamic `this.<field>` read dispatch (property-access.ts) routes through the
|
|
143692
|
+
// finalize-filled `__get_member_<name>` struct dispatcher instead of the
|
|
143693
|
+
// host-proxy `__extern_get` (whose externref identity diverges from the stored
|
|
143694
|
+
// native struct → the #2681/#2686 throw).
|
|
143695
|
+
thisStructName: resolveLiftedMethodThisStruct(ctx, arrow)
|
|
143003
143696
|
};
|
|
143004
143697
|
ctx.liveBodies.add(liftedFctx.body);
|
|
143005
143698
|
for (let i = 0; i < liftedFctx.params.length; i++) {
|
|
@@ -144869,7 +145562,7 @@ function compileStaticPropIncDec(ctx, fctx, globalIdx, f64Op, mode) {
|
|
|
144869
145562
|
fctx.body.push({ op: "local.get", index: mode === "postfix" ? oldTmp : newTmp });
|
|
144870
145563
|
return { kind: "f64" };
|
|
144871
145564
|
}
|
|
144872
|
-
function emitExternrefMemberIncDec(ctx, fctx, objLocal, propName, f64Op, mode) {
|
|
145565
|
+
function emitExternrefMemberIncDec(ctx, fctx, objLocal, propName, f64Op, mode, pinned) {
|
|
144873
145566
|
addStringConstantGlobal(ctx, propName);
|
|
144874
145567
|
const keyResult = compileStringLiteral(ctx, fctx, propName);
|
|
144875
145568
|
if (keyResult && keyResult.kind !== "externref") {
|
|
@@ -144878,16 +145571,21 @@ function emitExternrefMemberIncDec(ctx, fctx, objLocal, propName, f64Op, mode) {
|
|
|
144878
145571
|
const keyLocal = allocLocal(fctx, `__incdec_ekey_${fctx.locals.length}`, { kind: "externref" });
|
|
144879
145572
|
fctx.body.push({ op: "local.set", index: keyLocal });
|
|
144880
145573
|
fctx.body.push({ op: "local.get", index: objLocal });
|
|
144881
|
-
|
|
144882
|
-
|
|
144883
|
-
|
|
144884
|
-
|
|
144885
|
-
|
|
144886
|
-
|
|
144887
|
-
|
|
144888
|
-
|
|
144889
|
-
|
|
144890
|
-
|
|
145574
|
+
const getDispIdx = pinned ? reserveMemberGetDispatch(ctx, propName, fctx) : void 0;
|
|
145575
|
+
if (getDispIdx !== void 0) {
|
|
145576
|
+
fctx.body.push({ op: "call", funcIdx: getDispIdx });
|
|
145577
|
+
} else {
|
|
145578
|
+
fctx.body.push({ op: "local.get", index: keyLocal });
|
|
145579
|
+
const getIdx = ensureLateImport(
|
|
145580
|
+
ctx,
|
|
145581
|
+
"__extern_get",
|
|
145582
|
+
[{ kind: "externref" }, { kind: "externref" }],
|
|
145583
|
+
[{ kind: "externref" }]
|
|
145584
|
+
);
|
|
145585
|
+
flushLateImportShifts(ctx, fctx);
|
|
145586
|
+
if (getIdx !== void 0) {
|
|
145587
|
+
fctx.body.push({ op: "call", funcIdx: getIdx });
|
|
145588
|
+
}
|
|
144891
145589
|
}
|
|
144892
145590
|
addUnionImports(ctx);
|
|
144893
145591
|
const unboxIdx = ctx.funcMap.get("__unbox_number");
|
|
@@ -144914,7 +145612,7 @@ function emitExternrefMemberIncDec(ctx, fctx, objLocal, propName, f64Op, mode) {
|
|
|
144914
145612
|
[]
|
|
144915
145613
|
);
|
|
144916
145614
|
flushLateImportShifts(ctx, fctx);
|
|
144917
|
-
const dispatched = emitAlternateStructSetDispatch(
|
|
145615
|
+
const dispatched = pinned && emitAlternateStructSetDispatch(
|
|
144918
145616
|
ctx,
|
|
144919
145617
|
fctx,
|
|
144920
145618
|
objLocal,
|
|
@@ -144975,25 +145673,10 @@ function emitExternrefElementIncDec(ctx, fctx, baseLocal, keyExpr, f64Op, mode)
|
|
|
144975
145673
|
[]
|
|
144976
145674
|
);
|
|
144977
145675
|
flushLateImportShifts(ctx, fctx);
|
|
144978
|
-
|
|
144979
|
-
|
|
144980
|
-
|
|
144981
|
-
|
|
144982
|
-
ctx,
|
|
144983
|
-
fctx,
|
|
144984
|
-
baseLocal,
|
|
144985
|
-
boxedLocal,
|
|
144986
|
-
litName,
|
|
144987
|
-
/*strict*/
|
|
144988
|
-
false
|
|
144989
|
-
);
|
|
144990
|
-
}
|
|
144991
|
-
if (!dispatched) {
|
|
144992
|
-
fctx.body.push({ op: "local.get", index: baseLocal });
|
|
144993
|
-
fctx.body.push({ op: "local.get", index: keyLocal });
|
|
144994
|
-
fctx.body.push({ op: "local.get", index: boxedLocal });
|
|
144995
|
-
if (setIdx !== void 0) fctx.body.push({ op: "call", funcIdx: setIdx });
|
|
144996
|
-
}
|
|
145676
|
+
fctx.body.push({ op: "local.get", index: baseLocal });
|
|
145677
|
+
fctx.body.push({ op: "local.get", index: keyLocal });
|
|
145678
|
+
fctx.body.push({ op: "local.get", index: boxedLocal });
|
|
145679
|
+
if (setIdx !== void 0) fctx.body.push({ op: "call", funcIdx: setIdx });
|
|
144997
145680
|
fctx.body.push({ op: "local.get", index: mode === "postfix" ? oldTmp : newTmp });
|
|
144998
145681
|
return { kind: "f64" };
|
|
144999
145682
|
}
|
|
@@ -145019,6 +145702,7 @@ function compileMemberIncDec(ctx, fctx, operand, arithOp, mode) {
|
|
|
145019
145702
|
typeName = ctx.widenedVarStructMap.get(operand.expression.text);
|
|
145020
145703
|
}
|
|
145021
145704
|
if (!typeName) {
|
|
145705
|
+
const incDecPinned = operand.expression.kind === ts.SyntaxKind.ThisKeyword && fctx.thisStructName !== void 0 || resolveReceiverStruct(ctx, fctx, operand.expression) !== void 0;
|
|
145022
145706
|
const objResult2 = compileExpression$1(ctx, fctx, operand.expression);
|
|
145023
145707
|
if (objResult2) {
|
|
145024
145708
|
const objLocal = allocLocal(fctx, `__incdec_eobj_${fctx.locals.length}`, { kind: "externref" });
|
|
@@ -145026,7 +145710,7 @@ function compileMemberIncDec(ctx, fctx, operand, arithOp, mode) {
|
|
|
145026
145710
|
coerceType$2(ctx, fctx, objResult2, { kind: "externref" });
|
|
145027
145711
|
}
|
|
145028
145712
|
fctx.body.push({ op: "local.set", index: objLocal });
|
|
145029
|
-
return emitExternrefMemberIncDec(ctx, fctx, objLocal, propName, f64Op, mode);
|
|
145713
|
+
return emitExternrefMemberIncDec(ctx, fctx, objLocal, propName, f64Op, mode, incDecPinned);
|
|
145030
145714
|
}
|
|
145031
145715
|
reportSilentFallback(ctx, "const-fallback", "unary-updates:incdec-unresolvable-receiver-type", operand);
|
|
145032
145716
|
fctx.body.push({ op: "f64.const", value: NaN });
|
|
@@ -146647,11 +147331,11 @@ function compileExpressionInner(ctx, fctx, expr, expectedType) {
|
|
|
146647
147331
|
}
|
|
146648
147332
|
if (expr.kind === ts.SyntaxKind.TrueKeyword) {
|
|
146649
147333
|
fctx.body.push({ op: "i32.const", value: 1 });
|
|
146650
|
-
return { kind: "i32" };
|
|
147334
|
+
return { kind: "i32", boolean: true };
|
|
146651
147335
|
}
|
|
146652
147336
|
if (expr.kind === ts.SyntaxKind.FalseKeyword) {
|
|
146653
147337
|
fctx.body.push({ op: "i32.const", value: 0 });
|
|
146654
|
-
return { kind: "i32" };
|
|
147338
|
+
return { kind: "i32", boolean: true };
|
|
146655
147339
|
}
|
|
146656
147340
|
if (expr.kind === ts.SyntaxKind.NullKeyword) {
|
|
146657
147341
|
fctx.body.push({ op: "ref.null.extern" });
|
|
@@ -154570,7 +155254,18 @@ declare function __wasiStdinSetReader(cb: () => void): void;
|
|
|
154570
155254
|
declare function __wasiStdinStop(): void;
|
|
154571
155255
|
|
|
154572
155256
|
class __Js2wasmReadable {
|
|
154573
|
-
|
|
155257
|
+
// #2777 — accumulate drained bytes in an amortized-growth byte buffer instead
|
|
155258
|
+
// of building each 'data' chunk via per-byte string concatenation. Building the
|
|
155259
|
+
// chunk by \`this.chunk = this.chunk + String.fromCharCode(b)\` made a large
|
|
155260
|
+
// frame's read side quadratic (the consumer then re-flattened the growing
|
|
155261
|
+
// cons-rope on every charCodeAt/substring), which SIGKILLed nm_node_process at
|
|
155262
|
+
// multi-MiB. The bytes now live in \`buf[head..tail)\`; the chunk STRING the
|
|
155263
|
+
// Node 'data' contract delivers is materialised ONCE per emit/read from that
|
|
155264
|
+
// slice (a single flatten), so consumers receive a FLAT string and their
|
|
155265
|
+
// charCodeAt/substring over it is O(1)/O(k), not a re-flatten per access.
|
|
155266
|
+
private buf: Uint8Array = new Uint8Array(64);
|
|
155267
|
+
private head: number = 0;
|
|
155268
|
+
private tail: number = 0;
|
|
154574
155269
|
private dataCbs: ((c: string) => void)[] = [];
|
|
154575
155270
|
private endCbs: (() => void)[] = [];
|
|
154576
155271
|
private readableCbs: (() => void)[] = [];
|
|
@@ -154582,17 +155277,60 @@ class __Js2wasmReadable {
|
|
|
154582
155277
|
private eofReadableFired: boolean = false;
|
|
154583
155278
|
private destroyed: boolean = false;
|
|
154584
155279
|
|
|
155280
|
+
// Buffered byte count.
|
|
155281
|
+
private avail(): number { return this.tail - this.head; }
|
|
155282
|
+
|
|
155283
|
+
// Ensure room for \`extra\` more bytes at \`tail\`: first reclaim any consumed
|
|
155284
|
+
// prefix (head > 0), then amortized-double the backing array until it fits.
|
|
155285
|
+
private ensure(extra: number): void {
|
|
155286
|
+
if (this.tail + extra <= this.buf.length) { return; }
|
|
155287
|
+
if (this.head > 0) {
|
|
155288
|
+
const m = this.tail - this.head;
|
|
155289
|
+
let i = 0;
|
|
155290
|
+
while (i < m) { this.buf[i] = this.buf[this.head + i]; i = i + 1; }
|
|
155291
|
+
this.head = 0;
|
|
155292
|
+
this.tail = m;
|
|
155293
|
+
if (this.tail + extra <= this.buf.length) { return; }
|
|
155294
|
+
}
|
|
155295
|
+
let cap = this.buf.length;
|
|
155296
|
+
if (cap < 16) { cap = 16; }
|
|
155297
|
+
while (cap < this.tail + extra) { cap = cap * 2; }
|
|
155298
|
+
const nb = new Uint8Array(cap);
|
|
155299
|
+
let j = 0;
|
|
155300
|
+
while (j < this.tail) { nb[j] = this.buf[j]; j = j + 1; }
|
|
155301
|
+
this.buf = nb;
|
|
155302
|
+
}
|
|
155303
|
+
|
|
155304
|
+
// Materialise buf[start..end) as a FLAT string (one char per byte). The
|
|
155305
|
+
// trailing substring(0, len) forces a SINGLE flatten of the cons-rope built by
|
|
155306
|
+
// the per-byte concat, so the delivered chunk is flat — a consumer's
|
|
155307
|
+
// charCodeAt/substring over it is then O(1)/O(k), never a re-flatten per call.
|
|
155308
|
+
private slice(start: number, end: number): string {
|
|
155309
|
+
let s = "";
|
|
155310
|
+
let i = start;
|
|
155311
|
+
while (i < end) { s = s + String.fromCharCode(this.buf[i]); i = i + 1; }
|
|
155312
|
+
return s.substring(0, end - start);
|
|
155313
|
+
}
|
|
155314
|
+
|
|
155315
|
+
// Append all currently-buffered stdin bytes into \`buf\` — O(n), no string ops.
|
|
154585
155316
|
private drainBytes(): number {
|
|
154586
155317
|
let n = 0;
|
|
154587
155318
|
let b = __wasiStdinReadByte();
|
|
154588
|
-
while (b >= 0) {
|
|
155319
|
+
while (b >= 0) {
|
|
155320
|
+
this.ensure(1);
|
|
155321
|
+
this.buf[this.tail] = b;
|
|
155322
|
+
this.tail = this.tail + 1;
|
|
155323
|
+
n = n + 1;
|
|
155324
|
+
b = __wasiStdinReadByte();
|
|
155325
|
+
}
|
|
154589
155326
|
return n;
|
|
154590
155327
|
}
|
|
154591
155328
|
|
|
154592
155329
|
private emitChunk(): void {
|
|
154593
|
-
if (this.
|
|
154594
|
-
const out = this.
|
|
154595
|
-
this.
|
|
155330
|
+
if (this.tail <= this.head) { return; }
|
|
155331
|
+
const out = this.slice(this.head, this.tail);
|
|
155332
|
+
this.head = 0;
|
|
155333
|
+
this.tail = 0;
|
|
154596
155334
|
for (let i = 0; i < this.dataCbs.length; i = i + 1) { this.dataCbs[i](out); }
|
|
154597
155335
|
}
|
|
154598
155336
|
|
|
@@ -154605,7 +155343,7 @@ class __Js2wasmReadable {
|
|
|
154605
155343
|
// 'readable' fires when new bytes arrived OR when the stream has just reached
|
|
154606
155344
|
// EOF with bytes still buffered (Node emits a final 'readable' at end-of-
|
|
154607
155345
|
// stream so the consumer can read the last partial chunk before 'end').
|
|
154608
|
-
const eofFlush = atEof && !this.eofReadableFired && this.
|
|
155346
|
+
const eofFlush = atEof && !this.eofReadableFired && this.avail() > 0;
|
|
154609
155347
|
if (got > 0 || eofFlush) {
|
|
154610
155348
|
if (eofFlush) { this.eofReadableFired = true; }
|
|
154611
155349
|
for (let i = 0; i < this.readableCbs.length; i = i + 1) { this.readableCbs[i](); }
|
|
@@ -154614,7 +155352,7 @@ class __Js2wasmReadable {
|
|
|
154614
155352
|
// 'end' only after fd EOF AND the stream's own buffer is fully delivered
|
|
154615
155353
|
// (a paused stream withholds bytes in this.chunk, so EOF alone is not the
|
|
154616
155354
|
// end of the readable side -- matches Node).
|
|
154617
|
-
if (atEof && this.
|
|
155355
|
+
if (atEof && this.avail() === 0 && !this.ended) {
|
|
154618
155356
|
this.ended = true;
|
|
154619
155357
|
for (let i = 0; i < this.endCbs.length; i = i + 1) { this.endCbs[i](); }
|
|
154620
155358
|
}
|
|
@@ -154657,24 +155395,27 @@ class __Js2wasmReadable {
|
|
|
154657
155395
|
if (this.destroyed) { return null; }
|
|
154658
155396
|
// Pull any freshly-ready bytes so a paused .read() sees the latest buffer.
|
|
154659
155397
|
this.drainBytes();
|
|
154660
|
-
const avail = this.
|
|
155398
|
+
const avail = this.avail();
|
|
154661
155399
|
if (size === undefined || size < 0) {
|
|
154662
155400
|
if (avail === 0) { return null; }
|
|
154663
|
-
const all = this.
|
|
154664
|
-
this.
|
|
155401
|
+
const all = this.slice(this.head, this.tail);
|
|
155402
|
+
this.head = 0;
|
|
155403
|
+
this.tail = 0;
|
|
154665
155404
|
return all;
|
|
154666
155405
|
}
|
|
154667
155406
|
if (avail < size) {
|
|
154668
155407
|
if (__wasiStdinEof() && avail > 0) {
|
|
154669
|
-
const rest = this.
|
|
154670
|
-
this.
|
|
155408
|
+
const rest = this.slice(this.head, this.tail);
|
|
155409
|
+
this.head = 0;
|
|
155410
|
+
this.tail = 0;
|
|
154671
155411
|
return rest;
|
|
154672
155412
|
}
|
|
154673
155413
|
return null;
|
|
154674
155414
|
}
|
|
154675
|
-
const
|
|
154676
|
-
this.
|
|
154677
|
-
|
|
155415
|
+
const out = this.slice(this.head, this.head + size);
|
|
155416
|
+
this.head = this.head + size;
|
|
155417
|
+
if (this.head >= this.tail) { this.head = 0; this.tail = 0; }
|
|
155418
|
+
return out;
|
|
154678
155419
|
}
|
|
154679
155420
|
|
|
154680
155421
|
pause(): __Js2wasmReadable { this.paused = true; return this; }
|
|
@@ -155522,8 +156263,14 @@ function buildCodegenOptions(options, emitSourceMap, prep) {
|
|
|
155522
156263
|
utf8Storage: options.utf8Storage,
|
|
155523
156264
|
testRuntime: options.testRuntime,
|
|
155524
156265
|
wasi: options.target === "wasi",
|
|
155525
|
-
|
|
156266
|
+
// #2783 — the dynamic-linking axis: namespaces to leave as link-time imports
|
|
156267
|
+
// (deduped). `link: ["node:fs"]` is the only spelling; the old `linkNodeShims`
|
|
156268
|
+
// boolean was removed.
|
|
156269
|
+
link: [...new Set(options.link ?? [])],
|
|
155526
156270
|
standalone: options.target === "standalone",
|
|
156271
|
+
// (#2796) Diff-test-harness fidelity — defer top-level init to an export so
|
|
156272
|
+
// the host runs it after setExports (symmetric with standalone `_start`).
|
|
156273
|
+
deferTopLevelInit: options.deferTopLevelInit,
|
|
155527
156274
|
strictNoHostImports: options.strictNoHostImports,
|
|
155528
156275
|
// (#2119) thread module-strictness inference uniformly across all drivers.
|
|
155529
156276
|
inferModuleStrictArguments: options.inferModuleStrictArguments,
|
|
@@ -157704,6 +158451,7 @@ const _PROTO_CB_SLOTS = {
|
|
|
157704
158451
|
catch: { argIdx: 0, arity: 1 },
|
|
157705
158452
|
finally: { argIdx: 0, arity: 0 }
|
|
157706
158453
|
};
|
|
158454
|
+
const _VEC_PRIMITIVE_READ_METHODS = /* @__PURE__ */ new Set(["indexOf", "lastIndexOf", "includes", "join"]);
|
|
157707
158455
|
function _readIterResultField(result, field, exports$1) {
|
|
157708
158456
|
if (result != null && typeof result === "object" && _isWasmStruct(result)) {
|
|
157709
158457
|
const getter = exports$1?.[`__sget_${field}`];
|
|
@@ -159370,9 +160118,97 @@ function _setLikeRecordForHost(arg, exports$1, state) {
|
|
|
159370
160118
|
};
|
|
159371
160119
|
return { size: fixField("size"), has: fixField("has"), keys: fixField("keys") };
|
|
159372
160120
|
}
|
|
160121
|
+
function _asArrayIndex(key) {
|
|
160122
|
+
if (key === "0") return 0;
|
|
160123
|
+
if (key.length === 0 || key.charCodeAt(0) === 48) return void 0;
|
|
160124
|
+
const n = Number(key);
|
|
160125
|
+
if (Number.isInteger(n) && n >= 0 && n < 4294967295 && String(n) === key) return n;
|
|
160126
|
+
return void 0;
|
|
160127
|
+
}
|
|
160128
|
+
function _wrapVecForHost(vec, exports$1) {
|
|
160129
|
+
const cached = _hostProxyCache.get(vec);
|
|
160130
|
+
if (cached) return cached;
|
|
160131
|
+
const lenFn = exports$1.__vec_len;
|
|
160132
|
+
const getFn = exports$1.__vec_get;
|
|
160133
|
+
if (typeof lenFn !== "function" || typeof getFn !== "function") return void 0;
|
|
160134
|
+
const liveLen = () => {
|
|
160135
|
+
try {
|
|
160136
|
+
const n = lenFn(vec);
|
|
160137
|
+
return typeof n === "number" && n >= 0 ? n : 0;
|
|
160138
|
+
} catch {
|
|
160139
|
+
return 0;
|
|
160140
|
+
}
|
|
160141
|
+
};
|
|
160142
|
+
const elemAt = (i) => {
|
|
160143
|
+
try {
|
|
160144
|
+
return _wrapForHost(getFn(vec, i), exports$1);
|
|
160145
|
+
} catch {
|
|
160146
|
+
return void 0;
|
|
160147
|
+
}
|
|
160148
|
+
};
|
|
160149
|
+
const target = [];
|
|
160150
|
+
const handler = {
|
|
160151
|
+
get(_t, key) {
|
|
160152
|
+
if (key === "length") return liveLen();
|
|
160153
|
+
if (typeof key === "string") {
|
|
160154
|
+
const idx = _asArrayIndex(key);
|
|
160155
|
+
if (idx !== void 0) return idx < liveLen() ? elemAt(idx) : void 0;
|
|
160156
|
+
}
|
|
160157
|
+
return target[key];
|
|
160158
|
+
},
|
|
160159
|
+
has(_t, key) {
|
|
160160
|
+
if (key === "length") return true;
|
|
160161
|
+
if (typeof key === "string") {
|
|
160162
|
+
const idx = _asArrayIndex(key);
|
|
160163
|
+
if (idx !== void 0) return idx < liveLen();
|
|
160164
|
+
}
|
|
160165
|
+
return key in target;
|
|
160166
|
+
},
|
|
160167
|
+
ownKeys() {
|
|
160168
|
+
const n = liveLen();
|
|
160169
|
+
const keys = [];
|
|
160170
|
+
for (let i = 0; i < n; i++) keys.push(String(i));
|
|
160171
|
+
keys.push("length");
|
|
160172
|
+
return keys;
|
|
160173
|
+
},
|
|
160174
|
+
getOwnPropertyDescriptor(_t, key) {
|
|
160175
|
+
if (key === "length") {
|
|
160176
|
+
return { value: liveLen(), writable: true, enumerable: false, configurable: false };
|
|
160177
|
+
}
|
|
160178
|
+
if (typeof key === "string") {
|
|
160179
|
+
const idx = _asArrayIndex(key);
|
|
160180
|
+
if (idx !== void 0 && idx < liveLen()) {
|
|
160181
|
+
return { value: elemAt(idx), writable: true, enumerable: true, configurable: true };
|
|
160182
|
+
}
|
|
160183
|
+
}
|
|
160184
|
+
return void 0;
|
|
160185
|
+
},
|
|
160186
|
+
// Host-side writes are not part of the AST-read contract and the vec has no
|
|
160187
|
+
// general element-setter export; accept silently (keep the target clean) so
|
|
160188
|
+
// a stray host write neither throws nor leaves a phantom element. acorn's
|
|
160189
|
+
// own mutations go through `__extern_method_call` (unwrap → `__vec_push`).
|
|
160190
|
+
set() {
|
|
160191
|
+
return true;
|
|
160192
|
+
}
|
|
160193
|
+
};
|
|
160194
|
+
const proxy = new Proxy(target, handler);
|
|
160195
|
+
_hostProxyCache.set(vec, proxy);
|
|
160196
|
+
_hostProxyReverse.set(proxy, vec);
|
|
160197
|
+
return proxy;
|
|
160198
|
+
}
|
|
159373
160199
|
function _wrapForHost(obj, exports$1) {
|
|
159374
160200
|
if (obj == null || typeof obj !== "object") return obj;
|
|
159375
160201
|
if (!_isWasmStruct(obj)) return obj;
|
|
160202
|
+
if (exports$1) {
|
|
160203
|
+
try {
|
|
160204
|
+
const isVecFn = exports$1.__is_vec;
|
|
160205
|
+
if (typeof isVecFn === "function" && isVecFn(obj) === 1) {
|
|
160206
|
+
const vecView = _wrapVecForHost(obj, exports$1);
|
|
160207
|
+
if (vecView !== void 0) return vecView;
|
|
160208
|
+
}
|
|
160209
|
+
} catch {
|
|
160210
|
+
}
|
|
160211
|
+
}
|
|
159376
160212
|
const cached = _hostProxyCache.get(obj);
|
|
159377
160213
|
if (cached) return cached;
|
|
159378
160214
|
const target = /* @__PURE__ */ Object.create(null);
|
|
@@ -159418,6 +160254,13 @@ function _wrapForHost(obj, exports$1) {
|
|
|
159418
160254
|
}
|
|
159419
160255
|
} catch {
|
|
159420
160256
|
}
|
|
160257
|
+
try {
|
|
160258
|
+
const isDataFn = exports$1.__is_data_struct;
|
|
160259
|
+
if (typeof isDataFn === "function" && isDataFn(val) === 1) {
|
|
160260
|
+
return _wrapForHost(val, exports$1);
|
|
160261
|
+
}
|
|
160262
|
+
} catch {
|
|
160263
|
+
}
|
|
159421
160264
|
const exportKey = typeof key === "string" ? key : typeof key === "symbol" ? _symbolToWasm.get(key) : void 0;
|
|
159422
160265
|
if (exportKey !== void 0) {
|
|
159423
160266
|
const callFn = exports$1[`__call_${exportKey}`];
|
|
@@ -162305,6 +163148,27 @@ if (__fail) throw new Test262Error('eval harness assertion ' + __fail + ' failed
|
|
|
162305
163148
|
return exports$1.__vec_pop(rawVec);
|
|
162306
163149
|
}
|
|
162307
163150
|
}
|
|
163151
|
+
if (_VEC_PRIMITIVE_READ_METHODS.has(method) && typeof exports$1.__vec_len === "function" && typeof exports$1.__vec_get === "function") {
|
|
163152
|
+
const isVecFn = exports$1.__is_vec;
|
|
163153
|
+
let isVec = false;
|
|
163154
|
+
try {
|
|
163155
|
+
isVec = typeof isVecFn === "function" && isVecFn(rawVec) === 1;
|
|
163156
|
+
} catch {
|
|
163157
|
+
isVec = false;
|
|
163158
|
+
}
|
|
163159
|
+
if (isVec) {
|
|
163160
|
+
const len = exports$1.__vec_len(rawVec);
|
|
163161
|
+
if (typeof len === "number" && len >= 0) {
|
|
163162
|
+
const getFn = exports$1.__vec_get;
|
|
163163
|
+
const arr = new Array(len);
|
|
163164
|
+
for (let i = 0; i < len; i++) arr[i] = wrapHostValue(getFn(rawVec, i));
|
|
163165
|
+
const nativeFn = Array.prototype[method];
|
|
163166
|
+
if (typeof nativeFn === "function") {
|
|
163167
|
+
return nativeFn.apply(arr, wrappedArgs);
|
|
163168
|
+
}
|
|
163169
|
+
}
|
|
163170
|
+
}
|
|
163171
|
+
}
|
|
162308
163172
|
}
|
|
162309
163173
|
}
|
|
162310
163174
|
if ((method === "getOrInsert" || method === "getOrInsertComputed") && (wrappedObj instanceof Map || wrappedObj instanceof WeakMap)) {
|
|
@@ -162504,6 +163368,31 @@ if (__fail) throw new Test262Error('eval harness assertion ' + __fail + ' failed
|
|
|
162504
163368
|
const wrappedTarget = _wrapForHost(target, exports$1);
|
|
162505
163369
|
const wrappedSources2 = (sources ?? []).map((s) => _isWasmStruct(s) ? _wrapForHost(s, exports$1) : s);
|
|
162506
163370
|
Object.assign(wrappedTarget, ...wrappedSources2);
|
|
163371
|
+
const targetDescs = _getSidecarDescs(target);
|
|
163372
|
+
const staticFieldNames = new Set(_getStructFieldNames(target, exports$1) ?? []);
|
|
163373
|
+
for (const ws of wrappedSources2) {
|
|
163374
|
+
if (ws == null || typeof ws !== "object" && typeof ws !== "function") continue;
|
|
163375
|
+
let keys;
|
|
163376
|
+
try {
|
|
163377
|
+
keys = Reflect.ownKeys(ws);
|
|
163378
|
+
} catch {
|
|
163379
|
+
continue;
|
|
163380
|
+
}
|
|
163381
|
+
for (const k of keys) {
|
|
163382
|
+
let enumerable;
|
|
163383
|
+
try {
|
|
163384
|
+
enumerable = Object.getOwnPropertyDescriptor(ws, k)?.enumerable === true;
|
|
163385
|
+
} catch {
|
|
163386
|
+
enumerable = false;
|
|
163387
|
+
}
|
|
163388
|
+
if (!enumerable) continue;
|
|
163389
|
+
if (typeof k === "string" && staticFieldNames.has(k)) continue;
|
|
163390
|
+
const nk = _normalizeDescKey(k);
|
|
163391
|
+
if (!targetDescs.has(nk)) {
|
|
163392
|
+
targetDescs.set(nk, _SC_WRITABLE | _SC_ENUMERABLE | _SC_CONFIGURABLE | _SC_DEFINED);
|
|
163393
|
+
}
|
|
163394
|
+
}
|
|
163395
|
+
}
|
|
162507
163396
|
return target;
|
|
162508
163397
|
}
|
|
162509
163398
|
const wrappedSources = (sources ?? []).map((s) => _isWasmStruct(s) ? _wrapForHost(s, exports$1) : s);
|