@scriptc/compiler 0.0.27 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/cc.d.ts +6 -3
- package/dist/backend/cc.js +80 -27
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/object-localize.d.ts +16 -0
- package/dist/backend/object-localize.js +936 -0
- package/dist/backend/object-localize.js.map +1 -0
- package/dist/backend/object-localize.test.d.ts +1 -0
- package/dist/backend/object-localize.test.js +555 -0
- package/dist/backend/object-localize.test.js.map +1 -0
- package/dist/index.js +28 -7
- package/dist/index.js.map +1 -1
- package/dist/library/profile.js +13 -8
- package/dist/library/profile.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +1 -1
package/dist/backend/cc.d.ts
CHANGED
|
@@ -255,9 +255,12 @@ export interface LibArchiveOptions {
|
|
|
255
255
|
* symbol. Toolchain sanitizer ABI remains external as required,
|
|
256
256
|
* so N archives built under pairwise-distinct prefixes link into one
|
|
257
257
|
* process with no symbol collisions and no shared mutable runtime state.
|
|
258
|
-
* Undefined references (
|
|
259
|
-
* builds) keep their global binding.
|
|
260
|
-
*
|
|
258
|
+
* Undefined references (the target C/math runtime and system APIs, plus
|
|
259
|
+
* sanitizer ABI in instrumented builds) keep their global binding. Windows
|
|
260
|
+
* embedders additionally link advapi32, iphlpapi, and ws2_32. Omitted = the
|
|
261
|
+
* classic archive, byte-for-byte. Admitted for darwin/linux/win32 native
|
|
262
|
+
* hosts, linux and windows cross triples from any host, and macos cross
|
|
263
|
+
* triples from a darwin host (compileLibrary owns the refusal fence). */
|
|
261
264
|
localizeSymbols?: readonly string[];
|
|
262
265
|
/** Thread-instanced state (the profile's abi.instance_per_thread): every
|
|
263
266
|
* TU of the archive compiles with -DSCR_THREAD_INSTANCES, moving the
|
package/dist/backend/cc.js
CHANGED
|
@@ -6,6 +6,7 @@ import { access, chmod, copyFile, link, mkdir, mkdtemp, readdir, readFile, realp
|
|
|
6
6
|
import { availableParallelism, homedir, tmpdir } from "node:os";
|
|
7
7
|
import { basename, delimiter, dirname, extname, isAbsolute, join, resolve } from "node:path";
|
|
8
8
|
import { promisify } from "node:util";
|
|
9
|
+
import { localizeElfObject, mergeAndLocalizeCoffObjects } from "./object-localize.js";
|
|
9
10
|
const execFileAsync = promisify(execFile);
|
|
10
11
|
/** Test lanes run against one immutable checkout and one immutable toolchain
|
|
11
12
|
* for the lifetime of each Vitest worker. Production deliberately rediscovers
|
|
@@ -712,9 +713,12 @@ async function ensureTlsArchive(sanitize, driver, buildIdentity, cacheRoot = ven
|
|
|
712
713
|
* units a library may reach are the pure-data ones (regex + the vendored matcher, assert,
|
|
713
714
|
* inspect, symbol, searchParams, emitter+dyn_handle, zlib); every
|
|
714
715
|
* loop-hooked or ambient unit was refused at SC4005 before emission.
|
|
715
|
-
* External-symbol contract: undefined references only to
|
|
716
|
-
*
|
|
717
|
-
*
|
|
716
|
+
* External-symbol contract: undefined references only to the target's C/math
|
|
717
|
+
* runtime and system APIs. Windows embedders additionally link advapi32,
|
|
718
|
+
* iphlpapi, and ws2_32; the platform driver supplies its ordinary CRT and
|
|
719
|
+
* kernel imports. Zlib rides the VENDORED per-flavor objects here even on
|
|
720
|
+
* hosts because the executable lane's system `-lz` cannot ride inside an
|
|
721
|
+
* archive. */
|
|
718
722
|
/** The library base: the executable lane's unconditional sources minus the
|
|
719
723
|
* fiber/loop and child-process units, plus the library-mode TU. */
|
|
720
724
|
const LIB_RUNTIME_SOURCES = [
|
|
@@ -817,9 +821,10 @@ export async function compileLibArchive(opts) {
|
|
|
817
821
|
}
|
|
818
822
|
const vendorBuildIdentity = await currentVendorCacheBuildIdentity(driver, `${toolchainEnv}\0${implicitToolchain ?? "<uncached>"}`);
|
|
819
823
|
// Runtime-localized archives skip the completed-archive tier: their bytes
|
|
820
|
-
// additionally depend on the
|
|
821
|
-
//
|
|
822
|
-
//
|
|
824
|
+
// additionally depend on the localization toolchain's identity (host ld/
|
|
825
|
+
// objcopy or the cross driver's lld), which the archive key does not
|
|
826
|
+
// fingerprint. The runtime-object tier still serves them (localization
|
|
827
|
+
// consumes the same per-flavor objects).
|
|
823
828
|
const cacheCompleteArchive = opts.localizeSymbols === undefined &&
|
|
824
829
|
root !== null && await archiverSupportsPersistentCache(arArgv, driver);
|
|
825
830
|
let cachedArchive = null;
|
|
@@ -1054,9 +1059,11 @@ export async function compileLibArchive(opts) {
|
|
|
1054
1059
|
* renamed apart — they stop being visible to the embedder's linker at all,
|
|
1055
1060
|
* so a second archive built under a different prefix brings its own private
|
|
1056
1061
|
* copy of the whole runtime (allocator, collector, arena, panic sink) into
|
|
1057
|
-
* the same process. Undefined references (
|
|
1058
|
-
* instrumented builds) keep their global
|
|
1059
|
-
* sanitizer are the embedder's,
|
|
1062
|
+
* the same process. Undefined references (the target C/math runtime and
|
|
1063
|
+
* system APIs, plus sanitizer ABI in instrumented builds) keep their global
|
|
1064
|
+
* binding: those platform services and the sanitizer are the embedder's,
|
|
1065
|
+
* shared by design. Windows embedders additionally link advapi32, iphlpapi,
|
|
1066
|
+
* and ws2_32.
|
|
1060
1067
|
*
|
|
1061
1068
|
* Member selection matters: a classic archive's unused members (and their
|
|
1062
1069
|
* undefined references to units library mode excludes, like the
|
|
@@ -1064,26 +1071,37 @@ export async function compileLibArchive(opts) {
|
|
|
1064
1071
|
* blind merge of every object would carry those references into the one
|
|
1065
1072
|
* combined member. Staging the support objects into an intermediate
|
|
1066
1073
|
* archive keeps the linker's own member semantics: `ld -r` pulls only the
|
|
1067
|
-
* members the program object transitively needs
|
|
1074
|
+
* members the program object transitively needs (the COFF arm implements
|
|
1075
|
+
* the same member semantics in process).
|
|
1068
1076
|
*
|
|
1069
|
-
*
|
|
1077
|
+
* Mach-O — one host-ld64 invocation: -r merges program + needed members,
|
|
1070
1078
|
* -exported_symbols_list demotes every unlisted global to
|
|
1071
1079
|
* private extern, and -r without -keep_private_externs writes
|
|
1072
1080
|
* private externs out as non-external symbols. Apple ASan's
|
|
1073
1081
|
* image-registration COMMON remains shared so the final Mach-O
|
|
1074
|
-
* image registers its globals once.
|
|
1075
|
-
*
|
|
1076
|
-
*
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1079
|
-
*
|
|
1080
|
-
*
|
|
1081
|
-
*
|
|
1082
|
-
*
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1085
|
-
*
|
|
1086
|
-
*
|
|
1082
|
+
* image registers its globals once. ld64 reads every macOS
|
|
1083
|
+
* architecture, so darwin-host macos cross triples ride the
|
|
1084
|
+
* same arm; compileLibrary refuses macos targets elsewhere.
|
|
1085
|
+
* ELF, native linux host — ld -r merges with --force-group-allocation
|
|
1086
|
+
* (ASan's instrumented globals ride ELF section groups whose
|
|
1087
|
+
* signatures repeat across archives sharing runtime objects;
|
|
1088
|
+
* resolving the groups into the combined member keeps a later
|
|
1089
|
+
* multi-archive link from discarding one archive's copies),
|
|
1090
|
+
* then binutils objcopy --keep-global-symbols localizes every
|
|
1091
|
+
* other DEFINED global (objcopy leaves undefined symbols
|
|
1092
|
+
* global by its own rule). The exact historical recipe.
|
|
1093
|
+
* ELF, cross triples from any host — `zig cc -target <triple> -r`
|
|
1094
|
+
* merges (zig is already the cross driver's hard requirement),
|
|
1095
|
+
* then localizeElfObject demotes in process and resolves
|
|
1096
|
+
* section groups the way --force-group-allocation does, with
|
|
1097
|
+
* no host binutils/llvm-objcopy dependency.
|
|
1098
|
+
* COFF, native win32 hosts and windows cross triples from any host —
|
|
1099
|
+
* mergeAndLocalizeCoffObjects performs member selection, the
|
|
1100
|
+
* merge, cross-object symbol resolution, and demotion in
|
|
1101
|
+
* process: no linker offers a COFF relocatable mode (lld-link
|
|
1102
|
+
* mirrors MSVC link.exe; zig's COFF driver refuses multi-object
|
|
1103
|
+
* merges) and llvm-objcopy rejects symbol-scope flags for
|
|
1104
|
+
* COFF, so no tool pairing exists to shell out to. */
|
|
1087
1105
|
async function localizeLibraryObjects(driver, arArgv, buildDir, programObject, supportObjects, keepSymbols, stem) {
|
|
1088
1106
|
const platform = targetPlatform(driver);
|
|
1089
1107
|
const combined = join(buildDir, `${stem}.localized.o`);
|
|
@@ -1096,21 +1114,56 @@ async function localizeLibraryObjects(driver, arArgv, buildDir, programObject, s
|
|
|
1096
1114
|
catch (err) {
|
|
1097
1115
|
const stderr = err.stderr ?? String(err);
|
|
1098
1116
|
throw new Error(`${argv[0]} failed while localizing the library archive's runtime symbols (abi.localize_runtime).\n` +
|
|
1099
|
-
`Runtime symbol localization needs the
|
|
1117
|
+
`Runtime symbol localization needs the ${platform === "darwin" ? "host toolchain's ld" : driver.target === null ? "host toolchain's ld and objcopy" : "cross driver's relocatable link"} beside the C compiler.\n\n${stderr}`);
|
|
1100
1118
|
}
|
|
1101
1119
|
};
|
|
1120
|
+
if (platform === "win32") {
|
|
1121
|
+
// COFF has no relocatable-link tool to stage through; the member
|
|
1122
|
+
// selection and combine+demote happen in process over the object bytes.
|
|
1123
|
+
const [program, ...support] = await Promise.all([programObject, ...supportObjects].map((path) => readFile(path)));
|
|
1124
|
+
try {
|
|
1125
|
+
await writeFile(combined, mergeAndLocalizeCoffObjects(program, support, new Set(keepSymbols), {
|
|
1126
|
+
program: basename(programObject),
|
|
1127
|
+
support: supportObjects.map((path) => basename(path)),
|
|
1128
|
+
}));
|
|
1129
|
+
}
|
|
1130
|
+
catch (err) {
|
|
1131
|
+
throw new Error(`COFF symbol localization failed while localizing the library archive's runtime symbols (abi.localize_runtime).\n\n${err.message}`);
|
|
1132
|
+
}
|
|
1133
|
+
return combined;
|
|
1134
|
+
}
|
|
1102
1135
|
await run([arArgv[0] ?? "ar", ...arArgv.slice(1), "rcs", staging, ...supportObjects]);
|
|
1103
1136
|
if (platform === "darwin") {
|
|
1104
1137
|
await writeFile(keepFile, keepSymbols.map((s) => `_${s}\n`).join(""));
|
|
1105
1138
|
await run(["ld", "-r", programObject, staging, "-o", combined, "-exported_symbols_list", keepFile]);
|
|
1106
1139
|
}
|
|
1107
|
-
else if (platform === "linux") {
|
|
1140
|
+
else if (platform === "linux" && driver.target === null) {
|
|
1108
1141
|
await writeFile(keepFile, keepSymbols.map((s) => `${s}\n`).join(""));
|
|
1109
1142
|
await run(["ld", "-r", "--force-group-allocation", programObject, staging, "-o", combined]);
|
|
1110
1143
|
await run(["objcopy", `--keep-global-symbols=${keepFile}`, combined]);
|
|
1111
1144
|
}
|
|
1145
|
+
else if (platform === "linux") {
|
|
1146
|
+
// Cross ELF: the cross driver's own lld performs the relocatable merge
|
|
1147
|
+
// (with the staging archive's member semantics); demotion and section-
|
|
1148
|
+
// group resolution happen in process. -nostdlib keeps zig from feeding
|
|
1149
|
+
// libc/compiler-rt inputs into the merge.
|
|
1150
|
+
await run([
|
|
1151
|
+
driver.argv[0] ?? "zig",
|
|
1152
|
+
...driver.argv.slice(1),
|
|
1153
|
+
"-target", driver.target,
|
|
1154
|
+
"-nostdlib",
|
|
1155
|
+
"-r", programObject, staging,
|
|
1156
|
+
"-o", combined,
|
|
1157
|
+
]);
|
|
1158
|
+
try {
|
|
1159
|
+
await writeFile(combined, localizeElfObject(await readFile(combined), new Set(keepSymbols)));
|
|
1160
|
+
}
|
|
1161
|
+
catch (err) {
|
|
1162
|
+
throw new Error(`ELF symbol localization failed while localizing the library archive's runtime symbols (abi.localize_runtime).\n\n${err.message}`);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1112
1165
|
else {
|
|
1113
|
-
throw new Error(`runtime symbol localization (abi.localize_runtime)
|
|
1166
|
+
throw new Error(`runtime symbol localization (abi.localize_runtime) has no ${platform} arm; compileLibrary admits darwin, linux, and win32 builds only`);
|
|
1114
1167
|
}
|
|
1115
1168
|
return combined;
|
|
1116
1169
|
}
|