fix(javascript): preserve builtin identity and share alias traversal

Track module writes and escapes at their owner, preserve capture and reassignment ordering, and share CommonJS/default namespace identity without erasing parent-slot changes. Carry write sites into ambient alias resolution and use parsed write targets across consumers. Deduplicate returned-reference work with cycle context; retain unchanged temporal selection identity so provenance memoization stays effective.

Reviewed fixes include #2041, #2465, #2830, #2881, and #2948. Remove superseded mutation representations and the ineffective per-markValue dedup layer.

Validation: 380 focused JavaScript tests passed under a 384 MiB heap cap, including the previously aborting 30-level/128-call alias regression. Six public CLI/MCP builtin tests passed. Exact pdf.js completed-workflow performance remains unmeasured.
This commit is contained in:
morluto committed 2026-10-14 08:44:52 +08:00
1 parent 0f4c484be5
commit 04672f2b91
34 files changed
+3778 -321

No files matched your search

@@ -1,7 +1,5 @@
import * as t from "@babel/types";
import { semanticBuiltinNamespacePath } from "./javascriptSemanticProvenance.js";
import type {
JavaScriptSemanticCallable,
JavaScriptSemanticEventOperation,
@@ -18,6 +16,7 @@ import {
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
import { range } from "./javascriptStaticAnalysisHelpers.js";
import {
builtinDataEffectMethod,
dataEffectLiteralString,
dataEffectMemberCallee,
assignedSemanticResultBindings,
@@ -308,22 +307,11 @@ const timerMethod = (
? null
: method;
}
return timerMethodFromBinding(binding);
}
if (!t.isMemberExpression(callee) && !t.isOptionalMemberExpression(callee))
return null;
const method = admittedTimerMethod(
semanticStaticPropertyName(callee.property, callee.computed),
return admittedTimerMethod(
builtinDataEffectMethod(callee, state, ["timers", "node:timers"]) ?? "",
);
return method !== null &&
t.isIdentifier(callee.object) &&
timerNamespaceBinding(
resolveSemanticBindingState(state, callee.object, callee.object.name),
)
? method
: null;
};
const admittedTimerMethod = (
value: string,
): JavaScriptSemanticTimerOperation["method"] | null =>
@@ -331,28 +319,6 @@ const admittedTimerMethod = (
(candidate) => candidate === value,
) ?? null;
const timerMethodFromBinding = (
binding: JavaScriptSemanticBindingState,
): JavaScriptSemanticTimerOperation["method"] | null => {
for (const { specifier, importedPath } of binding.directOrigins) {
if (!timerModule(specifier)) continue;
const method = admittedTimerMethod(importedPath.at(-1) ?? "");
if (method !== null) return method;
}
return null;
};
const timerNamespaceBinding = (
binding: JavaScriptSemanticBindingState | undefined,
): boolean =>
binding?.directOrigins.some(
({ specifier, importedPath }) =>
timerModule(specifier) && semanticBuiltinNamespacePath(importedPath),
) ?? false;
const timerModule = (specifier: string): boolean =>
specifier === "timers" || specifier === "node:timers";
const bindingId = (
node:
| t.Expression