mirror of
https://github.com/morluto/rea
synced 2026-10-27 06:33:32 -04:00
fix(javascript): converge cyclic aliases with explicit projection widening
Replace initializer-history and full-path enumeration with a finite projection join at each source read. Retain conservative local returned-reference effects and disclose precision loss through static, semantic and captured-web results. Close full-binding callback cycles while preserving narrowed read semantics. Fixes #4348 Fixes #5138 Refs #4349 Refs #4364 Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Fuxuan-CN <3072252442@qq.com>
This commit is contained in:
@@ -61,7 +61,8 @@ it("bounds shared partial callback alias expansion by AST size", () => {
|
||||
);
|
||||
try {
|
||||
expect(
|
||||
createSemanticReturnedReferences(context.state)(last.argument.callee),
|
||||
createSemanticReturnedReferences(context.state)(last.argument.callee)
|
||||
.references,
|
||||
).toHaveLength(1);
|
||||
return {
|
||||
callReads,
|
||||
@@ -154,7 +155,8 @@ return a${depth}.make();}`);
|
||||
);
|
||||
try {
|
||||
expect(
|
||||
createSemanticReturnedReferences(context.state)(last.argument.callee),
|
||||
createSemanticReturnedReferences(context.state)(last.argument.callee)
|
||||
.references,
|
||||
).toHaveLength(1);
|
||||
return lookups.reduce(
|
||||
(total, lookup) => total + lookup.mock.calls.length,
|
||||
@@ -231,3 +233,37 @@ it("does not memoize alias cycle cuts across entry paths", () => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const meshLookups = (writes: number): number => {
|
||||
const source = `function f(){} function g(){} let a=f,b=g;
|
||||
function run(){${Array.from({ length: writes }, (_, index) =>
|
||||
index % 2 === 0 ? "a=b;" : "b=a;",
|
||||
).join("")} a();}`;
|
||||
const context = indexed(source);
|
||||
const run = context.state.program.body[3];
|
||||
if (!t.isFunctionDeclaration(run)) throw new Error("Missing run");
|
||||
const statement = run.body.body.at(-1);
|
||||
if (
|
||||
!t.isExpressionStatement(statement) ||
|
||||
!t.isCallExpression(statement.expression)
|
||||
)
|
||||
throw new Error("Missing mesh call");
|
||||
const lookups = vi.spyOn(context.bindingCache, "get");
|
||||
const result = context.resolve(statement.expression.callee);
|
||||
expect(result).toMatchObject({ complete: false, cycleDependent: true });
|
||||
expect(
|
||||
result.callableIds.map((id) => context.callableById.get(id)?.name).sort(),
|
||||
).toEqual(["f", "g"]);
|
||||
return lookups.mock.calls.length;
|
||||
};
|
||||
|
||||
it("closes cycles at full-binding reads with bounded lookup growth", () => {
|
||||
const six = meshLookups(6);
|
||||
const eight = meshLookups(8);
|
||||
const ten = meshLookups(10);
|
||||
const twelve = meshLookups(12);
|
||||
expect(six).toBeGreaterThan(0);
|
||||
expect(eight).toBeLessThan(3 * six);
|
||||
expect(ten).toBeLessThan(3 * eight);
|
||||
expect(twelve).toBeLessThan(3 * ten);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user