mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
`JSON.parse(text) as T`, `const x: T = anyValue` and `await res.json() as T` threw `TypeError: expected X at $.path, got Y` when the value did not fit `T`. Node never checks an assertion and continues with the value it has, so the build-container listener rejected an order Node accepts and a JWT with a string `exp` became a 500. A failed cast now keeps its value when it initializes a `const`/`let` binding declared in a function or block and only the code after the cast reads the binding. That code (the statements after the cast in each enclosing statement list, up to the declaration) lowers twice: the static copy, unchanged, runs while the value fits; a dynamic copy, in which the binding and everything derived from it is typed `any`, runs after a failure, so missing members read undefined, wrong-typed members keep their values, extra members stay visible in source order, and objects keep their identity. The cast sets the flag that selects the copy: the fused JSON.parse helper's slow path and the plain check call scr_dyn_check_recover, which takes back the TypeError and parks the value for checkedCast.fallbackTaken/fallbackTake. A failed value that flows into a typed slot outside the region is checked there, as any `any` value is: it continues when it fits and throws at that use when it does not. A statement of the dynamic copy with no `any` lowering becomes a runtime fence that throws only when a failed value reaches it. Module-level bindings, regions with hoisted declarations or super() calls, union targets and targets holding class instances, and --tier=static-only (and library mode) keep the throwing cast. `a?.b.c` on an `any` value now short-circuits only on `a`, so `.c` throws when `a.b` is undefined, as in Node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
118 lines
6.8 KiB
TypeScript
118 lines
6.8 KiB
TypeScript
export const USAGE = `scriptc — TypeScript/JavaScript to native and WebAssembly executables (experimental)
|
|
|
|
Usage:
|
|
scriptc build <file.ts|.js> [options] compile to an executable or source artifact
|
|
scriptc run <file.ts|.js> [options] compile and run
|
|
scriptc coverage <file.ts|.js> how much compiles statically, and why not
|
|
scriptc coverage <file.ts|.js> --external-types <specifier=file.d.ts>
|
|
type-resolve an embedder-provided module for analysis
|
|
scriptc build --lib --profile <p.json> library mode: compile the profile's entry
|
|
module to a linkable static archive
|
|
(<name>.lib.a), or a Wasm reactor
|
|
(<name>.wasm) on wasm32-wasi,
|
|
exporting the profile symbols; a profile
|
|
with a sidecar section also gets the
|
|
contract sidecar JSON beside the archive
|
|
scriptc cache warm [runtime|tls…] verify and load precompiled runtime families
|
|
for the current compiler/SDK/target
|
|
|
|
Options:
|
|
-o, --out <path> primary output path (default: .scriptc/<name><suffix>)
|
|
--emit <kind> primary output: ir, llvm, asm, obj, or exe
|
|
(default: exe). asm/obj use the matching platform helper
|
|
--print <kind> print machine-readable metadata instead of the output path
|
|
(native-link-info implies --emit=obj and never links;
|
|
diagnostics prints the versioned JSON diagnostics
|
|
envelope for build and coverage)
|
|
--fail-on <blockers|divergences>
|
|
coverage only: exit 1 when the entry path has blockers
|
|
(a build would fail), or also when it has Node
|
|
divergences
|
|
--backend <b> code generator (llvm)
|
|
--optimization <release|dev|speed>
|
|
native optimization posture (default: release/-O2). dev
|
|
uses -O0, source breakpoints, and cached LLVM object shards;
|
|
macOS executable builds also produce an adjacent .dSYM.
|
|
speed trades larger executables and longer builds for
|
|
faster programs (runtime inlining, inline reference
|
|
counting, cache-line-aligned runtime code on x86-64)
|
|
--strip remove symbol/debug payload from the linked executable
|
|
for smaller builds (opt in; --emit=exe only)
|
|
--windows-subsystem <console|gui>
|
|
Windows executable subsystem (default: console). gui
|
|
prevents Windows from opening a console window
|
|
--detached-exit
|
|
Linux: after process.exit, free the program's memory in
|
|
a helper process so the parent sees the exit sooner. The
|
|
helper keeps the executable mapped and its memory charged
|
|
for up to ~100 ms after exit (opt in; --emit=exe only)
|
|
--keep-llvm keep generated LLVM IR beside the executable (default)
|
|
--no-keep-llvm delete generated LLVM IR after compiling
|
|
--emit-ir also write IR beside an executable or library archive;
|
|
deprecated for executables: use --emit=ir for primary IR
|
|
--sanitize build with ASan + runtime RC audit
|
|
--ffi <file> bind signature-only TypeScript declarations to native
|
|
C symbols and link the manifest's archives/libraries
|
|
--npm-static <pkg[,pkg…]|auto>
|
|
compile the named npm packages' shipped JS statically as
|
|
program modules (repeatable; "auto" opts in every eligible
|
|
direct import: own .d.ts, unminified JS, no build-transform
|
|
markers; "pkg..." also names every package pkg depends
|
|
on). Packages that fail preflight are refused with a
|
|
diagnostic. Eligible dependencies compile automatically.
|
|
--provenance-sources
|
|
EXPERIMENTAL: compile npm dependencies from their
|
|
provenance-attested SOURCE (fetched at the attested
|
|
commit) as static program modules; packages without a
|
|
usable attestation use their published source
|
|
--external-types <specifier=file.d.ts>
|
|
coverage only: map an exact bare module specifier to a
|
|
local declaration file. The declaration supplies types
|
|
for analysis; the host module remains an explicit
|
|
external-boundary blocker (repeatable)
|
|
--tier <auto|static-only>
|
|
tier policy (default: auto). static-only keeps every
|
|
construct without a static lowering a compile error, so
|
|
the program has no dynamic-tier demotions, and makes a
|
|
checked cast whose value does not fit its type throw
|
|
instead of continuing with the value
|
|
--explain-dynamic[=<name>]
|
|
coverage only: list the functions that operate on dynamic
|
|
values and the bindings, fields, functions, classes and
|
|
modules the dynamic tier would take over, with the
|
|
refusal behind each; a name shows only that unit's chain
|
|
--wasm <file.wasm>
|
|
coverage only: report a WebAssembly module the program
|
|
loads whose path its sources do not spell (repeatable;
|
|
modules the sources name, inline modules and packaged
|
|
.wasm files are found without it)
|
|
-h, --help show this help
|
|
-v, --version print the version
|
|
`;
|
|
|
|
export const CLI_OPTIONS = {
|
|
out: { type: "string", short: "o" },
|
|
emit: { type: "string" },
|
|
print: { type: "string" },
|
|
"fail-on": { type: "string" },
|
|
backend: { type: "string" },
|
|
optimization: { type: "string" },
|
|
strip: { type: "boolean", default: false },
|
|
"windows-subsystem": { type: "string" },
|
|
"detached-exit": { type: "boolean", default: false },
|
|
"keep-llvm": { type: "boolean", default: true },
|
|
"emit-ir": { type: "boolean", default: false },
|
|
sanitize: { type: "boolean", default: false },
|
|
ffi: { type: "string" },
|
|
"npm-static": { type: "string", multiple: true },
|
|
"provenance-sources": { type: "boolean", default: false },
|
|
"external-types": { type: "string", multiple: true },
|
|
tier: { type: "string" },
|
|
"explain-dynamic": { type: "string" },
|
|
wasm: { type: "string", multiple: true },
|
|
lib: { type: "boolean", default: false },
|
|
profile: { type: "string" },
|
|
help: { type: "boolean", short: "h", default: false },
|
|
version: { type: "boolean", short: "v", default: false },
|
|
} as const;
|