Rename each shared libCall once when switching to child property tables (#2381)

This commit is contained in:
Chris Tate
2026-10-26 23:22:58 -05:00
committed by GitHub
2 changed files with 29 additions and 2 deletions
@@ -0,0 +1,26 @@
import { expect, test } from "vitest";
import { VOID, type IrExpr, type IrFunction, type IrStmt, type SrcLoc } from "../../ir/ir.js";
import { applyHandleProperties } from "./handle-properties.js";
import { ENTRY_NAME, type Lowerer } from "./lowerer.js";
const loc: SrcLoc = { file: "main.ts", start: 0, end: 1 };
const fn = (name: string, body: IrStmt[]): IrFunction => ({
name,
body,
params: [],
locals: [],
returnType: VOID,
loc,
});
test("renames a libCall the IR reaches from several statements once", () => {
const call: IrExpr = { kind: "libCall", fn: "dyn.defineProperty", args: [], type: VOID, loc };
const use: IrStmt = { kind: "exprStmt", expr: call, loc };
const functions = [fn(ENTRY_NAME, [use, use]), fn("helper", [use])];
applyHandleProperties({ writesOntoChildren: true } as unknown as Lowerer, functions);
expect(call).toMatchObject({ kind: "libCall", fn: "child.propsDefine" });
expect(functions[0]!.body[0]).toMatchObject({
kind: "exprStmt",
expr: { kind: "libCall", fn: "child.propsInstall" },
});
});
@@ -283,10 +283,11 @@ const RENAMES: ReadonlyMap<IrLibFn, IrLibFn> = new Map<IrLibFn, IrLibFn>([
* property-table entries (in place) and installs the table in %main. */
export function applyHandleProperties(lowerer: Lowerer, functions: IrFunction[]): void {
if (!lowerer.writesOntoChildren && !childAdditions(lowerer).any) return;
const calls: (IrExpr & { kind: "libCall" })[] = [];
// A node the IR shares at several places is renamed once.
const calls = new Set<IrExpr & { kind: "libCall" }>();
const visitor = {
expr: (e: IrExpr): boolean => {
if (e.kind === "libCall" && RENAMES.has(e.fn)) calls.push(e);
if (e.kind === "libCall" && RENAMES.has(e.fn)) calls.add(e);
return true;
},
stmt: (): boolean => true,