Add static one-shot zlib codecs (#355)

This commit is contained in:
Chris Tate
2026-09-20 01:21:41 -05:00
committed by GitHub
parent c33a18d421
commit e82dc998c4
19 changed files with 391 additions and 237 deletions
@@ -2,6 +2,6 @@
"schemaVersion": 3,
"nodeVersion": "24.15.0",
"nodeCommit": "848430679556aed0bd073f2bc263331ad84fa119",
"artifactVersion": "5128d693340c5986a825",
"artifactVersion": "e9ed9709bbb27602d75f",
"rowCount": 3662
}
+33 -33
View File
@@ -1370,9 +1370,9 @@
"apiEntries": 78,
"static": {
"supported": 0,
"partial": 5,
"refused": 10,
"not-implemented": 63,
"partial": 15,
"refused": 4,
"not-implemented": 59,
"by-design": 0,
"unreviewed": 0,
"not-applicable": 0
@@ -99370,9 +99370,9 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"detail": "No static compiler lowering is registered for this API yet.",
"verification": "registry-gap"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -99426,9 +99426,9 @@
"inherited": true
},
"static": {
"status": "refused",
"detail": "Explicitly rejected by a named compiler diagnostic.",
"verification": "explicit-refusal"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -99482,9 +99482,9 @@
"inherited": true
},
"static": {
"status": "refused",
"detail": "Explicitly rejected by a named compiler diagnostic.",
"verification": "explicit-refusal"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -99594,9 +99594,9 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"detail": "No static compiler lowering is registered for this API yet.",
"verification": "registry-gap"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -99650,9 +99650,9 @@
"inherited": true
},
"static": {
"status": "refused",
"detail": "Explicitly rejected by a named compiler diagnostic.",
"verification": "explicit-refusal"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -100098,9 +100098,9 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"detail": "No static compiler lowering is registered for this API yet.",
"verification": "registry-gap"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -100154,9 +100154,9 @@
"inherited": true
},
"static": {
"status": "refused",
"detail": "Explicitly rejected by a named compiler diagnostic.",
"verification": "explicit-refusal"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -100210,9 +100210,9 @@
"inherited": true
},
"static": {
"status": "refused",
"detail": "Explicitly rejected by a named compiler diagnostic.",
"verification": "explicit-refusal"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -100322,9 +100322,9 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"detail": "No static compiler lowering is registered for this API yet.",
"verification": "registry-gap"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -100378,9 +100378,9 @@
"inherited": true
},
"static": {
"status": "refused",
"detail": "Explicitly rejected by a named compiler diagnostic.",
"verification": "explicit-refusal"
"status": "partial",
"detail": "Implemented for the call shapes accepted by the compiler lowering.",
"verification": "test-backed"
},
"dynamic": {
"status": "partial",
@@ -7,9 +7,9 @@
"tierItemCount": 6663,
"tiers": {
"static": {
"replace-refusal": 57,
"verify-gap": 2734,
"audit-partial": 421,
"replace-refusal": 51,
"verify-gap": 2730,
"audit-partial": 431,
"classify": 2,
"implement": 81
},
@@ -108956,12 +108956,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "not-implemented",
"action": "verify-gap",
"verification": "registry-gap",
"confidence": "low",
"source": "compiler-unmatched:zlib",
"tests": []
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:node-builtin.zlib.deflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -109026,12 +109028,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "refused",
"action": "replace-refusal",
"verification": "explicit-refusal",
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:unsupported:node-builtin.zlib.gunzipSync",
"tests": []
"source": "surface-manifest:node-builtin.zlib.gunzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -109096,12 +109100,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "refused",
"action": "replace-refusal",
"verification": "explicit-refusal",
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:unsupported:node-builtin.zlib.gzipSync",
"tests": []
"source": "surface-manifest:node-builtin.zlib.gzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -109238,12 +109244,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "not-implemented",
"action": "verify-gap",
"verification": "registry-gap",
"confidence": "low",
"source": "compiler-unmatched:zlib",
"tests": []
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:node-builtin.zlib.inflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -109308,12 +109316,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "refused",
"action": "replace-refusal",
"verification": "explicit-refusal",
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:unsupported:node-builtin.zlib.unzipSync",
"tests": []
"source": "surface-manifest:node-builtin.zlib.unzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -109852,12 +109862,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "not-implemented",
"action": "verify-gap",
"verification": "registry-gap",
"confidence": "low",
"source": "compiler-unmatched:zlib",
"tests": []
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:node-builtin.zlib.deflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -109922,12 +109934,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "refused",
"action": "replace-refusal",
"verification": "explicit-refusal",
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:unsupported:node-builtin.zlib.gunzipSync",
"tests": []
"source": "surface-manifest:node-builtin.zlib.gunzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -109992,12 +110006,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "refused",
"action": "replace-refusal",
"verification": "explicit-refusal",
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:unsupported:node-builtin.zlib.gzipSync",
"tests": []
"source": "surface-manifest:node-builtin.zlib.gzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -110134,12 +110150,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "not-implemented",
"action": "verify-gap",
"verification": "registry-gap",
"confidence": "low",
"source": "compiler-unmatched:zlib",
"tests": []
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:node-builtin.zlib.inflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -110204,12 +110222,14 @@
"priority": "high",
"tiers": {
"static": {
"status": "refused",
"action": "replace-refusal",
"verification": "explicit-refusal",
"status": "partial",
"action": "audit-partial",
"verification": "test-backed",
"confidence": "high",
"source": "surface-manifest:unsupported:node-builtin.zlib.unzipSync",
"tests": []
"source": "surface-manifest:node-builtin.zlib.unzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -1491,9 +1491,9 @@
"apiEntries": 78,
"static": {
"supported": 0,
"partial": 5,
"refused": 10,
"not-implemented": 63,
"partial": 15,
"refused": 4,
"not-implemented": 59,
"by-design": 0,
"unreviewed": 0,
"not-applicable": 0
@@ -126329,8 +126329,11 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"evidence": "compiler-unmatched:zlib"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.deflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -126389,8 +126392,11 @@
"inherited": true
},
"static": {
"status": "refused",
"evidence": "surface-manifest:unsupported:node-builtin.zlib.gunzipSync"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.gunzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -126449,8 +126455,11 @@
"inherited": true
},
"static": {
"status": "refused",
"evidence": "surface-manifest:unsupported:node-builtin.zlib.gzipSync"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.gzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -126572,8 +126581,11 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"evidence": "compiler-unmatched:zlib"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.inflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -126632,8 +126644,11 @@
"inherited": true
},
"static": {
"status": "refused",
"evidence": "surface-manifest:unsupported:node-builtin.zlib.unzipSync"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.unzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -127547,8 +127562,11 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"evidence": "compiler-unmatched:zlib"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.deflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -127607,8 +127625,11 @@
"inherited": true
},
"static": {
"status": "refused",
"evidence": "surface-manifest:unsupported:node-builtin.zlib.gunzipSync"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.gunzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -127667,8 +127688,11 @@
"inherited": true
},
"static": {
"status": "refused",
"evidence": "surface-manifest:unsupported:node-builtin.zlib.gzipSync"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.gzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -127790,8 +127814,11 @@
"inherited": true
},
"static": {
"status": "not-implemented",
"evidence": "compiler-unmatched:zlib"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.inflateRawSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
@@ -127850,8 +127877,11 @@
"inherited": true
},
"static": {
"status": "refused",
"evidence": "surface-manifest:unsupported:node-builtin.zlib.unzipSync"
"status": "partial",
"evidence": "surface-manifest:node-builtin.zlib.unzipSync",
"tests": [
"tests/corpus/1404-zlib-crypto-bytes.ts"
]
},
"dynamic": {
"status": "partial",
+10 -3
View File
@@ -2037,14 +2037,21 @@ declare module "node:readline" {
export * from "readline";
}
/* node:zlib — deflateSync/inflateSync lower (Buffer in, Buffer out,
* Node's default options; libz links only into zlib-using binaries);
* gzip and friends typecheck and fence at their use sites. */
/* node:zlib — the one-shot zlib/raw/gzip codecs lower (Buffer in, Buffer
* out, Node's default options; libz links only into zlib-using binaries).
* The one-shot Brotli pair stays declared so reached calls receive the
* compiler's named SC2020 refusal; streaming, callback, Zstd, and explicit-
* options forms remain outside the fallback surface. */
declare module "zlib" {
export function deflateSync(data: string | Uint8Array): Buffer;
export function inflateSync(data: Uint8Array): Buffer;
export function deflateRawSync(data: string | Uint8Array): Buffer;
export function inflateRawSync(data: Uint8Array): Buffer;
export function gzipSync(data: string | Uint8Array): Buffer;
export function gunzipSync(data: Uint8Array): Buffer;
export function unzipSync(data: Uint8Array): Buffer;
export function brotliCompressSync(data: string | Uint8Array): Buffer;
export function brotliDecompressSync(data: Uint8Array): Buffer;
}
declare module "node:zlib" {
export * from "zlib";
+10
View File
@@ -4596,6 +4596,16 @@ function emitFilesystemLibCall(state: LibCallState): Temp {
return finish(`scr_zlib_deflate(${arg(0)})`);
case "zlib.inflateSync":
return finish(`scr_zlib_inflate(${arg(0)})`);
case "zlib.deflateRawSync":
return finish(`scr_zlib_deflate_mode(${arg(0)}, 1.0, -1.0)`);
case "zlib.inflateRawSync":
return finish(`scr_zlib_inflate_mode(${arg(0)}, 1.0)`);
case "zlib.gzipSync":
return finish(`scr_zlib_deflate_mode(${arg(0)}, 2.0, -1.0)`);
case "zlib.gunzipSync":
return finish(`scr_zlib_inflate_mode(${arg(0)}, 2.0)`);
case "zlib.unzipSync":
return finish(`scr_zlib_inflate_mode(${arg(0)}, 3.0)`);
case "fsp.readFile":
return finish(`scr_fsp_read_file(${arg(0)})`);
case "fsp.writeFile":
@@ -132,6 +132,33 @@ export function emitFilesystemLibCall(host: LlvmEmitterContext, e: LibCallExpr):
if (alwaysThrowSym !== undefined) {
return emitAlwaysThrowLibCall(host, e, alwaysThrowSym);
}
if (
e.fn === "zlib.deflateRawSync" || e.fn === "zlib.inflateRawSync" ||
e.fn === "zlib.gzipSync" || e.fn === "zlib.gunzipSync" ||
e.fn === "zlib.unzipSync"
) {
const input = host.emitExpr(e.args[0]!);
const compressing = e.fn === "zlib.deflateRawSync" || e.fn === "zlib.gzipSync";
const mode = e.fn === "zlib.deflateRawSync" || e.fn === "zlib.inflateRawSync"
? 1
: e.fn === "zlib.unzipSync"
? 3
: 2;
const sym = compressing ? "scr_zlib_deflate_mode" : "scr_zlib_inflate_mode";
host.declare(
compressing
? `declare ptr @${sym}(ptr, double, double)`
: `declare ptr @${sym}(ptr, double)`,
);
const raw = B.tmp();
const args = compressing
? `ptr ${input.name}, double ${f64Lit(mode)}, double ${f64Lit(-1)}`
: `ptr ${input.name}, double ${f64Lit(mode)}`;
B.line(`${raw} = call ptr @${sym}(${args})`);
const out = host.own({ name: raw, type: e.type });
if (!compressing) host.emitPendingCheck();
return out;
}
if (e.fn === "fs.renameCb") {
// The callback MOVES into the next-turn operation. Its emitted
// adapter materializes the callback's Error | null union (or the
@@ -756,11 +756,18 @@ export const BUILTIN_MODULE_FNS: Record<string, Record<string, BuiltinModuleFn |
pbkdf2: { fn: "crypto.pbkdf2Cb", params: [], result: VOID },
},
zlib: {
// Buffer in, Buffer out, Node's default options; string inputs fence
// per site (see the zlib special case in lowerBuiltinModuleCall).
// native-toolchain.ts links libz only when these appear on the IR.
// Buffer in, Buffer out, Node's default options; string inputs and
// explicit options fence per site (see the zlib special case in
// lowerBuiltinModuleCall). native-toolchain.ts links libz only when
// these appear on the IR. The format-specific rows lower to the
// existing mode runtime (raw=1, gzip=2, auto-detect=3).
deflateSync: { fn: "zlib.deflateSync", params: [BYTES_U8], result: BYTES_U8 },
inflateSync: { fn: "zlib.inflateSync", params: [BYTES_U8], result: BYTES_U8 },
deflateRawSync: { fn: "zlib.deflateRawSync", params: [BYTES_U8], result: BYTES_U8 },
inflateRawSync: { fn: "zlib.inflateRawSync", params: [BYTES_U8], result: BYTES_U8 },
gzipSync: { fn: "zlib.gzipSync", params: [BYTES_U8], result: BYTES_U8 },
gunzipSync: { fn: "zlib.gunzipSync", params: [BYTES_U8], result: BYTES_U8 },
unzipSync: { fn: "zlib.unzipSync", params: [BYTES_U8], result: BYTES_U8 },
},
url: {
// fileURLToPath accepts a URL value OR a string — the call lowering
@@ -1282,10 +1289,10 @@ export function builtinModulesArrayLit(loc: { file: string; start: number; end:
}
/** Member-specific hints for RECOGNIZED builtin modules whose member has
* no lowering. deflateSync/inflateSync lower now (Buffers are real);
* the rest of the zlib surface points at the lowered pair. */
* no lowering. The one-shot zlib/deflate-raw/gzip codecs lower now
* (Buffers are real); the remaining zlib surface points at that family. */
const ZLIB_HINT =
"deflateSync and inflateSync are the lowered zlib surface";
"deflateSync, inflateSync, deflateRawSync, inflateRawSync, gzipSync, gunzipSync, and unzipSync are the lowered zlib surface";
/** The loose-equality quartet's shared hint: == coercion has no lowering
* anywhere in this compiler, and Node itself points at the strict forms. */
@@ -1392,9 +1399,6 @@ export const BUILTIN_MODULE_FENCE_HINTS: Record<string, Record<string, string |
"randomBytes, and the createHash chain",
},
zlib: {
gzipSync: ZLIB_HINT,
gunzipSync: ZLIB_HINT,
unzipSync: ZLIB_HINT,
brotliCompressSync: ZLIB_HINT,
brotliDecompressSync: ZLIB_HINT,
},
+12 -4
View File
@@ -3237,12 +3237,17 @@ export type IrLibFn =
| "fs.writeFileSyncBytes"
| "fsp.readFileBytes"
/** node:zlib (scr_zlib.c — native-toolchain.ts compiles/links it ONLY when these
* appear on the IR, the regex/libcurl gating precedent): deflateSync/
* inflateSync over u8 bytes with Node's default options. deflate never
* throws (OOM aborts); inflate of corrupt input THROWS Node's error
* catchably. */
* appear on the IR, the regex/libcurl gating precedent): one-shot zlib,
* raw-DEFLATE, gzip, and auto-detect codecs over u8 bytes with Node's
* default options. Compression never throws (OOM aborts); decompression
* of corrupt input THROWS Node's error catchably. */
| "zlib.deflateSync"
| "zlib.inflateSync"
| "zlib.deflateRawSync"
| "zlib.inflateRawSync"
| "zlib.gzipSync"
| "zlib.gunzipSync"
| "zlib.unzipSync"
/** The Buffer overloads of the raw stream writes — same promptly
* submitted streams as process.stdoutWrite/stderrWrite, constantly true.
* The encoding arg is evaluated but ignored for bytes, like Node. The Cb
@@ -7518,6 +7523,9 @@ export const MAY_THROW_LIB_FNS: ReadonlySet<IrLibFn> = new Set([
"fs.readFileSyncBytes",
"fs.writeFileSyncBytes",
"zlib.inflateSync",
"zlib.inflateRawSync",
"zlib.gunzipSync",
"zlib.unzipSync",
"date.toISOString",
"date.toISOStringValue",
"fs.mkdirRecursiveSync",
+5
View File
@@ -838,6 +838,11 @@ export const LIB_FN_SIGS: Record<IrLibFn, { argTypes: (IrType | null)[]; result:
"fsp.readFileBytes": { argTypes: [STRING], result: { kind: "promise", inner: BYTES_U8 } },
"zlib.deflateSync": { argTypes: [BYTES_U8], result: BYTES_U8 },
"zlib.inflateSync": { argTypes: [BYTES_U8], result: BYTES_U8 },
"zlib.deflateRawSync": { argTypes: [BYTES_U8], result: BYTES_U8 },
"zlib.inflateRawSync": { argTypes: [BYTES_U8], result: BYTES_U8 },
"zlib.gzipSync": { argTypes: [BYTES_U8], result: BYTES_U8 },
"zlib.gunzipSync": { argTypes: [BYTES_U8], result: BYTES_U8 },
"zlib.unzipSync": { argTypes: [BYTES_U8], result: BYTES_U8 },
"process.stdoutWriteBytes": { argTypes: [BYTES_U8, STRING], result: BOOL },
"process.stderrWriteBytes": { argTypes: [BYTES_U8, STRING], result: BOOL },
// Completion callback is program-dependent: zero params, checked-dynamic,
+17 -11
View File
@@ -1865,7 +1865,7 @@
"name": "zlib.brotliCompressSync",
"status": "unsupported",
"code": "SC2020",
"note": "deflateSync and inflateSync are the lowered zlib surface"
"note": "deflateSync, inflateSync, deflateRawSync, inflateRawSync, gzipSync, gunzipSync, and unzipSync are the lowered zlib surface"
},
{
"id": "node-builtin.zlib.brotliDecompressSync",
@@ -1873,7 +1873,13 @@
"name": "zlib.brotliDecompressSync",
"status": "unsupported",
"code": "SC2020",
"note": "deflateSync and inflateSync are the lowered zlib surface"
"note": "deflateSync, inflateSync, deflateRawSync, inflateRawSync, gzipSync, gunzipSync, and unzipSync are the lowered zlib surface"
},
{
"id": "node-builtin.zlib.deflateRawSync",
"kind": "node-builtin",
"name": "zlib.deflateRawSync",
"status": "static"
},
{
"id": "node-builtin.zlib.deflateSync",
@@ -1885,17 +1891,19 @@
"id": "node-builtin.zlib.gunzipSync",
"kind": "node-builtin",
"name": "zlib.gunzipSync",
"status": "unsupported",
"code": "SC2020",
"note": "deflateSync and inflateSync are the lowered zlib surface"
"status": "static"
},
{
"id": "node-builtin.zlib.gzipSync",
"kind": "node-builtin",
"name": "zlib.gzipSync",
"status": "unsupported",
"code": "SC2020",
"note": "deflateSync and inflateSync are the lowered zlib surface"
"status": "static"
},
{
"id": "node-builtin.zlib.inflateRawSync",
"kind": "node-builtin",
"name": "zlib.inflateRawSync",
"status": "static"
},
{
"id": "node-builtin.zlib.inflateSync",
@@ -1907,9 +1915,7 @@
"id": "node-builtin.zlib.unzipSync",
"kind": "node-builtin",
"name": "zlib.unzipSync",
"status": "unsupported",
"code": "SC2020",
"note": "deflateSync and inflateSync are the lowered zlib surface"
"status": "static"
},
{
"id": "stdlib.abort-controller.abort",
+3 -3
View File
@@ -5438,9 +5438,9 @@ void scr_fs_throw(int e, const char *op, const ScrStr *path);
* ("incorrect header check", ...). Borrow their input; results +1. */
ScrBytes *scr_zlib_deflate(const ScrBytes *data);
ScrBytes *scr_zlib_inflate(const ScrBytes *data);
/* The island's mode variants (0 zlib / 1 raw / 2 gzip; inflate adds
* 3 = auto-detect) — scr_zlib_island.c bridges them into the embedded
* engine's node:zlib shim. */
/* The format-mode variants (0 zlib / 1 raw / 2 gzip; inflate adds
* 3 = auto-detect). Static one-shot codecs call these directly, and
* scr_zlib_island.c bridges them into the embedded engine's node:zlib shim. */
ScrBytes *scr_zlib_deflate_mode(const ScrBytes *data, double mode, double level);
ScrBytes *scr_zlib_inflate_mode(const ScrBytes *data, double mode);
void scr_zlib_island_install(void);
+9 -8
View File
@@ -1,9 +1,9 @@
/* node:zlib, the lowered slice: deflateSync/inflateSync over u8 bytes with
* Node's DEFAULT options (zlib format, Z_DEFAULT_COMPRESSION, windowBits
* 15). Compiled ONLY when the program uses zlib (native-toolchain.ts gates it exactly
* like scr_regex.c/libregexp), so zlib-free binaries keep their
* historical link line. Host builds link the system -lz; cross targets
* link the vendored zlib built per target (ensureZlibObjects in native-toolchain.ts).
/* node:zlib, the lowered slice: the one-shot zlib/raw-DEFLATE/gzip codecs
* over u8 bytes with Node's DEFAULT options. Compiled ONLY when the program
* uses zlib (native-toolchain.ts gates it exactly like scr_regex.c/libregexp),
* so zlib-free binaries keep their historical link line. Host builds link
* the system -lz; cross targets link the vendored zlib built per target
* (ensureZlibObjects in native-toolchain.ts).
*
* Compressed OUTPUT bytes are zlib-version-dependent — the differential
* corpus tests round-trips and fixed-blob inflation, never raw deflate
@@ -83,8 +83,9 @@ ScrBytes *scr_zlib_inflate(const ScrBytes *data) {
return out;
}
/* ── the island's mode variants (scr_zlib_island.c bridges these into
* the embedded engine's node:zlib shim) ───────────────────────────────
/* ── format-mode variants (static raw/gzip/unzip calls use these directly;
* scr_zlib_island.c also bridges them into the embedded engine's node:zlib
* shim) ───────────────────────────────────────────────────────────────
* mode: 0 zlib (windowBits 15), 1 raw (-15), 2 gzip (15+16); inflate
* additionally takes 3 = auto-detect zlib/gzip (15+32, Node's unzip). */
+40 -5
View File
@@ -1,9 +1,18 @@
// zlib deflateSync/inflateSync round trips (compressed BYTES are
// zlib-version-dependent, so only round-trip results and a fixed-blob
// inflation print — never raw deflate output), plus crypto.randomBytes as
// a real Buffer with the composed .toString path unchanged beside it.
// The one-shot zlib/raw-DEFLATE/gzip codecs with default options.
// Compressed BYTES are zlib-version-dependent, so only round-trip results,
// format markers, and fixed-blob inflation print — never compressed output.
// crypto.randomBytes remains beside them as a real Buffer with the composed
// .toString path unchanged.
import { randomBytes } from "node:crypto";
import { deflateSync, inflateSync } from "node:zlib";
import {
deflateRawSync,
deflateSync,
gunzipSync,
gzipSync,
inflateRawSync,
inflateSync,
unzipSync,
} from "node:zlib";
const raw = Buffer.from("hello hello hello hello compression works", "utf8");
const packed = deflateSync(raw);
@@ -12,10 +21,28 @@ console.log("header", packed[0]);
console.log("rt", inflateSync(packed).toString() === raw.toString());
console.log("rthex", inflateSync(packed).toString("hex") === raw.toString("hex"));
const rawPacked = deflateRawSync(raw);
console.log("raw", rawPacked.length > 0, inflateRawSync(rawPacked).equals(raw));
const gzipPacked = gzipSync(raw);
console.log("gzip-header", gzipPacked.subarray(0, 2).toString("hex"));
console.log("gzip", gunzipSync(gzipPacked).equals(raw));
console.log("unzip", unzipSync(packed).equals(raw), unzipSync(gzipPacked).equals(raw));
// A fixed blob deflated by zlib once (any zlib inflates it identically).
const fixed = Buffer.from("789c2b29ce4b2cc92c4b05000fa2036f", "hex");
console.log("fixed", inflateSync(fixed).toString());
// Fixed gzip/raw-DEFLATE blobs for decoder evidence independent of each
// encoder in this binary.
const fixedGzip = Buffer.from(
"1f8b08000000000000132b2e492cc94c5648ce4f494d5648cbac28292d4a05007d4d0da114000000",
"hex",
);
const fixedRaw = Buffer.from("2b2e492cc94c5648ce4f494d5648cbac28292d4a0500", "hex");
console.log("fixed-gzip", gunzipSync(fixedGzip).toString());
console.log("fixed-raw", inflateRawSync(fixedRaw).toString());
const empty = deflateSync(new Uint8Array(0));
console.log("empty", inflateSync(empty).length);
@@ -35,6 +62,14 @@ try {
console.log("truncated", e.message);
}
}
try {
gunzipSync(gzipPacked.subarray(0, gzipPacked.length - 4));
console.log("no-throw");
} catch (e) {
if (e instanceof Error) {
console.log("gzip-truncated", e.message);
}
}
const r = randomBytes(16);
console.log("rand", r.length, r.byteLength);
+5 -3
View File
@@ -28,8 +28,10 @@ accessSync("/bin/sh", constants.X_OK);
const tmp = mkdtempSync("/tmp/scr-");
const raw = readFileSync("/etc/hosts").toString(tty ? "hex" : "latin1"); // runtime BufferEncoding selection lowers too
const intervalWithSignal = promiseInterval(1, "tick", {}); // AbortSignal options stay fenced
// The computed encoding is now part of the static Buffer surface.
import { deflateSync, gzipSync } from "node:zlib";
// The computed encoding is now part of the static Buffer surface. The
// one-shot zlib/raw/gzip codecs lower; string data keeps the wrap-it-first
// hint, while Brotli remains an explicit member fence.
import { brotliCompressSync, deflateSync } from "node:zlib";
const packed = deflateSync("data"); // string data: the wrap-it-first hint
const zipped = gzipSync("data"); // beyond the lowered pair: fenced
const brotli = brotliCompressSync(Buffer.from("data")); // outside the lowered family: fenced
// The remaining imports continue the declared-but-not-lowered surface.
+5 -6
View File
@@ -46,13 +46,12 @@ console.log(win32.sep);
const u = new URL("https://example.com/x?a=1");
console.log(u.hash);
u.searchParams.get("a");
/* The zlib surface beyond the lowered deflateSync/inflateSync pair
* fences with the pair named; the lowered pair itself takes Buffers, so a
* string argument (which @types/node admits) gets the wrap-it-first
* hint. */
import { deflateSync, gzipSync } from "zlib";
/* The one-shot zlib/raw/gzip codecs lower; string input still gets the
* wrap-it-first hint, while Brotli remains a member-qualified fence with
* the lowered family named. */
import { brotliCompressSync, deflateSync } from "zlib";
deflateSync("data");
gzipSync("data");
brotliCompressSync(Buffer.from("data"));
/* The http2 compatibility slice's @types/node-world fences (divergence
* 56): the SNICallback option fences by name with the serve-one-pair
* hint, and its conditional-spread portless spelling fences at the
@@ -21,24 +21,24 @@ node-fallback-fence.ts:30:28 - error SC2020: 'timers/promises.setInterval with 3
29 | const raw = readFileSync("/etc/hosts").toString(tty ? "hex" : "latin1"); // runtime BufferEncoding selection lowers too
30 | const intervalWithSignal = promiseInterval(1, "tick", {}); // AbortSignal options stay fenced
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31 | // The computed encoding is now part of the static Buffer surface.
31 | // The computed encoding is now part of the static Buffer surface. The
hint: the lowered form is setInterval(delay, value) with an explicit yielded value; AbortSignal options are not supported yet
node-fallback-fence.ts:33:28 - error SC2020: 'deflateSync of 'string' data' is part of the standard library types but has no scriptc lowering yet
node-fallback-fence.ts:35:28 - error SC2020: 'deflateSync of 'string' data' is part of the standard library types but has no scriptc lowering yet
32 | import { deflateSync, gzipSync } from "node:zlib";
33 | const packed = deflateSync("data"); // string data: the wrap-it-first hint
34 | import { brotliCompressSync, deflateSync } from "node:zlib";
35 | const packed = deflateSync("data"); // string data: the wrap-it-first hint
| ^~~~~~
34 | const zipped = gzipSync("data"); // beyond the lowered pair: fenced
36 | const brotli = brotliCompressSync(Buffer.from("data")); // outside the lowered family: fenced
hint: zlib works on Buffers: deflateSync(Buffer.from(s, "utf8"))
node-fallback-fence.ts:34:16 - error SC2020: 'zlib.gzipSync' is part of the standard library types but has no scriptc lowering yet
node-fallback-fence.ts:36:16 - error SC2020: 'zlib.brotliCompressSync' is part of the standard library types but has no scriptc lowering yet
33 | const packed = deflateSync("data"); // string data: the wrap-it-first hint
34 | const zipped = gzipSync("data"); // beyond the lowered pair: fenced
| ^~~~~~~~~~~~~~~~
35 | // The remaining imports continue the declared-but-not-lowered surface.
35 | const packed = deflateSync("data"); // string data: the wrap-it-first hint
36 | const brotli = brotliCompressSync(Buffer.from("data")); // outside the lowered family: fenced
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 | // The remaining imports continue the declared-but-not-lowered surface.
hint: deflateSync and inflateSync are the lowered zlib surface
hint: deflateSync, inflateSync, deflateRawSync, inflateRawSync, gzipSync, gunzipSync, and unzipSync are the lowered zlib surface
@@ -88,128 +88,128 @@ fenced.ts:47:13 - error SC2020: 'URL.hash' is typed by @types/node but has no sc
hint: protocol, pathname, href, host, hostname, search, searchParams, and toString() are the supported URL members
fenced.ts:54:13 - error SC2020: 'deflateSync of 'string' data' is part of the standard library types but has no scriptc lowering yet
fenced.ts:53:13 - error SC2020: 'deflateSync of 'string' data' is part of the standard library types but has no scriptc lowering yet
53 | import { deflateSync, gzipSync } from "zlib";
54 | deflateSync("data");
52 | import { brotliCompressSync, deflateSync } from "zlib";
53 | deflateSync("data");
| ^~~~~~
55 | gzipSync("data");
54 | brotliCompressSync(Buffer.from("data"));
hint: zlib works on Buffers: deflateSync(Buffer.from(s, "utf8"))
fenced.ts:55:1 - error SC2020: 'zlib.gzipSync' is typed by @types/node but has no scriptc lowering yet
fenced.ts:54:1 - error SC2020: 'zlib.brotliCompressSync' is typed by @types/node but has no scriptc lowering yet
54 | deflateSync("data");
55 | gzipSync("data");
| ^~~~~~~~~~~~~~~~
56 | /* The http2 compatibility slice's @types/node-world fences (divergence
53 | deflateSync("data");
54 | brotliCompressSync(Buffer.from("data"));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 | /* The http2 compatibility slice's @types/node-world fences (divergence
hint: deflateSync and inflateSync are the lowered zlib surface
hint: deflateSync, inflateSync, deflateRawSync, inflateRawSync, gzipSync, gunzipSync, and unzipSync are the lowered zlib surface
fenced.ts:64:71 - error SC2020: 'a createSecureServer SNICallback of 'undefined' values' is part of the standard library types but has no scriptc lowering yet
fenced.ts:63:71 - error SC2020: 'a createSecureServer SNICallback of 'undefined' values' is part of the standard library types but has no scriptc lowering yet
63 | import * as http2 from "node:http2";
64 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", SNICallback: undefined });
62 | import * as http2 from "node:http2";
63 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", SNICallback: undefined });
| ^~~~~~~~~~~~~~~~~~~~~~
65 | http2.createSecureServer({
64 | http2.createSecureServer({
hint: SNICallback lowers as a direct option or the conditional spread ...(x ? { SNICallback: x } : {}) — the callback is (servername, cb) => void with cb: (err: Error | null, ctx?: tls.SecureContext) => void
fenced.ts:69:3 - error SC2020: 'createSecureServer options with a conditional spread' is part of the standard library types but has no scriptc lowering yet
fenced.ts:68:3 - error SC2020: 'createSecureServer options with a conditional spread' is part of the standard library types but has no scriptc lowering yet
68 | key: "pem",
69 | ...(1 ? { SNICallback: undefined } : {}),
67 | key: "pem",
68 | ...(1 ? { SNICallback: undefined } : {}),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70 | });
69 | });
hint: the lowered conditional spread is exactly ...(x ? { SNICallback: x } : {}) — the included value must BE the condition
fenced.ts:71:71 - error SC2020: 'createSecureServer option 'streamResetBurst' with a non-literal value' is part of the standard library types but has no scriptc lowering yet
fenced.ts:70:71 - error SC2020: 'createSecureServer option 'streamResetBurst' with a non-literal value' is part of the standard library types but has no scriptc lowering yet
70 | });
71 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", streamResetBurst: 1 + 0 });
69 | });
70 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", streamResetBurst: 1 + 0 });
| ^~~~~~~~~~~~~~~~~~~~~~~
72 | http2.connect("https://localhost");
71 | http2.connect("https://localhost");
hint: h2 session-tuning options are accepted with literal values but are not applied yet
fenced.ts:78:1 - error SC2020: 'crypto.generateKeyPair' is typed by @types/node but has no scriptc lowering yet
fenced.ts:77:1 - error SC2020: 'crypto.generateKeyPair' is typed by @types/node but has no scriptc lowering yet
77 | import { createCipheriv, generateKeyPair, pbkdf2Sync, setFips } from "node:crypto";
78 | generateKeyPair("rsa", { modulusLength: 2048 }, () => {});
76 | import { createCipheriv, generateKeyPair, pbkdf2Sync, setFips } from "node:crypto";
77 | generateKeyPair("rsa", { modulusLength: 2048 }, () => {});
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79 | createCipheriv("aes-128-cbc", Buffer.alloc(16), Buffer.alloc(16));
78 | createCipheriv("aes-128-cbc", Buffer.alloc(16), Buffer.alloc(16));
hint: asymmetric-key operations need a public-key stack (bignum, RSA/EC/EdDSA math) and a KeyObject value model — neither exists in the static runtime, so no faithful lowering can be small; the lowered crypto surface is hashing, randomness, and the introspection statics
fenced.ts:79:1 - error SC2020: 'crypto.createCipheriv' is typed by @types/node but has no scriptc lowering yet
fenced.ts:78:1 - error SC2020: 'crypto.createCipheriv' is typed by @types/node but has no scriptc lowering yet
78 | generateKeyPair("rsa", { modulusLength: 2048 }, () => {});
79 | createCipheriv("aes-128-cbc", Buffer.alloc(16), Buffer.alloc(16));
77 | generateKeyPair("rsa", { modulusLength: 2048 }, () => {});
78 | createCipheriv("aes-128-cbc", Buffer.alloc(16), Buffer.alloc(16));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
80 | pbkdf2Sync("pw", "salt", 100000, 64, "sha512");
79 | pbkdf2Sync("pw", "salt", 100000, 64, "sha512");
hint: symmetric ciphers need a cipher stack the static runtime does not vendor — the lowered crypto surface is hashing, randomness, and the introspection statics
fenced.ts:80:38 - error SC2020: 'crypto.pbkdf2Sync with algorithm 'sha512'' is part of the standard library types but has no scriptc lowering yet
fenced.ts:79:38 - error SC2020: 'crypto.pbkdf2Sync with algorithm 'sha512'' is part of the standard library types but has no scriptc lowering yet
79 | createCipheriv("aes-128-cbc", Buffer.alloc(16), Buffer.alloc(16));
80 | pbkdf2Sync("pw", "salt", 100000, 64, "sha512");
78 | createCipheriv("aes-128-cbc", Buffer.alloc(16), Buffer.alloc(16));
79 | pbkdf2Sync("pw", "salt", 100000, 64, "sha512");
| ^~~~~~~~
81 | setFips(false);
80 | setFips(false);
hint: md5, sha1, and sha256 are the lowered digest algorithms
fenced.ts:81:1 - error SC2020: 'crypto.setFips' is typed by @types/node but has no scriptc lowering yet
fenced.ts:80:1 - error SC2020: 'crypto.setFips' is typed by @types/node but has no scriptc lowering yet
80 | pbkdf2Sync("pw", "salt", 100000, 64, "sha512");
81 | setFips(false);
79 | pbkdf2Sync("pw", "salt", 100000, 64, "sha512");
80 | setFips(false);
| ^~~~~~~~~~~~~~
82 | fetch("https://example.invalid/", {
81 | fetch("https://example.invalid/", {
hint: a compiled binary has no FIPS provider to enable, and Node itself throws on setFips(true) in a non-FIPS build — getFips() answers 0 here
fenced.ts:83:3 - error SC2020: 'RequestInit option 'integrity' in a static build' is typed by @types/node but has no scriptc lowering yet
fenced.ts:82:3 - error SC2020: 'RequestInit option 'integrity' in a static build' is typed by @types/node but has no scriptc lowering yet
82 | fetch("https://example.invalid/", {
83 | integrity: "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
81 | fetch("https://example.invalid/", {
82 | integrity: "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84 | });
83 | });
hint: neither compiler tier preserves this RequestInit member's conversion or transport behavior
fenced.ts:87:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
fenced.ts:86:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
86 | const body = (await fetch(url)).body!;
87 | body.tee();
85 | const body = (await fetch(url)).body!;
86 | body.tee();
| ^~~~~~~~
88 | const tee = body.tee;
87 | const tee = body.tee;
hint: the dynamic Web Streams bridge exposes only an explicit unsupported stub for this operation
fenced.ts:88:15 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
fenced.ts:87:15 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
87 | body.tee();
88 | const tee = body.tee;
86 | body.tee();
87 | const tee = body.tee;
| ^~~~~~~~
89 | body["tee"]();
88 | body["tee"]();
hint: the dynamic Web Streams bridge exposes only an explicit unsupported stub for this operation
fenced.ts:89:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
fenced.ts:88:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
88 | const tee = body.tee;
89 | body["tee"]();
87 | const tee = body.tee;
88 | body["tee"]();
| ^~~~~~~~~~~
90 | const bracketTee = body["tee"];
89 | const bracketTee = body["tee"];
hint: the dynamic Web Streams bridge exposes only an explicit unsupported stub for this operation
fenced.ts:90:22 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
fenced.ts:89:22 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet
89 | body["tee"]();
90 | const bracketTee = body["tee"];
88 | body["tee"]();
89 | const bracketTee = body["tee"];
| ^~~~~~~~~~~
91 | }
90 | }
hint: the dynamic Web Streams bridge exposes only an explicit unsupported stub for this operation
+2 -2
View File
@@ -217,8 +217,8 @@ const PROBES: Probe[] = [
{ id: "diagnostic.sc1031", source: "class C {\n f = 1;\n m(): number {\n return this.f;\n }\n}\nconst { m } = new C();\nconsole.log(m());\n" },
{ id: "diagnostic.sc1121", source: 'console.log(/ab/g.test("abab"));\n' },
{
id: "node-builtin.zlib.gzipSync",
source: 'import { gzipSync } from "node:zlib";\ngzipSync("data");\nconsole.log(0);\n',
id: "node-builtin.zlib.brotliCompressSync",
source: 'import { brotliCompressSync } from "node:zlib";\nbrotliCompressSync(Buffer.from("data"));\nconsole.log(0);\n',
},
];