mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-28 06:53:42 +08:00
* feat: support wasm32-wasi as a production target - Add production LLVM WASI codegen with a 32-bit ABI, coroutines, and dynamic modules - Integrate WASI builds and execution into the CLI with capability diagnostics - Add differential coverage and document the fourth production target Co-authored-by: Albert <57402359+bulatovv@users.noreply.github.com> * fix: address wasm target review findings * fix WASI guest paths and fetch alias detection * fix WASI async bridge and fetch detection --------- Co-authored-by: Albert <57402359+bulatovv@users.noreply.github.com>
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import { tmpdir } from "node:os";
|
|
import { buildTargetPlatform, wasiGuestPath } from "@scriptc/compiler";
|
|
|
|
/** Default executable filename for the build target. Explicit --out paths
|
|
* stay exact; only scriptc's generated default needs the Windows PE suffix. */
|
|
export function defaultExecutableName(stem: string, platform: string = buildTargetPlatform()): string {
|
|
if (platform === "win32") return `${stem}.exe`;
|
|
if (platform === "wasi") return `${stem}.wasm`;
|
|
return stem;
|
|
}
|
|
|
|
/** Host paths exposed by `scriptc run` to a WASI Preview 1 module. Guest
|
|
* `/tmp` maps to the host's real platform temp directory instead of assuming
|
|
* the POSIX spelling exists (notably false on Windows). */
|
|
export function wasiPreopens(
|
|
cwd: string = process.cwd(),
|
|
hostTmp: string = tmpdir(),
|
|
): Record<string, string> {
|
|
return { "/": cwd, "/tmp": hostTmp };
|
|
}
|
|
|
|
/** Environment inherited by a WASI module. Host-absolute directory values
|
|
* must not claim paths outside the guest namespace: `/` is the module's
|
|
* capability root/home/cwd and `/tmp` is its writable temporary directory. */
|
|
export function wasiEnvironment(
|
|
env: NodeJS.ProcessEnv = process.env,
|
|
cwd: string = process.cwd(),
|
|
hostTmp: string = tmpdir(),
|
|
): Record<string, string> {
|
|
const guest = Object.fromEntries(
|
|
Object.entries(env).filter((entry): entry is [string, string] => entry[1] !== undefined),
|
|
);
|
|
|
|
guest["PWD"] = "/";
|
|
guest["HOME"] = "/";
|
|
guest["TMPDIR"] = "/tmp";
|
|
if (guest["USERPROFILE"] !== undefined) guest["USERPROFILE"] = "/";
|
|
if (guest["TMP"] !== undefined) guest["TMP"] = "/tmp";
|
|
if (guest["TEMP"] !== undefined) guest["TEMP"] = "/tmp";
|
|
|
|
// These optional shell/package-manager paths retain their meaning only
|
|
// when they fall under a capability the runner actually exposes.
|
|
for (const key of ["OLDPWD", "INIT_CWD"] as const) {
|
|
const value = guest[key];
|
|
if (value === undefined) continue;
|
|
const mapped = wasiGuestPath(value, cwd, hostTmp);
|
|
if (mapped === null) delete guest[key];
|
|
else guest[key] = mapped;
|
|
}
|
|
|
|
return guest;
|
|
}
|