Build the bootstrap test's own seed without the function layout

The bootstrap test builds its own seed when CI shares none, and that build
still applied the committed function layout, so its LLVM listed functions in
a different order from the native compiler's own emission. Both seed builds
now share one environment, which leaves the layout out.
This commit is contained in:
Chris Tate
2026-10-25 23:42:51 -05:00
parent f2c53ff2f8
commit a8080733df
3 changed files with 33 additions and 17 deletions
+14 -9
View File
@@ -25,6 +25,19 @@ export function verifyBootstrapSeed(directory, revision, sanitize) {
}
}
/** The environment a bootstrap seed builds with, over the inherited one. The
* bootstrap compares the seed's LLVM with the native compiler's own emission,
* which has no function layout. The layout only orders the functions, so the
* seed is built without it. */
export function seedBuildEnvironment(sanitize) {
return {
SCRIPTC_SAN: sanitize ? "1" : "",
SCRIPTC_NATIVE_EMIT_IR: "1",
SCRIPTC_NATIVE_OPTIMIZATION: sanitize ? "dev" : "release",
SCRIPTC_NATIVE_LAYOUT: "",
};
}
async function main() {
const directory = process.env.SCRIPTC_BOOTSTRAP_SEED_DIRECTORY;
const revision = process.env.GITHUB_SHA;
@@ -47,15 +60,7 @@ async function main() {
{
cwd: root,
stdio: "inherit",
env: {
...process.env,
SCRIPTC_NATIVE_EMIT_IR: "1",
SCRIPTC_NATIVE_OPTIMIZATION: sanitize ? "dev" : "release",
// The bootstrap compares the seed's LLVM with the native compiler's
// own emission, which has no function layout. The layout only orders
// the functions, so the seed is built without it.
SCRIPTC_NATIVE_LAYOUT: "",
},
env: { ...process.env, ...seedBuildEnvironment(sanitize) },
},
);
writeFileSync(
+17 -1
View File
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { load } from "js-yaml";
import { expect, test } from "vitest";
import { verifyBootstrapSeed } from "../../scripts/bootstrap-seed.mjs";
import { seedBuildEnvironment, verifyBootstrapSeed } from "../../scripts/bootstrap-seed.mjs";
test("bootstrap artifacts require a complete seed from the same revision, lane, and path", () => {
const directory = mkdtempSync(join(tmpdir(), "scriptc-seed-contract-"));
@@ -36,6 +36,22 @@ test("bootstrap artifacts require a complete seed from the same revision, lane,
}
});
test("seeds build without the function layout in both lanes, shared or not", () => {
for (const sanitize of [false, true])
expect(seedBuildEnvironment(sanitize)).toEqual({
SCRIPTC_SAN: sanitize ? "1" : "",
SCRIPTC_NATIVE_EMIT_IR: "1",
SCRIPTC_NATIVE_OPTIMIZATION: sanitize ? "dev" : "release",
SCRIPTC_NATIVE_LAYOUT: "",
});
// The bootstrap test builds its own seed when CI shares none.
const driver = readFileSync(
new URL("./self-hosting-native-driver.test.ts", import.meta.url),
"utf8",
);
expect(driver).toContain("...seedBuildEnvironment(sanitize)");
});
test("CI restores each seed only into its matching instrumented bootstrap lane", () => {
const workflow = load(
readFileSync(new URL("../../.github/workflows/ci.yml", import.meta.url), "utf8"),
@@ -1,4 +1,4 @@
import { verifyBootstrapSeed } from "../../scripts/bootstrap-seed.mjs";
import { seedBuildEnvironment, verifyBootstrapSeed } from "../../scripts/bootstrap-seed.mjs";
import { execFile, spawnSync } from "node:child_process";
import {
chmodSync,
@@ -89,12 +89,7 @@ test(
// seed avoids optimizing the huge compiler module before ASan can
// exercise its complete traversal, serialization and LLVM emission.
...options,
env: {
...process.env,
SCRIPTC_SAN: sanitize ? "1" : "",
SCRIPTC_NATIVE_EMIT_IR: "1",
SCRIPTC_NATIVE_OPTIMIZATION: sanitize ? "dev" : "release",
},
env: { ...process.env, ...seedBuildEnvironment(sanitize) },
},
),
);