mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-22 05:59:31 +08:00
- Remove C emission, debugging options, and automatic backend fallback. - Complete LLVM lowering and native bootstrap coverage across supported targets. - Link executables and libraries with precompiled C runtime packs, including iOS and Android.
54 lines
2.7 KiB
TypeScript
54 lines
2.7 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { deserializeModule, serializeModule } from "../../../packages/compiler/src/ir/serialize.js";
|
|
import { validateModule } from "../../../packages/compiler/src/ir/validate.js";
|
|
import { scalarizeNumericRecords } from "../../../packages/compiler/src/ir/scalar-records.js";
|
|
import { findConstantNumericTables } from "../../../packages/compiler/src/ir/constant-tables.js";
|
|
import { matchIntegerBytesForLoop } from "../../../packages/compiler/src/ir/integer-loops.js";
|
|
import { everyStmtList } from "../../../packages/compiler/src/ir/traverse.js";
|
|
import { computeMayThrow } from "../../../packages/compiler/src/backend/may-throw.js";
|
|
import { computeTraced } from "../../../packages/compiler/src/backend/cycle-analysis.js";
|
|
|
|
try {
|
|
const mod = deserializeModule(readFileSync(process.argv[2]!, "utf8"));
|
|
if (process.argv[3] === "optimize") {
|
|
const before = validateModule(mod);
|
|
if (before.length > 0) throw new Error(JSON.stringify(before));
|
|
const original = serializeModule(mod);
|
|
const optimized = scalarizeNumericRecords(mod);
|
|
if (serializeModule(mod) !== original) throw new Error("optimizer mutated its input");
|
|
const after = validateModule(optimized);
|
|
if (after.length > 0) throw new Error(JSON.stringify(after));
|
|
console.log(serializeModule(optimized));
|
|
} else {
|
|
// Analysis deliberately accepts structural IR too: e.g. link/unwind
|
|
// decisions can be inspected without constructing executable FFI calls.
|
|
const may = computeMayThrow(mod);
|
|
const traced = computeTraced(mod);
|
|
const tables: { id: string; symbol: string; values: string[] }[] = [];
|
|
for (const [id, table] of findConstantNumericTables(mod)) {
|
|
tables.push({ id, symbol: table.symbol, values: table.values.map((value) => Object.is(value, -0) ? "-0" : String(value)) });
|
|
}
|
|
const loops: { fn: string; localId: string; receiver: string }[] = [];
|
|
for (const fn of mod.functions) {
|
|
const locals = new Map(fn.locals.map((local) => [local.id, local]));
|
|
everyStmtList(fn.body, { expr: () => true, stmt: (stmt) => {
|
|
if (stmt.kind === "for") {
|
|
const loop = matchIntegerBytesForLoop(stmt, locals);
|
|
if (loop && loop.limitReceiver.kind === "varRef") {
|
|
loops.push({ fn: fn.name, localId: loop.localId, receiver: loop.limitReceiver.localId });
|
|
}
|
|
}
|
|
return true;
|
|
} });
|
|
}
|
|
console.log(JSON.stringify({
|
|
mayThrow: [...may.fns], indirect: may.indirect,
|
|
tracedShapes: [...traced.shapes], tracedUnions: [...traced.unions], tables, loops,
|
|
}));
|
|
}
|
|
} catch (error) {
|
|
if (error instanceof Error) console.log(error.name + ": " + error.message);
|
|
else console.log("unexpected thrown value");
|
|
process.exitCode = 1;
|
|
}
|