@wasm-oj/server 0.2.0
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/LICENSE +21 -0
- package/README.md +6 -0
- package/THIRD_PARTY_NOTICES.md +302 -0
- package/crates/runtime-core/Cargo.lock +5099 -0
- package/crates/runtime-core/Cargo.toml +66 -0
- package/crates/runtime-core/README.md +47 -0
- package/crates/runtime-core/src/bin/wasm-oj-compiler.rs +418 -0
- package/crates/runtime-core/src/bin/wasm-oj-runner.rs +294 -0
- package/crates/runtime-core/src/capabilities.rs +118 -0
- package/crates/runtime-core/src/compiler.rs +658 -0
- package/crates/runtime-core/src/contract.rs +5 -0
- package/crates/runtime-core/src/deterministic.rs +1051 -0
- package/crates/runtime-core/src/error.rs +58 -0
- package/crates/runtime-core/src/filesystem.rs +547 -0
- package/crates/runtime-core/src/filesystem_quota.rs +167 -0
- package/crates/runtime-core/src/go_compiler_session.rs +297 -0
- package/crates/runtime-core/src/interactive.rs +1019 -0
- package/crates/runtime-core/src/judge_package.rs +1539 -0
- package/crates/runtime-core/src/lib.rs +98 -0
- package/crates/runtime-core/src/memory.rs +84 -0
- package/crates/runtime-core/src/meter.rs +549 -0
- package/crates/runtime-core/src/module_imports.rs +149 -0
- package/crates/runtime-core/src/module_policy.rs +714 -0
- package/crates/runtime-core/src/output.rs +204 -0
- package/crates/runtime-core/src/run/mod.rs +208 -0
- package/crates/runtime-core/src/run/native.rs +260 -0
- package/crates/runtime-core/src/run/web.rs +229 -0
- package/crates/runtime-core/src/run/web_runtime.rs +109 -0
- package/crates/runtime-core/src/types.rs +268 -0
- package/crates/runtime-core/src/web.rs +83 -0
- package/dist/chunks/go-toolchain-Dbt-lp2L.js +426 -0
- package/dist/chunks/java-toolchain-DajoRCHu.js +44 -0
- package/dist/chunks/python-toolchain-Dx834o2A.js +4 -0
- package/dist/chunks/rust-toolchain-CJ3sMxPE.js +252 -0
- package/dist/chunks/toolchains-C6KuA1yM.js +224 -0
- package/dist/go-stage.mjs +193 -0
- package/dist/index.d.ts +221 -0
- package/dist/index.js +4393 -0
- package/dist/java-stage.mjs +111 -0
- package/dist/python-stage.mjs +90 -0
- package/dist/rustc-stage.mjs +301 -0
- package/dist/server-build-stage.mjs +2564 -0
- package/dist/server-runner-stage.mjs +155 -0
- package/licenses/fflate-MIT.txt +21 -0
- package/licenses/runtime-core-dependencies.html +6253 -0
- package/licenses/runtime-core-dependencies.json +3041 -0
- package/licenses/wasmer-sdk-MIT.txt +21 -0
- package/licenses/wasmer-sdk-dependencies.html +6901 -0
- package/licenses/wasmer-sdk-dependencies.json +3013 -0
- package/package.json +70 -0
- package/rust-toolchain.toml +5 -0
- package/testdata/wojjdg02-v2-text.hex +1 -0
- package/vendor/shared-buffer/Cargo.toml +22 -0
- package/vendor/shared-buffer/LICENSE_APACHE.md +176 -0
- package/vendor/shared-buffer/LICENSE_MIT.md +25 -0
- package/vendor/shared-buffer/README.md +34 -0
- package/vendor/shared-buffer/src/lib.rs +58 -0
- package/vendor/shared-buffer/src/mmap.rs +250 -0
- package/vendor/shared-buffer/src/owned.rs +389 -0
- package/vendor/virtual-fs/Cargo.toml +181 -0
- package/vendor/virtual-fs/LICENSE +25 -0
- package/vendor/virtual-fs/src/arc_box_file.rs +142 -0
- package/vendor/virtual-fs/src/arc_file.rs +182 -0
- package/vendor/virtual-fs/src/arc_fs.rs +68 -0
- package/vendor/virtual-fs/src/buffer_file.rs +103 -0
- package/vendor/virtual-fs/src/builder.rs +232 -0
- package/vendor/virtual-fs/src/combine_file.rs +101 -0
- package/vendor/virtual-fs/src/cow_file.rs +345 -0
- package/vendor/virtual-fs/src/dual_write_file.rs +113 -0
- package/vendor/virtual-fs/src/empty_fs.rs +81 -0
- package/vendor/virtual-fs/src/filesystems.rs +108 -0
- package/vendor/virtual-fs/src/host_fs.rs +1390 -0
- package/vendor/virtual-fs/src/lib.rs +782 -0
- package/vendor/virtual-fs/src/limiter.rs +252 -0
- package/vendor/virtual-fs/src/mem_fs/file.rs +1799 -0
- package/vendor/virtual-fs/src/mem_fs/file_opener.rs +941 -0
- package/vendor/virtual-fs/src/mem_fs/filesystem.rs +2134 -0
- package/vendor/virtual-fs/src/mem_fs/mod.rs +245 -0
- package/vendor/virtual-fs/src/mem_fs/offloaded_file.rs +474 -0
- package/vendor/virtual-fs/src/mem_fs/stdio.rs +318 -0
- package/vendor/virtual-fs/src/mount_fs.rs +2225 -0
- package/vendor/virtual-fs/src/null_file.rs +87 -0
- package/vendor/virtual-fs/src/ops.rs +364 -0
- package/vendor/virtual-fs/src/overlay_fs.rs +2216 -0
- package/vendor/virtual-fs/src/passthru_fs.rs +119 -0
- package/vendor/virtual-fs/src/pipe.rs +603 -0
- package/vendor/virtual-fs/src/random_file.rs +88 -0
- package/vendor/virtual-fs/src/special_file.rs +108 -0
- package/vendor/virtual-fs/src/static_file.rs +133 -0
- package/vendor/virtual-fs/src/static_fs.rs +460 -0
- package/vendor/virtual-fs/src/tmp_fs.rs +95 -0
- package/vendor/virtual-fs/src/trace_fs.rs +258 -0
- package/vendor/virtual-fs/src/webc_volume_fs.rs +829 -0
- package/vendor/virtual-fs/src/zero_file.rs +90 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { F as RUST_PACKAGE_MANIFEST_ASSET_PATH, I as RUST_PACKAGE_MANIFEST_SHA256, L as RUST_PACKAGE_SHA256, N as RUST_COMPRESSED_PACKAGE_SHA256, P as RUST_PACKAGE_ASSET_PATH, R as RUST_VERSION } from "./toolchains-C6KuA1yM.js";
|
|
2
|
+
/**
|
|
3
|
+
* Accept a mounted output only after byte-identical snapshots have persisted for
|
|
4
|
+
* the complete stability interval. This prevents a valid WebAssembly prefix
|
|
5
|
+
* from being mistaken for the command's final output.
|
|
6
|
+
*/
|
|
7
|
+
var MountedOutputStabilityObserver = class {
|
|
8
|
+
#stabilityMs;
|
|
9
|
+
#candidate;
|
|
10
|
+
#candidateSince = 0;
|
|
11
|
+
constructor(stabilityMs = 75) {
|
|
12
|
+
if (!Number.isFinite(stabilityMs) || stabilityMs <= 0) throw new RangeError("Mounted-output stability interval must be positive and finite.");
|
|
13
|
+
this.#stabilityMs = stabilityMs;
|
|
14
|
+
}
|
|
15
|
+
observe(snapshot, monotonicMs) {
|
|
16
|
+
if (!Number.isFinite(monotonicMs)) throw new RangeError("Mounted-output observation time must be finite.");
|
|
17
|
+
if (!snapshot) {
|
|
18
|
+
this.#candidate = void 0;
|
|
19
|
+
this.#candidateSince = 0;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!this.#candidate || !bytesEqual(this.#candidate, snapshot)) {
|
|
23
|
+
this.#candidate = snapshot.slice();
|
|
24
|
+
this.#candidateSince = monotonicMs;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (monotonicMs - this.#candidateSince < this.#stabilityMs) return void 0;
|
|
28
|
+
return snapshot.slice();
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function bytesEqual(left, right) {
|
|
32
|
+
if (left.byteLength !== right.byteLength) return false;
|
|
33
|
+
for (let index = 0; index < left.byteLength; index += 1) if (left[index] !== right[index]) return false;
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/compiler/rust-linker.ts
|
|
38
|
+
var RUST_LINKER_COMMAND = "wasm-ld";
|
|
39
|
+
var RUST_OBJECT_PATH = "/work/build/main.o";
|
|
40
|
+
var RUST_FINAL_OUTPUT_PATH = "/work/build/main.wasm";
|
|
41
|
+
var RUST_OBJECT_PLACEHOLDER = "__WASM_OJ_RUST_OBJECT__";
|
|
42
|
+
var RUST_ALLOCATOR_PLACEHOLDER = "__WASM_OJ_RUST_ALLOCATOR_BITCODE__";
|
|
43
|
+
var RUST_OUTPUT_PLACEHOLDER = "__WASM_OJ_RUST_OUTPUT__";
|
|
44
|
+
/** Validate the exact linker argv embedded in the digest-pinned Rust manifest. */
|
|
45
|
+
function decodeRustLinkerArgumentContract(value) {
|
|
46
|
+
if (!isRecord(value)) throw new Error("Pinned Rust linker arguments must be an object.");
|
|
47
|
+
if (value.objectPlaceholder !== "__WASM_OJ_RUST_OBJECT__") throw new Error("Pinned Rust linker object placeholder does not match the compiler contract.");
|
|
48
|
+
if (value.outputPlaceholder !== "__WASM_OJ_RUST_OUTPUT__") throw new Error("Pinned Rust linker output placeholder does not match the compiler contract.");
|
|
49
|
+
if (value.allocatorPlaceholder !== "__WASM_OJ_RUST_ALLOCATOR_BITCODE__") throw new Error("Pinned Rust linker allocator placeholder does not match the compiler contract.");
|
|
50
|
+
const debug = validateTemplate("debug", value.debug, "-O0");
|
|
51
|
+
const release = validateTemplate("release", value.release, "-O2");
|
|
52
|
+
return Object.freeze({
|
|
53
|
+
objectPlaceholder: RUST_OBJECT_PLACEHOLDER,
|
|
54
|
+
allocatorPlaceholder: RUST_ALLOCATOR_PLACEHOLDER,
|
|
55
|
+
outputPlaceholder: RUST_OUTPUT_PLACEHOLDER,
|
|
56
|
+
debug,
|
|
57
|
+
release
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function instantiateRustLinkerArguments(contract, optimization, allocatorBitcodePath) {
|
|
61
|
+
if (!/^\/work\/build\/main\.[a-z0-9]+\.rcgu\.bc$/i.test(allocatorBitcodePath)) throw new Error(`Rust allocator bitcode has unexpected path '${allocatorBitcodePath}'.`);
|
|
62
|
+
return (optimization === "release" ? contract.release : contract.debug).map((argument) => {
|
|
63
|
+
if (argument === contract.objectPlaceholder) return RUST_OBJECT_PATH;
|
|
64
|
+
if (argument === contract.allocatorPlaceholder) return allocatorBitcodePath;
|
|
65
|
+
if (argument === contract.outputPlaceholder) return RUST_FINAL_OUTPUT_PATH;
|
|
66
|
+
return argument;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function validateTemplate(label, value, expectedOptimization) {
|
|
70
|
+
if (!Array.isArray(value) || value.length === 0 || value.some((item) => typeof item !== "string")) throw new Error(`Pinned Rust ${label} linker arguments must be a non-empty string array.`);
|
|
71
|
+
const args = value;
|
|
72
|
+
requireExactlyOnce(args, RUST_OBJECT_PLACEHOLDER, `${label} object placeholder`);
|
|
73
|
+
requireExactlyOnce(args, RUST_ALLOCATOR_PLACEHOLDER, `${label} allocator placeholder`);
|
|
74
|
+
const outputIndex = requireExactlyOnce(args, RUST_OUTPUT_PLACEHOLDER, `${label} output placeholder`);
|
|
75
|
+
if (outputIndex === 0 || args[outputIndex - 1] !== "-o") throw new Error(`Pinned Rust ${label} linker output placeholder must follow '-o'.`);
|
|
76
|
+
requireExactlyOnce(args, expectedOptimization, `${label} linker optimization`);
|
|
77
|
+
if (!args.includes("--gc-sections") || !args.includes("--shared-memory")) throw new Error(`Pinned Rust ${label} linker arguments omit required WebAssembly flags.`);
|
|
78
|
+
if (!args.some((argument) => argument.endsWith("/self-contained/crt1-command.o"))) throw new Error(`Pinned Rust ${label} linker arguments omit the WASI command startup object.`);
|
|
79
|
+
if (!args.some((argument) => argument.startsWith("/rust/") && argument.endsWith(".rlib"))) throw new Error(`Pinned Rust ${label} linker arguments omit the Rust standard library.`);
|
|
80
|
+
for (const argument of args) {
|
|
81
|
+
if (!argument || argument.includes("\0")) throw new Error(`Pinned Rust ${label} linker arguments contain an empty or NUL-bearing value.`);
|
|
82
|
+
if (argument.startsWith("@")) throw new Error(`Pinned Rust ${label} linker arguments unexpectedly use a response file.`);
|
|
83
|
+
if (argument.startsWith("/") && (!argument.startsWith("/rust/") || argument.split("/").includes(".."))) throw new Error(`Pinned Rust ${label} linker arguments reference unmounted path '${argument}'.`);
|
|
84
|
+
}
|
|
85
|
+
return Object.freeze([...args]);
|
|
86
|
+
}
|
|
87
|
+
function requireExactlyOnce(args, value, label) {
|
|
88
|
+
const indices = args.flatMap((argument, index) => argument === value ? [index] : []);
|
|
89
|
+
if (indices.length !== 1) throw new Error(`Pinned Rust ${label} must occur exactly once.`);
|
|
90
|
+
return indices[0];
|
|
91
|
+
}
|
|
92
|
+
function isRecord(value) {
|
|
93
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/compiler/rust-toolchain.ts
|
|
97
|
+
var RUST_TARGET_TRIPLE = "wasm32-wasip1-threads";
|
|
98
|
+
var RUST_EDITION = "2024";
|
|
99
|
+
var RUST_COMPILE_TIMEOUT_MS = 18e4;
|
|
100
|
+
var RUST_UNINIT_CONST_CHUNK_THRESHOLD = "4294967295";
|
|
101
|
+
var RUST_DETERMINISTIC_REPLACEMENTS = Object.freeze(["wasi_snapshot_preview1.random_get", "wasi_snapshot_preview1.clock_time_get"]);
|
|
102
|
+
var RUST_TOOLCHAIN = Object.freeze({
|
|
103
|
+
version: RUST_VERSION,
|
|
104
|
+
packageAsset: RUST_PACKAGE_ASSET_PATH,
|
|
105
|
+
packageCompressedSha256: RUST_COMPRESSED_PACKAGE_SHA256,
|
|
106
|
+
packageSha256: RUST_PACKAGE_SHA256,
|
|
107
|
+
manifestAsset: RUST_PACKAGE_MANIFEST_ASSET_PATH,
|
|
108
|
+
manifestSha256: RUST_PACKAGE_MANIFEST_SHA256,
|
|
109
|
+
target: RUST_TARGET_TRIPLE,
|
|
110
|
+
edition: RUST_EDITION
|
|
111
|
+
});
|
|
112
|
+
function rustcObjectArguments(entry, optimization, rootExterns = []) {
|
|
113
|
+
const optimizationArguments = optimization === "release" ? [
|
|
114
|
+
"-C",
|
|
115
|
+
"opt-level=2",
|
|
116
|
+
"-C",
|
|
117
|
+
"debuginfo=0"
|
|
118
|
+
] : [
|
|
119
|
+
"-C",
|
|
120
|
+
"opt-level=0",
|
|
121
|
+
"-C",
|
|
122
|
+
"debuginfo=1"
|
|
123
|
+
];
|
|
124
|
+
return [
|
|
125
|
+
"--target",
|
|
126
|
+
RUST_TARGET_TRIPLE,
|
|
127
|
+
"--sysroot",
|
|
128
|
+
"/rust",
|
|
129
|
+
"-Zno-parallel-backend",
|
|
130
|
+
"-Z",
|
|
131
|
+
"threads=1",
|
|
132
|
+
"-Z",
|
|
133
|
+
"randomize-layout=no",
|
|
134
|
+
"-Z",
|
|
135
|
+
"layout-seed=0",
|
|
136
|
+
"-Z",
|
|
137
|
+
`uninit-const-chunk-threshold=${RUST_UNINIT_CONST_CHUNK_THRESHOLD}`,
|
|
138
|
+
"-C",
|
|
139
|
+
"codegen-units=1",
|
|
140
|
+
"-C",
|
|
141
|
+
"llvm-args=-rng-seed=1",
|
|
142
|
+
"-C",
|
|
143
|
+
"metadata=wasm_oj_submission",
|
|
144
|
+
"-C",
|
|
145
|
+
"target-feature=+atomics,+bulk-memory,+mutable-globals",
|
|
146
|
+
`/work/${entry}`,
|
|
147
|
+
"--crate-name",
|
|
148
|
+
"wasm_oj_submission",
|
|
149
|
+
"--crate-type",
|
|
150
|
+
"bin",
|
|
151
|
+
"--edition",
|
|
152
|
+
RUST_EDITION,
|
|
153
|
+
"--error-format=json",
|
|
154
|
+
"--json=diagnostic-rendered-ansi",
|
|
155
|
+
"--remap-path-prefix=/work=.",
|
|
156
|
+
"-C",
|
|
157
|
+
"panic=abort",
|
|
158
|
+
...rootExterns.flatMap((item) => ["--extern", `${item.crateName}=${item.path}`]),
|
|
159
|
+
...optimizationArguments,
|
|
160
|
+
"-C",
|
|
161
|
+
"save-temps=yes",
|
|
162
|
+
"--emit=obj",
|
|
163
|
+
"-o",
|
|
164
|
+
RUST_OBJECT_PATH
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
function rustcDependencyArguments(dependency, optimization) {
|
|
168
|
+
const optimizationArguments = optimization === "release" ? [
|
|
169
|
+
"-C",
|
|
170
|
+
"opt-level=2",
|
|
171
|
+
"-C",
|
|
172
|
+
"debuginfo=0"
|
|
173
|
+
] : [
|
|
174
|
+
"-C",
|
|
175
|
+
"opt-level=0",
|
|
176
|
+
"-C",
|
|
177
|
+
"debuginfo=1"
|
|
178
|
+
];
|
|
179
|
+
return [
|
|
180
|
+
"--target",
|
|
181
|
+
RUST_TARGET_TRIPLE,
|
|
182
|
+
"--sysroot",
|
|
183
|
+
"/rust",
|
|
184
|
+
"-Zno-parallel-backend",
|
|
185
|
+
"-Z",
|
|
186
|
+
"threads=1",
|
|
187
|
+
"-Z",
|
|
188
|
+
"randomize-layout=no",
|
|
189
|
+
"-Z",
|
|
190
|
+
"layout-seed=0",
|
|
191
|
+
"-C",
|
|
192
|
+
"codegen-units=1",
|
|
193
|
+
"-C",
|
|
194
|
+
"llvm-args=-rng-seed=1",
|
|
195
|
+
"-C",
|
|
196
|
+
`metadata=${dependency.id}`,
|
|
197
|
+
"-C",
|
|
198
|
+
"target-feature=+atomics,+bulk-memory,+mutable-globals",
|
|
199
|
+
`/work/${dependency.root}`,
|
|
200
|
+
"--crate-name",
|
|
201
|
+
dependency.crateName,
|
|
202
|
+
"--crate-type",
|
|
203
|
+
"rlib",
|
|
204
|
+
"--edition",
|
|
205
|
+
dependency.edition,
|
|
206
|
+
"--error-format=json",
|
|
207
|
+
"--json=diagnostic-rendered-ansi",
|
|
208
|
+
"--remap-path-prefix=/work=.",
|
|
209
|
+
"-C",
|
|
210
|
+
"panic=abort",
|
|
211
|
+
"--cap-lints",
|
|
212
|
+
"allow",
|
|
213
|
+
...dependency.features.flatMap((feature) => ["--cfg", `feature=${JSON.stringify(feature)}`]),
|
|
214
|
+
...dependency.externs.flatMap((item) => ["--extern", `${item.crateName}=${item.path}`]),
|
|
215
|
+
...optimizationArguments,
|
|
216
|
+
"--emit=link",
|
|
217
|
+
"-o",
|
|
218
|
+
dependency.outputPath
|
|
219
|
+
];
|
|
220
|
+
}
|
|
221
|
+
function deterministicRustCompilerEnvironment() {
|
|
222
|
+
return {
|
|
223
|
+
RUST_MIN_STACK: "16777216",
|
|
224
|
+
SOURCE_DATE_EPOCH: "946684800",
|
|
225
|
+
TZ: "UTC",
|
|
226
|
+
LC_ALL: "C"
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function deterministicRustLinkerEnvironment() {
|
|
230
|
+
return {
|
|
231
|
+
SOURCE_DATE_EPOCH: "946684800",
|
|
232
|
+
TZ: "UTC",
|
|
233
|
+
LC_ALL: "C",
|
|
234
|
+
VSLANG: "1033"
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function decodeRustToolchainManifest(bytes) {
|
|
238
|
+
const manifest = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
239
|
+
const compiler = asRecord(manifest.compiler, "compiler");
|
|
240
|
+
const linker = asRecord(manifest.linker, "linker");
|
|
241
|
+
const pipeline = asRecord(manifest.pipeline, "pipeline");
|
|
242
|
+
const output = asRecord(manifest.output, "output");
|
|
243
|
+
const mounts = asRecord(manifest.filesystemMounts, "filesystemMounts");
|
|
244
|
+
if (manifest.version !== RUST_TOOLCHAIN.version || manifest.target !== RUST_TOOLCHAIN.target || compiler.command !== "rustc" || JSON.stringify(compiler.deterministicReplacements) !== JSON.stringify(RUST_DETERMINISTIC_REPLACEMENTS) || linker.command !== "wasm-ld" || pipeline.strategy !== "rustc-object-then-wasm-ld" || pipeline.objectEmission !== "rustc --emit=obj -C save-temps=yes" || pipeline.allocatorShim !== "rustc-generated LLVM bitcode" || pipeline.linkArgsSource !== "rustc --print=link-args" || mounts.rust !== "/rust" || mounts.linker !== "/usr" || output.sha256 !== RUST_TOOLCHAIN.packageSha256 || output.compressedSha256 !== RUST_TOOLCHAIN.packageCompressedSha256) throw new Error("Pinned Rust toolchain manifest does not match the compiler contract.");
|
|
245
|
+
return Object.freeze({ linkerArguments: decodeRustLinkerArgumentContract(linker.arguments) });
|
|
246
|
+
}
|
|
247
|
+
function asRecord(value, label) {
|
|
248
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Pinned Rust toolchain manifest '${label}' field must be an object.`);
|
|
249
|
+
return value;
|
|
250
|
+
}
|
|
251
|
+
//#endregion
|
|
252
|
+
export { deterministicRustLinkerEnvironment as a, RUST_FINAL_OUTPUT_PATH as c, instantiateRustLinkerArguments as d, MountedOutputStabilityObserver as f, deterministicRustCompilerEnvironment as i, RUST_LINKER_COMMAND as l, RUST_TOOLCHAIN as n, rustcDependencyArguments as o, decodeRustToolchainManifest as r, rustcObjectArguments as s, RUST_COMPILE_TIMEOUT_MS as t, RUST_OBJECT_PATH as u };
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { isBuiltinLanguage } from "@wasm-oj/contracts";
|
|
2
|
+
//#region src/core/toolchains.ts
|
|
3
|
+
var CLANG_VERSION = "22.0.0-git20542-10";
|
|
4
|
+
var CLANG_PACKAGE = `wasm-oj/clang@${CLANG_VERSION}`;
|
|
5
|
+
var CLANG_PACKAGE_ASSET_PATH = `/toolchains/clang-${CLANG_VERSION}.webc.gz.bin`;
|
|
6
|
+
var CLANG_CC1_PINS_ASSET_PATH = `/toolchains/clang-${CLANG_VERSION}.cc1-pins.json`;
|
|
7
|
+
var CLANG_MANIFEST_ASSET_PATH = `/toolchains/clang-${CLANG_VERSION}.manifest.json`;
|
|
8
|
+
var CLANG_LIBCXX_PCH_MANIFEST_ASSET_PATH = `/toolchains/clang-${CLANG_VERSION}.libcxx-pch.json`;
|
|
9
|
+
var CLANG_LIBCXX_PCH_DEBUG_ASSET_PATH = `/toolchains/clang-${CLANG_VERSION}.cpp-debug.pch.gz.bin`;
|
|
10
|
+
var CLANG_LIBCXX_PCH_RELEASE_ASSET_PATH = `/toolchains/clang-${CLANG_VERSION}.cpp-release.pch.gz.bin`;
|
|
11
|
+
var CLANG_COMPRESSED_PACKAGE_SHA256 = "7f10d90b8e52b270f04874641a1d0bf9e94e85b4f6c7573a774cebbc6d32552a";
|
|
12
|
+
/** SHA-256 after browser-side gzip decompression. */
|
|
13
|
+
var CLANG_PACKAGE_SHA256 = "21ded33b9c6d4e1aaad5528c940bdaf6c3e84be77ea8f522f018ca7289a2a224";
|
|
14
|
+
/** SHA-256 of the pinned cc1/wasm-ld argv manifest; regenerated by scripts/pin-clang-cc1-argv.mjs. */
|
|
15
|
+
var CLANG_CC1_PINS_SHA256 = "66c4604dccd3f89d8e1472bf4432367d7396cce4a01279b1a1db445f229dba72";
|
|
16
|
+
var CLANG_MANIFEST_SHA256 = "6382dcdfb6a2da49032a0e08da3b1fb490eb24432be85c3c12e3e871a5065273";
|
|
17
|
+
/** Updated atomically with the generated toolchain-admitted PCH assets. */
|
|
18
|
+
var CLANG_LIBCXX_PCH_MANIFEST_SHA256 = "d126c99e951a7302d4ea2b66da4ed64d3d74e9d319d562518867c8d8c97a06b8";
|
|
19
|
+
var CLANG_LIBCXX_PCH = Object.freeze({
|
|
20
|
+
"cpp-debug": Object.freeze({
|
|
21
|
+
path: CLANG_LIBCXX_PCH_DEBUG_ASSET_PATH,
|
|
22
|
+
sha256: "05a4db721448ba33e65977cb4ac366908ea215ab377e3b6d09f1fd224d515b68",
|
|
23
|
+
compressedSha256: "a4152027d248412eca8aec3e7e23f6f7c81f95170cae9fd385bcf02e57e91fc9"
|
|
24
|
+
}),
|
|
25
|
+
"cpp-release": Object.freeze({
|
|
26
|
+
path: CLANG_LIBCXX_PCH_RELEASE_ASSET_PATH,
|
|
27
|
+
sha256: "aec9e778ac527c120ba369b9b0e142cf8206d11365801208847ba0e1c39daa1a",
|
|
28
|
+
compressedSha256: "18f4ca8ab8ca7888db572ba34146fc1acb213a7e7305000ea6285188f52f99f4"
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
var PYTHON_VERSION = "3.14.6";
|
|
32
|
+
var PYTHON_PACKAGE_SHA256 = "454ffc53936aa13a0d7f4afbb5bd50ada339c8ebd04bbf27ea19e4104cf43207";
|
|
33
|
+
var PYTHON_PACKAGE = `${`wasm-oj/cpython@${PYTHON_VERSION}`}#sha256:${PYTHON_PACKAGE_SHA256}`;
|
|
34
|
+
var PYTHON_PACKAGE_ASSET_PATH = `/toolchains/python-${PYTHON_VERSION}-wasip1.webc.gz.bin`;
|
|
35
|
+
var PYTHON_PACKAGE_MANIFEST_ASSET_PATH = `/toolchains/python-${PYTHON_VERSION}-wasip1.manifest.json`;
|
|
36
|
+
var PYTHON_COMPRESSED_PACKAGE_SHA256 = "218cd20ac4abb443e0700816010a615a345a43eae623a0232da2227135a6c7a6";
|
|
37
|
+
var PYTHON_PACKAGE_MANIFEST_SHA256 = "054eccad04a7cee7ba1661062142ef0d639976850981eab8fc785f48eb26129e";
|
|
38
|
+
var PYTHON_RUNTIME_FILES_ARCHIVE_SHA256 = "44d894f91487f20c2bb04fe496a9343db37d8720fb706472c2b4a7f3300db039";
|
|
39
|
+
var QUICKJS_VERSION = "0.15.1";
|
|
40
|
+
var QUICKJS_PACKAGE = `wasm-oj/quickjs-ng@${QUICKJS_VERSION}`;
|
|
41
|
+
var QUICKJS_ASSET_PATH = `/toolchains/quickjs-${QUICKJS_VERSION}.wasm.gz.bin`;
|
|
42
|
+
var QUICKJS_ASSET_SHA256 = "8c7f0588210490e7d77f198fc91f72c1b94787ab4c359c4786ca59a363c4f5e8";
|
|
43
|
+
var TYPESCRIPT_VERSION = "7.0.2";
|
|
44
|
+
var TYPESCRIPT_ASSET_PATH = `/toolchains/typescript-${TYPESCRIPT_VERSION}.wasm.gz.bin`;
|
|
45
|
+
var TYPESCRIPT_ASSET_SHA256 = "06e58ce887d95d1895055699b8dc96a1cde7d1f2baa48de40f9b790e3271dc16";
|
|
46
|
+
var RUST_VERSION = "1.91.1-dev";
|
|
47
|
+
var RUST_PACKAGE_ASSET_PATH = `/toolchains/rust-${RUST_VERSION}.webc.gz.bin`;
|
|
48
|
+
var RUST_PACKAGE_MANIFEST_ASSET_PATH = `/toolchains/rust-${RUST_VERSION}.manifest.json`;
|
|
49
|
+
var RUST_COMPRESSED_PACKAGE_SHA256 = "cfbdadc67be1315e735aa55bdf8a5a0d00171982a023fefcf7ba586127753887";
|
|
50
|
+
/** SHA-256 after browser-side gzip decompression. */
|
|
51
|
+
var RUST_PACKAGE_SHA256 = "765de8d68d03078e79f69f49dec0dcab1ff96fe3bbe5e9eafebb2ce61a39d3ee";
|
|
52
|
+
var RUST_PACKAGE_MANIFEST_SHA256 = "d5bbdca994e61888679c5738cb9420649c0854ed0eb5d65468bc67d5d550bce1";
|
|
53
|
+
var GO_VERSION = "1.26.5";
|
|
54
|
+
var GO_PACKAGE_ASSET_PATH = `/toolchains/go-${GO_VERSION}-wasip1.webc.gz.bin`;
|
|
55
|
+
var GO_PACKAGE_MANIFEST_ASSET_PATH = `/toolchains/go-${GO_VERSION}-wasip1.manifest.json`;
|
|
56
|
+
var GO_STANDARD_LIBRARY_ASSET_PATH = `/toolchains/go-${GO_VERSION}-wasip1.stdlib.gz.bin`;
|
|
57
|
+
var GO_COMPRESSED_PACKAGE_SHA256 = "70a7e359884b09b2e1a622d6ac5cd6e31c334aab519e6dd80dff5e040a9e09e4";
|
|
58
|
+
var GO_PACKAGE_SHA256 = "c3a97934b6a83fefdea5c31f99141f70f76189eedc9ec0fa9ccd41302e50963b";
|
|
59
|
+
var GO_PACKAGE_MANIFEST_SHA256 = "5d784e9ca640b9525e84b598c0beb97ca110ae908568ca45f6441a441d99a262";
|
|
60
|
+
var GO_COMPRESSED_STANDARD_LIBRARY_SHA256 = "aeffc384fdc624544f174ba5fc3c22395717fdbc3c4387d677d20855b6be80d8";
|
|
61
|
+
var GO_STANDARD_LIBRARY_SHA256 = "e1ec64b08efd02b35b7ffdaf3970875aaae98325fa4795eafca94ebae2d0d192";
|
|
62
|
+
var GO_COMPILER_SHA256 = "9e557f5b86961fd604217d7521461c5d2b7322e383fa30dead5669b77db12201";
|
|
63
|
+
var GO_LINKER_SHA256 = "2eefca10af935a307ab7946447146bd30e0ea0fb5460be54dc1c55844d155580";
|
|
64
|
+
var JAVA_VERSION = "teavm-0.13.1-wasi";
|
|
65
|
+
var JAVA_COMPILER_PACKAGE = `wasm-oj/java-teavm@${JAVA_VERSION}`;
|
|
66
|
+
var JAVA_COMPILER_ASSET_PATH = "/toolchains/java-teavm-0.13.1.wasi.compiler.webc.gz.bin";
|
|
67
|
+
var JAVA_COMPILE_CLASSLIB_ASSET_PATH = "/toolchains/java-teavm-0.13.1.compile-classlib.bin";
|
|
68
|
+
var JAVA_RUNTIME_CLASSLIB_ASSET_PATH = "/toolchains/java-teavm-0.13.1.runtime-classlib.bin";
|
|
69
|
+
var JAVA_COMPILER_COMPRESSED_PACKAGE_SHA256 = "129f1f51d591e58954f88787d36396b856a9a68ba3ae9c9d14f20bd67c2c7722";
|
|
70
|
+
var JAVA_COMPILER_PACKAGE_SHA256 = "f8f86761cf31062565187e4a66f73b6903f257fe84c0ce70ea1cd28441b6c2e9";
|
|
71
|
+
var JAVA_COMPILER_SHA256 = "33a0d662395256f10a5d02ea305fc7b18007b2b8fe8996859017b084d3d19735";
|
|
72
|
+
var JAVA_COMPILE_CLASSLIB_SHA256 = "acfe3fb09e5f2c0c7c8dc2339c66fcdadc1f8e1bf1c74be446926175ef770868";
|
|
73
|
+
var JAVA_RUNTIME_CLASSLIB_SHA256 = "21a9394586e416af2fca4eb0ed08521cbc8924e1d1afaa07863a59a3cfae54ab";
|
|
74
|
+
Object.freeze({
|
|
75
|
+
[CLANG_PACKAGE_ASSET_PATH]: CLANG_COMPRESSED_PACKAGE_SHA256,
|
|
76
|
+
[CLANG_CC1_PINS_ASSET_PATH]: CLANG_CC1_PINS_SHA256,
|
|
77
|
+
[CLANG_MANIFEST_ASSET_PATH]: CLANG_MANIFEST_SHA256,
|
|
78
|
+
[CLANG_LIBCXX_PCH_MANIFEST_ASSET_PATH]: CLANG_LIBCXX_PCH_MANIFEST_SHA256,
|
|
79
|
+
[CLANG_LIBCXX_PCH_DEBUG_ASSET_PATH]: CLANG_LIBCXX_PCH["cpp-debug"].compressedSha256,
|
|
80
|
+
[CLANG_LIBCXX_PCH_RELEASE_ASSET_PATH]: CLANG_LIBCXX_PCH["cpp-release"].compressedSha256,
|
|
81
|
+
[PYTHON_PACKAGE_ASSET_PATH]: PYTHON_COMPRESSED_PACKAGE_SHA256,
|
|
82
|
+
[PYTHON_PACKAGE_MANIFEST_ASSET_PATH]: PYTHON_PACKAGE_MANIFEST_SHA256,
|
|
83
|
+
[QUICKJS_ASSET_PATH]: QUICKJS_ASSET_SHA256,
|
|
84
|
+
[TYPESCRIPT_ASSET_PATH]: TYPESCRIPT_ASSET_SHA256,
|
|
85
|
+
[RUST_PACKAGE_ASSET_PATH]: RUST_COMPRESSED_PACKAGE_SHA256,
|
|
86
|
+
[RUST_PACKAGE_MANIFEST_ASSET_PATH]: RUST_PACKAGE_MANIFEST_SHA256,
|
|
87
|
+
[GO_PACKAGE_ASSET_PATH]: GO_COMPRESSED_PACKAGE_SHA256,
|
|
88
|
+
[GO_PACKAGE_MANIFEST_ASSET_PATH]: GO_PACKAGE_MANIFEST_SHA256,
|
|
89
|
+
[GO_STANDARD_LIBRARY_ASSET_PATH]: GO_COMPRESSED_STANDARD_LIBRARY_SHA256,
|
|
90
|
+
[JAVA_COMPILER_ASSET_PATH]: JAVA_COMPILER_COMPRESSED_PACKAGE_SHA256,
|
|
91
|
+
[JAVA_COMPILE_CLASSLIB_ASSET_PATH]: JAVA_COMPILE_CLASSLIB_SHA256,
|
|
92
|
+
[JAVA_RUNTIME_CLASSLIB_ASSET_PATH]: JAVA_RUNTIME_CLASSLIB_SHA256
|
|
93
|
+
});
|
|
94
|
+
var TOOLCHAIN_CONTENT_SHA256 = Object.freeze({
|
|
95
|
+
c: Object.freeze([
|
|
96
|
+
CLANG_COMPRESSED_PACKAGE_SHA256,
|
|
97
|
+
CLANG_PACKAGE_SHA256,
|
|
98
|
+
CLANG_CC1_PINS_SHA256,
|
|
99
|
+
CLANG_MANIFEST_SHA256
|
|
100
|
+
]),
|
|
101
|
+
cpp: Object.freeze([
|
|
102
|
+
CLANG_COMPRESSED_PACKAGE_SHA256,
|
|
103
|
+
CLANG_PACKAGE_SHA256,
|
|
104
|
+
CLANG_CC1_PINS_SHA256,
|
|
105
|
+
CLANG_MANIFEST_SHA256
|
|
106
|
+
]),
|
|
107
|
+
rust: Object.freeze([
|
|
108
|
+
RUST_COMPRESSED_PACKAGE_SHA256,
|
|
109
|
+
RUST_PACKAGE_SHA256,
|
|
110
|
+
RUST_PACKAGE_MANIFEST_SHA256
|
|
111
|
+
]),
|
|
112
|
+
python: Object.freeze([
|
|
113
|
+
PYTHON_COMPRESSED_PACKAGE_SHA256,
|
|
114
|
+
PYTHON_PACKAGE_SHA256,
|
|
115
|
+
PYTHON_PACKAGE_MANIFEST_SHA256,
|
|
116
|
+
PYTHON_RUNTIME_FILES_ARCHIVE_SHA256
|
|
117
|
+
]),
|
|
118
|
+
javascript: Object.freeze([TYPESCRIPT_ASSET_SHA256, QUICKJS_ASSET_SHA256]),
|
|
119
|
+
typescript: Object.freeze([TYPESCRIPT_ASSET_SHA256, QUICKJS_ASSET_SHA256]),
|
|
120
|
+
go: Object.freeze([
|
|
121
|
+
GO_COMPRESSED_PACKAGE_SHA256,
|
|
122
|
+
GO_PACKAGE_SHA256,
|
|
123
|
+
GO_PACKAGE_MANIFEST_SHA256,
|
|
124
|
+
GO_COMPRESSED_STANDARD_LIBRARY_SHA256,
|
|
125
|
+
GO_STANDARD_LIBRARY_SHA256,
|
|
126
|
+
GO_COMPILER_SHA256,
|
|
127
|
+
GO_LINKER_SHA256
|
|
128
|
+
])
|
|
129
|
+
});
|
|
130
|
+
/** Exact executable/compiler content used by cache keys and cost calibration. */
|
|
131
|
+
function toolchainContentIdentity(language) {
|
|
132
|
+
if (language === "java") return [
|
|
133
|
+
JAVA_COMPILER_COMPRESSED_PACKAGE_SHA256,
|
|
134
|
+
JAVA_COMPILER_PACKAGE_SHA256,
|
|
135
|
+
JAVA_COMPILER_SHA256,
|
|
136
|
+
JAVA_COMPILE_CLASSLIB_SHA256,
|
|
137
|
+
JAVA_RUNTIME_CLASSLIB_SHA256
|
|
138
|
+
].join(".");
|
|
139
|
+
if (!isBuiltinLanguage(language)) throw new Error(`WASM-OJ has no built-in toolchain for '${language}'.`);
|
|
140
|
+
return TOOLCHAIN_CONTENT_SHA256[language].join(".");
|
|
141
|
+
}
|
|
142
|
+
function freezeToolchain(definition) {
|
|
143
|
+
return Object.freeze({
|
|
144
|
+
...definition,
|
|
145
|
+
compilerPackages: Object.freeze([...definition.compilerPackages]),
|
|
146
|
+
targets: Object.freeze([...definition.targets])
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
var TOOLCHAINS = Object.freeze({
|
|
150
|
+
c: freezeToolchain({
|
|
151
|
+
language: "c",
|
|
152
|
+
label: "Clang 22",
|
|
153
|
+
artifact: "wasm",
|
|
154
|
+
compilerPackages: [CLANG_PACKAGE],
|
|
155
|
+
targets: ["wasip1", "wasix"],
|
|
156
|
+
version: CLANG_VERSION,
|
|
157
|
+
note: "Native wasip1 module via Clang and LLD; directly executable by WASI and WASIX runtimes."
|
|
158
|
+
}),
|
|
159
|
+
cpp: freezeToolchain({
|
|
160
|
+
language: "cpp",
|
|
161
|
+
label: "Clang++ 22 (C++20)",
|
|
162
|
+
artifact: "wasm",
|
|
163
|
+
compilerPackages: [CLANG_PACKAGE],
|
|
164
|
+
targets: ["wasip1", "wasix"],
|
|
165
|
+
version: CLANG_VERSION,
|
|
166
|
+
note: "C++20/libc++ wasip1 module; directly executable by WASI and WASIX runtimes."
|
|
167
|
+
}),
|
|
168
|
+
rust: freezeToolchain({
|
|
169
|
+
language: "rust",
|
|
170
|
+
label: `Rust ${RUST_VERSION}`,
|
|
171
|
+
artifact: "wasm",
|
|
172
|
+
compilerPackages: [`rustc@${RUST_VERSION}#sha256:${RUST_PACKAGE_SHA256}`],
|
|
173
|
+
targets: ["wasip1"],
|
|
174
|
+
version: RUST_VERSION,
|
|
175
|
+
note: "Real rustc, its matching standard library, and a fresh deterministic wasm-ld stage execute as one pinned WebC under Wasmer."
|
|
176
|
+
}),
|
|
177
|
+
python: freezeToolchain({
|
|
178
|
+
language: "python",
|
|
179
|
+
label: `CPython ${PYTHON_VERSION}`,
|
|
180
|
+
artifact: "runtime-bundle",
|
|
181
|
+
compilerPackages: [PYTHON_PACKAGE],
|
|
182
|
+
runtimePackage: PYTHON_PACKAGE,
|
|
183
|
+
targets: ["wasip1"],
|
|
184
|
+
version: PYTHON_VERSION,
|
|
185
|
+
note: "Byte-compiled project bundled with the source-built CPython wasm32-wasip1 interpreter and standard library."
|
|
186
|
+
}),
|
|
187
|
+
javascript: freezeToolchain({
|
|
188
|
+
language: "javascript",
|
|
189
|
+
label: "QuickJS-ng",
|
|
190
|
+
artifact: "runtime-bundle",
|
|
191
|
+
compilerPackages: [`typescript@${TYPESCRIPT_VERSION}-wasi`],
|
|
192
|
+
runtimePackage: QUICKJS_PACKAGE,
|
|
193
|
+
targets: ["wasip1"],
|
|
194
|
+
version: QUICKJS_VERSION,
|
|
195
|
+
note: "JavaScript checked by TypeScript/WASI, then executed by the bundled QuickJS-ng/WASI runtime."
|
|
196
|
+
}),
|
|
197
|
+
typescript: freezeToolchain({
|
|
198
|
+
language: "typescript",
|
|
199
|
+
label: "TypeScript + QuickJS-ng",
|
|
200
|
+
artifact: "runtime-bundle",
|
|
201
|
+
compilerPackages: [`typescript@${TYPESCRIPT_VERSION}-wasi`],
|
|
202
|
+
runtimePackage: QUICKJS_PACKAGE,
|
|
203
|
+
targets: ["wasip1"],
|
|
204
|
+
version: TYPESCRIPT_VERSION,
|
|
205
|
+
note: "The native TypeScript compiler and QuickJS-ng runtime both execute as local WASI modules."
|
|
206
|
+
}),
|
|
207
|
+
go: freezeToolchain({
|
|
208
|
+
language: "go",
|
|
209
|
+
label: `Go ${GO_VERSION}`,
|
|
210
|
+
artifact: "wasm",
|
|
211
|
+
compilerPackages: [`go@${GO_VERSION}#sha256:${GO_PACKAGE_SHA256}`],
|
|
212
|
+
targets: ["wasip1"],
|
|
213
|
+
version: GO_VERSION,
|
|
214
|
+
note: "The standard Go compiler, linker, and pinned wasip1 standard library execute locally as one WebC under Wasmer."
|
|
215
|
+
})
|
|
216
|
+
});
|
|
217
|
+
function toolchainPackageIdentities(language) {
|
|
218
|
+
if (language === "java") return [JAVA_COMPILER_PACKAGE];
|
|
219
|
+
if (!isBuiltinLanguage(language)) throw new Error(`WASM-OJ has no built-in toolchain for '${language}'.`);
|
|
220
|
+
const toolchain = TOOLCHAINS[language];
|
|
221
|
+
return [.../* @__PURE__ */ new Set([...toolchain.compilerPackages, ...toolchain.runtimePackage ? [toolchain.runtimePackage] : []])];
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { PYTHON_PACKAGE_ASSET_PATH as A, TYPESCRIPT_VERSION as B, JAVA_COMPILE_CLASSLIB_ASSET_PATH as C, JAVA_VERSION as D, JAVA_RUNTIME_CLASSLIB_SHA256 as E, RUST_PACKAGE_MANIFEST_ASSET_PATH as F, toolchainPackageIdentities as H, RUST_PACKAGE_MANIFEST_SHA256 as I, RUST_PACKAGE_SHA256 as L, QUICKJS_PACKAGE as M, RUST_COMPRESSED_PACKAGE_SHA256 as N, PYTHON_COMPRESSED_PACKAGE_SHA256 as O, RUST_PACKAGE_ASSET_PATH as P, RUST_VERSION as R, JAVA_COMPILER_PACKAGE_SHA256 as S, JAVA_RUNTIME_CLASSLIB_ASSET_PATH as T, toolchainContentIdentity as V, GO_STANDARD_LIBRARY_SHA256 as _, CLANG_PACKAGE_ASSET_PATH as a, JAVA_COMPILER_COMPRESSED_PACKAGE_SHA256 as b, GO_COMPILER_SHA256 as c, GO_LINKER_SHA256 as d, GO_PACKAGE_ASSET_PATH as f, GO_STANDARD_LIBRARY_ASSET_PATH as g, GO_PACKAGE_SHA256 as h, CLANG_LIBCXX_PCH_MANIFEST_SHA256 as i, PYTHON_PACKAGE_SHA256 as j, PYTHON_PACKAGE as k, GO_COMPRESSED_PACKAGE_SHA256 as l, GO_PACKAGE_MANIFEST_SHA256 as m, CLANG_CC1_PINS_SHA256 as n, CLANG_PACKAGE_SHA256 as o, GO_PACKAGE_MANIFEST_ASSET_PATH as p, CLANG_LIBCXX_PCH_MANIFEST_ASSET_PATH as r, CLANG_VERSION as s, CLANG_CC1_PINS_ASSET_PATH as t, GO_COMPRESSED_STANDARD_LIBRARY_SHA256 as u, GO_VERSION as v, JAVA_COMPILE_CLASSLIB_SHA256 as w, JAVA_COMPILER_PACKAGE as x, JAVA_COMPILER_ASSET_PATH as y, TYPESCRIPT_ASSET_PATH as z };
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { a as decodeGoToolchainManifest, c as goCompileDependencyArguments, d as reachableGoDependencies, f as validateGoStandardLibrary, i as GO_TOOLCHAIN, l as goImportConfig, o as deterministicGoCompilerEnvironment, r as GO_OUTPUT_PATH, s as goCompileArguments, t as GO_ARCHIVE_PATH, u as goLinkArguments } from "./chunks/go-toolchain-Dbt-lp2L.js";
|
|
2
|
+
import { writeFileSync } from "node:fs";
|
|
3
|
+
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { gunzipSync } from "node:zlib";
|
|
9
|
+
//#region src/server/go-stage.mjs
|
|
10
|
+
var COMPILER_MEMORY_LIMIT_BYTES = 536870912;
|
|
11
|
+
var COMPILER_OUTPUT_LIMIT_BYTES = 33554432;
|
|
12
|
+
var COMPILER_RESPONSE_LIMIT_BYTES = 268435456;
|
|
13
|
+
var temporaryDirectory;
|
|
14
|
+
try {
|
|
15
|
+
const encoded = JSON.parse(await readStdin());
|
|
16
|
+
const verifiedToolchain = encoded.verifiedToolchain === true;
|
|
17
|
+
let [packageBytes, manifest, standardLibrary] = await Promise.all([
|
|
18
|
+
loadGoPackage(requiredToolchainAsset(encoded, GO_TOOLCHAIN.packageAsset), verifiedToolchain),
|
|
19
|
+
loadGoManifest(requiredToolchainAsset(encoded, GO_TOOLCHAIN.manifestAsset), verifiedToolchain),
|
|
20
|
+
loadGoStandardLibrary(requiredToolchainAsset(encoded, GO_TOOLCHAIN.standardLibraryAsset), verifiedToolchain)
|
|
21
|
+
]);
|
|
22
|
+
validateGoStandardLibrary(standardLibrary, manifest.packages);
|
|
23
|
+
temporaryDirectory = await mkdtemp(path.join(os.tmpdir(), "wasm-oj-go-toolchain-"));
|
|
24
|
+
const packagePath = path.join(temporaryDirectory, "go.webc");
|
|
25
|
+
const standardLibraryPath = path.join(temporaryDirectory, "go-stdlib.wasmojgo");
|
|
26
|
+
await writeFile(packagePath, packageBytes, {
|
|
27
|
+
flag: "wx",
|
|
28
|
+
mode: 384
|
|
29
|
+
});
|
|
30
|
+
await writeFile(standardLibraryPath, standardLibrary, {
|
|
31
|
+
flag: "wx",
|
|
32
|
+
mode: 384
|
|
33
|
+
});
|
|
34
|
+
packageBytes = void 0;
|
|
35
|
+
standardLibrary = void 0;
|
|
36
|
+
const sourceFiles = Object.fromEntries(encoded.request.files.map((file) => [`/work/${file.path}`, file.content]));
|
|
37
|
+
const dependencySourceFiles = Object.fromEntries((encoded.request.dependencyFiles ?? []).map((file) => [`/work/${file.path}`, file.content]));
|
|
38
|
+
const dependencies = reachableGoDependencies(encoded.request.files, encoded.request.dependencies ?? [], manifest.packages);
|
|
39
|
+
const importPackages = [...manifest.packages, ...dependencies.map((item) => ({
|
|
40
|
+
importPath: item.importPath,
|
|
41
|
+
archivePath: item.archivePath
|
|
42
|
+
}))];
|
|
43
|
+
const sharedFilesBase64 = Object.fromEntries(Object.entries({
|
|
44
|
+
...sourceFiles,
|
|
45
|
+
...dependencySourceFiles,
|
|
46
|
+
"/go/VERSION": `go${GO_TOOLCHAIN.version}\n`,
|
|
47
|
+
"/work/importcfg": goImportConfig(importPackages, false),
|
|
48
|
+
"/work/importcfg.link": goImportConfig(importPackages, true)
|
|
49
|
+
}).map(([guestPath, contents]) => [guestPath, Buffer.from(contents).toString("base64")]));
|
|
50
|
+
const common = {
|
|
51
|
+
env: deterministicGoCompilerEnvironment(),
|
|
52
|
+
stdinBase64: "",
|
|
53
|
+
filesBase64: {},
|
|
54
|
+
cwd: "/work",
|
|
55
|
+
outputLimitBytes: COMPILER_OUTPUT_LIMIT_BYTES
|
|
56
|
+
};
|
|
57
|
+
const results = (await runCompiler(encoded.compilerExecutable, {
|
|
58
|
+
schema: encoded.compileBatchSchema,
|
|
59
|
+
packagePath,
|
|
60
|
+
memoryLimitBytes: COMPILER_MEMORY_LIMIT_BYTES,
|
|
61
|
+
sharedFilesArchivePath: standardLibraryPath,
|
|
62
|
+
sharedFilesBase64,
|
|
63
|
+
requests: [
|
|
64
|
+
...dependencies.map((dependency) => ({
|
|
65
|
+
...common,
|
|
66
|
+
command: "go-compile",
|
|
67
|
+
args: goCompileDependencyArguments(dependency, encoded.request.optimization),
|
|
68
|
+
outputPaths: [dependency.archivePath]
|
|
69
|
+
})),
|
|
70
|
+
{
|
|
71
|
+
...common,
|
|
72
|
+
command: "go-compile",
|
|
73
|
+
args: goCompileArguments(encoded.request.files, encoded.request.optimization),
|
|
74
|
+
outputPaths: [GO_ARCHIVE_PATH]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
...common,
|
|
78
|
+
command: "go-link",
|
|
79
|
+
args: goLinkArguments(encoded.request.optimization),
|
|
80
|
+
outputPaths: [GO_OUTPUT_PATH]
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
})).responses.flatMap((response) => response.result ? [response.result] : []);
|
|
84
|
+
const stdout = results.map((result) => Buffer.from(result.stdoutBase64, "base64").toString("utf8")).join("");
|
|
85
|
+
const stderr = results.map((result) => Buffer.from(result.stderrBase64, "base64").toString("utf8")).join("");
|
|
86
|
+
const linked = results.at(-1);
|
|
87
|
+
const wasmBase64 = linked?.code === 0 ? linked.outputFilesBase64?.[GO_OUTPUT_PATH] : void 0;
|
|
88
|
+
writeResult({
|
|
89
|
+
success: results.length === dependencies.length + 2 && results.every((result) => result.code === 0) && typeof wasmBase64 === "string",
|
|
90
|
+
wasmBase64,
|
|
91
|
+
stdout,
|
|
92
|
+
stderr
|
|
93
|
+
});
|
|
94
|
+
} catch (error) {
|
|
95
|
+
writeResult(void 0, error instanceof Error ? error.message : String(error));
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
} finally {
|
|
98
|
+
if (temporaryDirectory) await rm(temporaryDirectory, {
|
|
99
|
+
recursive: true,
|
|
100
|
+
force: true
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function runCompiler(executable, request) {
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const child = spawn(executable, [], { stdio: [
|
|
106
|
+
"pipe",
|
|
107
|
+
"pipe",
|
|
108
|
+
"pipe"
|
|
109
|
+
] });
|
|
110
|
+
const stdout = [];
|
|
111
|
+
const stderr = [];
|
|
112
|
+
let stdoutBytes = 0;
|
|
113
|
+
let stderrBytes = 0;
|
|
114
|
+
let failure;
|
|
115
|
+
const fail = (error) => {
|
|
116
|
+
failure ??= error;
|
|
117
|
+
child.kill("SIGKILL");
|
|
118
|
+
};
|
|
119
|
+
child.stdout.on("data", (chunk) => {
|
|
120
|
+
stdoutBytes += chunk.byteLength;
|
|
121
|
+
if (stdoutBytes > COMPILER_RESPONSE_LIMIT_BYTES) fail(/* @__PURE__ */ new Error(`WASM-OJ compiler response exceeded ${COMPILER_RESPONSE_LIMIT_BYTES} bytes.`));
|
|
122
|
+
else stdout.push(chunk);
|
|
123
|
+
});
|
|
124
|
+
child.stderr.on("data", (chunk) => {
|
|
125
|
+
stderrBytes += chunk.byteLength;
|
|
126
|
+
if (stderrBytes > COMPILER_OUTPUT_LIMIT_BYTES) fail(/* @__PURE__ */ new Error(`WASM-OJ compiler diagnostics exceeded ${COMPILER_OUTPUT_LIMIT_BYTES} bytes.`));
|
|
127
|
+
else stderr.push(chunk);
|
|
128
|
+
});
|
|
129
|
+
child.on("error", fail);
|
|
130
|
+
child.stdin.on("error", fail);
|
|
131
|
+
child.on("close", () => {
|
|
132
|
+
if (failure) {
|
|
133
|
+
reject(failure);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const text = Buffer.concat(stdout).toString("utf8");
|
|
138
|
+
if (!text) throw new Error(Buffer.concat(stderr).toString("utf8") || "WASM-OJ compiler returned no response.");
|
|
139
|
+
resolve(JSON.parse(text));
|
|
140
|
+
} catch (error) {
|
|
141
|
+
reject(error);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
child.stdin.end(JSON.stringify(request));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function writeResult(result, error) {
|
|
148
|
+
writeFileSync(3, JSON.stringify(result ? {
|
|
149
|
+
ok: true,
|
|
150
|
+
result
|
|
151
|
+
} : {
|
|
152
|
+
ok: false,
|
|
153
|
+
error
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
async function loadGoPackage(file, verifiedToolchain) {
|
|
157
|
+
const compressed = await readFile(file);
|
|
158
|
+
if (!verifiedToolchain) verifyDigest(file, compressed, GO_TOOLCHAIN.packageCompressedSha256);
|
|
159
|
+
const bytes = uint8View(gunzipSync(compressed));
|
|
160
|
+
if (!verifiedToolchain) verifyDigest("decompressed Go WebC", bytes, GO_TOOLCHAIN.packageSha256);
|
|
161
|
+
return bytes;
|
|
162
|
+
}
|
|
163
|
+
async function loadGoManifest(file, verifiedToolchain) {
|
|
164
|
+
const bytes = new Uint8Array(await readFile(file));
|
|
165
|
+
if (!verifiedToolchain) verifyDigest(file, bytes, GO_TOOLCHAIN.manifestSha256);
|
|
166
|
+
return decodeGoToolchainManifest(bytes);
|
|
167
|
+
}
|
|
168
|
+
async function loadGoStandardLibrary(file, verifiedToolchain) {
|
|
169
|
+
const compressed = await readFile(file);
|
|
170
|
+
if (!verifiedToolchain) verifyDigest(file, compressed, GO_TOOLCHAIN.standardLibraryCompressedSha256);
|
|
171
|
+
const bytes = uint8View(gunzipSync(compressed));
|
|
172
|
+
if (!verifiedToolchain) verifyDigest("decompressed Go standard library", bytes, GO_TOOLCHAIN.standardLibrarySha256);
|
|
173
|
+
return bytes;
|
|
174
|
+
}
|
|
175
|
+
function requiredToolchainAsset(encoded, assetPath) {
|
|
176
|
+
const file = encoded?.toolchainAssets?.[assetPath];
|
|
177
|
+
if (typeof file !== "string" || !path.isAbsolute(file)) throw new Error(`The Go compiler stage did not receive absolute asset '${assetPath}'.`);
|
|
178
|
+
return file;
|
|
179
|
+
}
|
|
180
|
+
function verifyDigest(label, bytes, expected) {
|
|
181
|
+
const actual = createHash("sha256").update(bytes).digest("hex");
|
|
182
|
+
if (actual !== expected) throw new Error(`Pinned Go toolchain asset '${label}' has digest ${actual}; expected ${expected}.`);
|
|
183
|
+
}
|
|
184
|
+
function uint8View(bytes) {
|
|
185
|
+
return new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
186
|
+
}
|
|
187
|
+
async function readStdin() {
|
|
188
|
+
const chunks = [];
|
|
189
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
190
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
export {};
|