diff --git a/Cargo.lock b/Cargo.lock index 3e6e81b..d386f72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2005,7 +2005,7 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "slice-cas" -version = "0.10.11" +version = "0.10.12" dependencies = [ "aho-corasick", "anyhow", @@ -2026,7 +2026,7 @@ dependencies = [ [[package]] name = "slice-cli" -version = "0.10.11" +version = "0.10.12" dependencies = [ "anyhow", "criterion", @@ -2047,7 +2047,7 @@ dependencies = [ [[package]] name = "slice-engine" -version = "0.10.11" +version = "0.10.12" dependencies = [ "aho-corasick", "anyhow", @@ -2077,7 +2077,7 @@ dependencies = [ [[package]] name = "slice-io" -version = "0.10.11" +version = "0.10.12" dependencies = [ "anyhow", "criterion", @@ -2088,7 +2088,7 @@ dependencies = [ [[package]] name = "slice-sandbox" -version = "0.10.11" +version = "0.10.12" dependencies = [ "anyhow", "blake3", diff --git a/Cargo.toml b/Cargo.toml index 2c1af98..c734c93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = [ ] [workspace.package] -version = "0.10.11" +version = "0.10.12" edition = "2021" authors = ["Slice Runtime Team"] license = "MIT OR Apache-2.0" diff --git a/README.md b/README.md index f16fa35..b73aec6 100644 --- a/README.md +++ b/README.md @@ -12,45 +12,45 @@ ## Verified Benchmark Overview (Linux `x86_64` Docker & Windows `x86_64`) -> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./tests/reports/latest.md)** (Archive: [`bench_v0.10.11_20261111_055407Z_898e90b.md`](./tests/reports/bench_v0.10.11_20261111_055407Z_898e90b.md)) -> **Provenance:** Slice `v0.10.11` (`898e90b`) · Generated `2026-11-11T05:54:07Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` -> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **28/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. +> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./tests/reports/latest.md)** (Archive: [`bench_v0.10.12_20261111_175836Z_dc31f74.md`](./tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md)) +> **Provenance:** Slice `v0.10.12` (`dc31f74`) · Generated `2026-11-11T17:58:36Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **29/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. #### 1. Core Architecture, HTTP Throughput & 1,000-Tenant MicroVM Density -| Metric | Slice (`v0.10.11` `SLICEBC\x01`) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Advantage | +| Metric | Slice (`v0.10.12` `SLICEBC\x01`) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Advantage | | :--- | :---: | :---: | :---: | :---: | :--- | -| **In-Process Isolate Cold Start (`P50` / `P99`)** | **`1.23 us` / `2.03 us`** | N/A (Process/VM) | N/A (Process/VM) | N/A (Process/VM) | **~120,000x faster than 125ms Firecracker VM** | -| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.47 ms` (`9.70 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | +| **In-Process Isolate Cold Start (`P50` / `P99`)** | **`1.02 us` / `4.27 us`** | N/A (Process/VM) | N/A (Process/VM) | N/A (Process/VM) | **~120,000x faster than 125ms Firecracker VM** | +| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.74 ms` (`9.82 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | | **500-Module Monorepo Cold Boot (`stat()` Calls)** | **`3.41 ms` (`0 stat()`)** | `12.72 ms` (`500+ stat`) | `41.80 ms` (`500+ stat`) | `70.38 ms` (`1,500+ stat`) | **`3.7x` faster than Bun / `20.6x` Node.js** | -| **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`153,174 req/s`** (Tier-0)
**`145,192 req/s`** (Tier-1) | `101,093 req/s` | `99,307 req/s` | `54,637 req/s` | **`1.52x` (`Tier-0`) / `1.44x` (`Tier-1`) vs `Bun.serve`** | -| **Peak Process Memory (`Max RSS` Across Suite)** | **`14.25 – 21.88 MB`** | `26.13 – 41.13 MB` | `45.53 – 61.75 MB` | `69.91 – 93.12 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | +| **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`154,794 req/s`** (Tier-0)
**`147,564 req/s`** (Tier-1) | `100,562 req/s` | `99,082 req/s` | `56,447 req/s` | **`1.54x` (`Tier-0`) / `1.47x` (`Tier-1`) vs `Bun.serve`** | +| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.45 – 21.63 MB`** | `26.13 – 40.25 MB` | `45.69 – 62.38 MB` | `70.15 – 93.00 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | | **Multi-Tenant Security Containment** | **`5 / 5 PASS`** (OCap+SES+Fuel+DLP) | `0 / 5` (Ambient) | `2 / 5` (Coarse CLI) | `0 / 5` (Ambient) | **Hardware & Language Zero-Trust Isolation** | #### 2. Real-Life Workload Summary by Domain (All 33 Workloads Aggregated) | Workload Domain & Stack Coverage | Suites | Slice Cold `.cas` Avg (Range) | Slice Warm (`--warm`) Avg | Bun `v1.4.4` Avg | Deno `v2.9.8` Avg | Node.js `v27.0.0-alpha.0.0.0` Avg | Category Speedup vs Bun / Node.js | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- | -| **Core Edge, Auth & Crypto (`Apps 01, 04, 05, 16`)**
Multi-file TS, SHA-256/HMAC, JWT/OAuth2, `.env` Auto-DLP | `4` | **`8.21 ms`** (`6.70–10.51 ms`) | **`3.72 ms`** | `14.26 ms` | `41.57 ms` | `62.14 ms` | **`1.74x Bun` (`3.83x` Warm) / `7.57x Node`** | -| **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`11.43 ms`** (`7.62–14.79 ms`) | **`4.37 ms`** | `17.40 ms` | `48.13 ms` | `66.84 ms` | **`1.52x Bun` (`3.98x` Warm) / `5.85x Node`** | -| **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`16.13 ms`** (`8.52–30.84 ms`) | **`8.10 ms`** | `18.60 ms` | `52.66 ms` | `95.09 ms` | **`1.15x Bun` (`2.29x` Warm) / `5.90x Node`** | -| **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.24 ms`** (`8.74–20.16 ms`) | **`2.93 ms`** | `28.64 ms` | `63.70 ms` | `86.48 ms` | **`2.01x Bun` (`9.77x` Warm) / `6.07x Node`** | -| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`20.59 ms`** (`15.22–32.08 ms`) | **`8.39 ms`** | `29.73 ms` | `56.05 ms` | `94.07 ms` | **`1.44x Bun` (`3.54x` Warm) / `4.57x Node`** | -| **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`20.58 ms`** (`13.69–32.18 ms`) | **`6.77 ms`** | `20.18 ms` | `54.28 ms` | `79.15 ms` | **`0.98x Bun` (`2.98x` Warm) / `3.85x Node`** | +| **Core Edge, Auth & Crypto (`Apps 01, 04, 05, 16`)**
Multi-file TS, SHA-256/HMAC, JWT/OAuth2, `.env` Auto-DLP | `4` | **`7.84 ms`** (`6.28–10.07 ms`) | **`2.17 ms`** | `14.52 ms` | `42.60 ms` | `62.07 ms` | **`1.85x Bun` (`6.69x` Warm) / `7.92x Node`** | +| **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`10.94 ms`** (`7.25–14.23 ms`) | **`3.16 ms`** | `17.64 ms` | `48.12 ms` | `65.89 ms` | **`1.61x Bun` (`5.59x` Warm) / `6.02x Node`** | +| **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`15.45 ms`** (`8.12–29.33 ms`) | **`7.31 ms`** | `18.48 ms` | `52.47 ms` | `93.96 ms` | **`1.20x Bun` (`2.53x` Warm) / `6.08x Node`** | +| **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.25 ms`** (`8.72–20.99 ms`) | **`2.48 ms`** | `28.68 ms` | `62.87 ms` | `86.44 ms` | **`2.01x Bun` (`11.57x` Warm) / `6.07x Node`** | +| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`20.74 ms`** (`14.65–34.19 ms`) | **`7.47 ms`** | `29.22 ms` | `54.14 ms` | `93.40 ms` | **`1.41x Bun` (`3.91x` Warm) / `4.50x Node`** | +| **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`21.17 ms`** (`13.17–34.84 ms`) | **`6.27 ms`** | `20.96 ms` | `56.54 ms` | `80.98 ms` | **`0.99x Bun` (`3.34x` Warm) / `3.82x Node`** | #### 3. Flagship Real-World Representative Workloads (9 of 33 Highlights) | # | Flagship Workload | Slice Cold `.cas` | Slice Warm (`--warm`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :--- | -| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.70 ms`** | **`1.68 ms`** | `13.45 ms` | `35.70 ms` | `59.15 ms` | **`2.01x Bun` (`8.01x` Warm) / `8.83x Node`** | -| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.62 ms`** | **`1.72 ms`** | `13.79 ms` | `45.41 ms` | `61.73 ms` | **`1.81x Bun` (`8.00x` Warm) / `8.10x Node`** | -| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`16.69 ms`** | **`7.97 ms`** | `21.63 ms` | `53.17 ms` | `112.88 ms` | **`1.30x Bun` (`2.71x` Warm) / `6.76x Node`** | -| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.30 ms`** | **`0.61 ms`** | `22.40 ms` | `55.00 ms` | `76.30 ms` | **`1.98x Bun` (`36.60x` Warm) / `6.75x Node`** | -| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.16 ms`** | **`2.23 ms`** | `55.92 ms` | `112.63 ms` | `101.84 ms` | **`2.77x Bun` (`25.10x` Warm) / `5.05x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.22 ms`** | **`5.63 ms`** | `19.63 ms` | `52.60 ms` | `94.61 ms` | **`1.29x Bun` (`3.49x` Warm) / `6.22x Node`** | -| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`32.08 ms`** | **`16.95 ms`** | `43.52 ms` | `74.25 ms` | `112.27 ms` | **`1.36x Bun` (`2.57x` Warm) / `3.50x Node`** | -| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.71 ms`** | **`13.02 ms`** | `28.39 ms` | `72.12 ms` | `88.96 ms` | **`0.88x Bun` (`2.18x` Warm) / `2.76x Node`** | -| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.21 ms`** | **`7.92 ms`** | `20.31 ms` | `62.71 ms` | `84.14 ms` | **`1.11x Bun` (`2.56x` Warm) / `4.62x Node`** | +| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.28 ms`** | **`1.05 ms`** | `13.38 ms` | `35.22 ms` | `58.45 ms` | **`2.13x Bun` (`12.74x` Warm) / `9.31x Node`** | +| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.25 ms`** | **`1.29 ms`** | `14.08 ms` | `43.23 ms` | `61.79 ms` | **`1.94x Bun` (`10.92x` Warm) / `8.52x Node`** | +| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.83 ms`** | **`6.70 ms`** | `21.20 ms` | `56.40 ms` | `108.62 ms` | **`1.34x Bun` (`3.17x` Warm) / `6.86x Node`** | +| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.26 ms`** | **`0.50 ms`** | `25.08 ms` | `55.78 ms` | `73.35 ms` | **`2.23x Bun` (`50.56x` Warm) / `6.51x Node`** | +| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.99 ms`** | **`1.74 ms`** | `57.15 ms` | `114.02 ms` | `101.72 ms` | **`2.72x Bun` (`32.86x` Warm) / `4.85x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`14.65 ms`** | **`5.59 ms`** | `19.86 ms` | `51.15 ms` | `94.15 ms` | **`1.36x Bun` (`3.55x` Warm) / `6.43x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`34.37 ms`** | **`14.26 ms`** | `43.71 ms` | `68.04 ms` | `108.54 ms` | **`1.28x Bun` (`3.07x` Warm) / `3.17x Node`** | +| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.84 ms`** | **`12.99 ms`** | `28.86 ms` | `73.55 ms` | `91.05 ms` | **`0.83x Bun` (`2.22x` Warm) / `2.61x Node`** | +| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.14 ms`** | **`8.32 ms`** | `21.10 ms` | `65.54 ms` | `86.65 ms` | **`1.16x Bun` (`2.54x` Warm) / `4.78x Node`** | *Full 33-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](./tests/reports/latest.md)**.* diff --git a/crates/slice-cli/src/commands/run.rs b/crates/slice-cli/src/commands/run.rs index b94c2fa..7c5af61 100644 --- a/crates/slice-cli/src/commands/run.rs +++ b/crates/slice-cli/src/commands/run.rs @@ -142,6 +142,17 @@ pub(crate) fn run_embedded_standalone(archive: MappedCasArchive) -> Result<()> { exec_cfg.fuel_limit, exec_cfg.mem_limit, ); + if !args.is_empty() { + let mut standalone_argv = Vec::with_capacity(args.len() + 1); + standalone_argv.push("slice".to_string()); + standalone_argv.push(args[0].clone()); + for a in &args[1..] { + if a != "--quiet" && a != "-q" && a != "--metrics" && a != "--warm" { + standalone_argv.push(a.clone()); + } + } + isolate.set_process_argv(standalone_argv); + } for sec in &exec_cfg.audit_secrets { isolate.add_egress_audit_secret(sec.clone()); } diff --git a/crates/slice-cli/src/server/connection.rs b/crates/slice-cli/src/server/connection.rs index 30c2b4a..689e565 100644 --- a/crates/slice-cli/src/server/connection.rs +++ b/crates/slice-cli/src/server/connection.rs @@ -669,7 +669,7 @@ pub(crate) fn serve_connection_with_isolate( .map(|v| v.as_slice()) .unwrap_or(bytecode); - match isolate.execute_http_request(active_bytecode, None, &req_ctx) { + match isolate.execute_http_request_fast(active_bytecode, None, &req_ctx) { Ok(outcome) => { // Check for RFC 6455 Server-Side WebSocket Upgrade (`Upgrade: websocket` + `Sec-WebSocket-Key`) if is_ws_upgrade @@ -685,7 +685,7 @@ pub(crate) fn serve_connection_with_isolate( write_buf.extend_from_slice(accept_key.as_bytes()); write_buf .extend_from_slice(b"\r\nServer: Slice-NexusJS/0.2\r\nX-Slice-Tenant: "); - write_buf.extend_from_slice(outcome.metrics.tenant_id.as_bytes()); + write_buf.extend_from_slice(tenant_id.as_bytes()); write_buf.extend_from_slice(b"\r\n\r\n"); stream.write_all(write_buf)?; stream.flush()?; @@ -766,10 +766,10 @@ pub(crate) fn serve_connection_with_isolate( return Ok(()); } - let isolate_us = outcome.metrics.total_time_ns / 1_000; + let isolate_us = outcome.total_time_ns / 1_000; let total_us = (req_start.elapsed().as_nanos() / 1_000) as u64; let safe_ct = if slice_engine::is_valid_http_header_value(&outcome.content_type) { - outcome.content_type.as_str() + outcome.content_type.as_ref() } else { "application/octet-stream" }; @@ -791,13 +791,13 @@ pub(crate) fn serve_connection_with_isolate( write_buf.extend_from_slice(b"\r\nConnection: "); write_buf.extend_from_slice(conn_hdr.as_bytes()); write_buf.extend_from_slice(b"\r\nServer: Slice-NexusJS/0.2\r\nX-Slice-Tenant: "); - write_buf.extend_from_slice(outcome.metrics.tenant_id.as_bytes()); + write_buf.extend_from_slice(tenant_id.as_bytes()); write_buf.extend_from_slice(b"\r\nX-Slice-Isolate-Us: "); push_u64_ascii(write_buf, isolate_us); write_buf.extend_from_slice(b"\r\nX-Slice-Total-Us: "); push_u64_ascii(write_buf, total_us); write_buf.extend_from_slice(b"\r\nX-Slice-Fuel-Used: "); - push_u64_ascii(write_buf, outcome.metrics.fuel_consumed); + push_u64_ascii(write_buf, outcome.fuel_consumed); write_buf.extend_from_slice(b"\r\n"); // N-Sec-2: Validate all custom response headers against CRLF / control character injection diff --git a/crates/slice-engine/build.rs b/crates/slice-engine/build.rs index dcff3f2..7409630 100644 --- a/crates/slice-engine/build.rs +++ b/crates/slice-engine/build.rs @@ -58,6 +58,7 @@ const PRELUDE_SPECS: &[(&str, &str)] = &[ "src/preludes/17_buffer_binary_rw.js", ), ("INTL_PRELUDE", "src/preludes/18_intl.js"), + ("PROCESS_CLI_PRELUDE", "src/preludes/19_process_cli.js"), ]; fn main() { diff --git a/crates/slice-engine/microbench/main.rs b/crates/slice-engine/microbench/main.rs index 4d7f42d..81cfaf8 100644 --- a/crates/slice-engine/microbench/main.rs +++ b/crates/slice-engine/microbench/main.rs @@ -7,7 +7,7 @@ use slice_engine::intrinsics::{ fast_parse_ms, hmac_sha256_hex, make_ring_aead_key, parse_whatwg_url, sha256_hex, zlib_compress_bytes, zlib_decompress_bytes, AesExpandedKey, }; -use slice_engine::{compile_source_to_bytecode, SliceIsolate}; +use slice_engine::{compile_source_to_bytecode, HttpRequestContext, SliceIsolate}; use slice_sandbox::CapabilityToken; use std::hint::black_box; @@ -404,12 +404,147 @@ if (idx < 0 || gCount !== 5 || ab2.byteLength !== 64 || !c1 || !d1) throw new Er group.finish(); } +fn bench_http_cli_and_host_fs(c: &mut Criterion) { + let mut group = c.benchmark_group("slice_engine::http_and_cli"); + + let tier0_http_bc = + compile_source_to_bytecode("const base = 1400; const fee = 37; return base + fee;"); + group.bench_function("http_fast_dispatch_tier0_slicesnp", |b| { + let mut iso = SliceIsolate::spawn( + "tenant-default", + 1, + CapabilityToken::pure_compute(), + 10_000_000, + 16 * 1024 * 1024, + ); + let hdrs = [("host", "localhost"), ("accept", "application/json")]; + let req = HttpRequestContext { + method: "GET", + path: "/v1/quote", + query: "tier=0", + tenant_id: "tenant-default", + body: "", + headers: &hdrs, + }; + let mut slot = 1u32; + b.iter(|| { + slot = slot.wrapping_add(1); + iso.reset_for_request("tenant-default", slot, 10_000_000, 16 * 1024 * 1024); + let out = iso + .execute_http_request_fast(black_box(&tier0_http_bc), None, black_box(&req)) + .expect("tier0 http fast"); + black_box(out.response_body.len()) + }); + }); + + let wintertc_http_src = r#" +const req = Slice.request(); +Slice.respond( + 200, + JSON.stringify({ ok: true, method: req.method, path: req.path, tenant: req.tenant }), + "application/json" +); +"#; + let wintertc_http_bc = compile_source_to_bytecode(wintertc_http_src); + group.bench_function("http_fast_dispatch_wintertc_boacas", |b| { + SliceIsolate::prewarm_boa_pool(1); + let mut iso = SliceIsolate::spawn( + "tenant-default", + 1, + CapabilityToken::pure_compute(), + 10_000_000, + 16 * 1024 * 1024, + ); + let hdrs = [("host", "localhost"), ("user-agent", "slice-bench/1.0")]; + let req = HttpRequestContext { + method: "GET", + path: "/v1/health", + query: "region=iad", + tenant_id: "tenant-default", + body: "", + headers: &hdrs, + }; + let mut slot = 1u32; + b.iter(|| { + slot = slot.wrapping_add(1); + iso.reset_for_request("tenant-default", slot, 10_000_000, 16 * 1024 * 1024); + let out = iso + .execute_http_request_fast(black_box(&wintertc_http_bc), None, black_box(&req)) + .expect("wintertc http fast"); + black_box(out.response_body.len()) + }); + }); + + let kv_cli_src = r#" +Slice.kv.set("bench:k1", "alpha-value", 0); +const val = Slice.kv.get("bench:k1"); +const bl = Buffer.byteLength(val + process.argv[0], "utf8"); +if (bl < 10) throw new Error("kv cli bench mismatch"); +"#; + let kv_cli_bc = compile_source_to_bytecode(kv_cli_src); + group.bench_function("warm_kv_and_process_cli_boacas", |b| { + SliceIsolate::prewarm_boa_pool(1); + b.iter(|| { + let mut iso = SliceIsolate::spawn( + "bench-kv-cli", + 1, + CapabilityToken::pure_compute(), + 10_000_000, + 16 * 1024 * 1024, + ); + let res = iso + .execute_bytecode(black_box(&kv_cli_bc), None) + .expect("kv cli execute"); + black_box(res.fuel_consumed) + }); + }); + + let tmp_dir = std::env::temp_dir().join("slice_microbench_host_fs"); + let _ = std::fs::create_dir_all(&tmp_dir); + let host_file = tmp_dir.join("sample_payload.json"); + let sample_json = r#"{"service":"slice-runtime","ok":true,"count":42,"tags":["fast","safe","deterministic"]}"# + .repeat(8); + let _ = std::fs::write(&host_file, sample_json.as_bytes()); + let host_file_norm = host_file.to_string_lossy().replace('\\', "/"); + let tmp_dir_norm = tmp_dir.to_string_lossy().replace('\\', "/"); + let host_fs_src = format!( + r#" +const fs = require("node:fs"); +const txt = fs.readFileSync({:?}, "utf8"); +const raw = fs.readFileSync({:?}); +if (txt.length !== raw.length || txt.length < 64) throw new Error("host fs mismatch"); +"#, + host_file_norm, host_file_norm + ); + let host_fs_bc = compile_source_to_bytecode(&host_fs_src); + group.bench_function("host_fs_read_file_sync_utf8_and_bytes", |b| { + SliceIsolate::prewarm_boa_pool(1); + let caps = CapabilityToken::pure_compute().with_read_prefix(&tmp_dir_norm); + b.iter(|| { + let mut iso = SliceIsolate::spawn( + "bench-host-fs", + 1, + caps.clone(), + 10_000_000, + 16 * 1024 * 1024, + ); + let res = iso + .execute_bytecode(black_box(&host_fs_bc), None) + .expect("host fs execute"); + black_box(res.fuel_consumed) + }); + }); + + group.finish(); +} + criterion_group!( benches, bench_boacas_and_automaton, bench_intrinsics_and_numeric_vm, bench_json_operations, bench_vfs_and_stream_operations, - bench_wave3_als_intl_crypto_and_buffer + bench_wave3_als_intl_crypto_and_buffer, + bench_http_cli_and_host_fs ); criterion_main!(benches); diff --git a/crates/slice-engine/src/bindings/child_process.rs b/crates/slice-engine/src/bindings/child_process.rs index c3aa069..2e516d9 100644 --- a/crates/slice-engine/src/bindings/child_process.rs +++ b/crates/slice-engine/src/bindings/child_process.rs @@ -3,7 +3,7 @@ use crate::bindings::helpers::{active_tenant_id_or_default, consume_crypto_kdf_fuel}; use crate::boa_realm::{ check_boa_fs_read_ocap, BOA_EGRESS_SECRETS, BOA_ENV_MAP, BOA_EXEC_BINS, BOA_KV_MEM_BUDGET, - BOA_LAST_CHILD_PROC_VIOLATION, BOA_VIOLATION, + BOA_VIOLATION, }; use crate::intrinsics::{base64_decode, base64_encode}; use crate::state_and_kv::verify_egress_secrets_slice; @@ -639,9 +639,7 @@ pub(crate) fn register_child_process_host_functions(ctx: &mut boa_engine::Contex binary: exec_file, }; let msg = violation.to_string(); - BOA_LAST_CHILD_PROC_VIOLATION.with(|v| { - *v.borrow_mut() = Some(violation); - }); + crate::boa_realm::set_child_proc_violation(violation); return Err(JsNativeError::error().with_message(msg).into()); } @@ -653,9 +651,7 @@ pub(crate) fn register_child_process_host_functions(ctx: &mut boa_engine::Contex path: cwd_dir.clone(), }; let msg = violation.to_string(); - BOA_LAST_CHILD_PROC_VIOLATION.with(|v| { - *v.borrow_mut() = Some(violation); - }); + crate::boa_realm::set_child_proc_violation(violation); return Err(JsNativeError::error().with_message(msg).into()); } } @@ -762,9 +758,7 @@ pub(crate) fn register_child_process_host_functions(ctx: &mut boa_engine::Contex ) { let msg = violation.to_string(); - BOA_LAST_CHILD_PROC_VIOLATION.with(|v| { - *v.borrow_mut() = Some(violation); - }); + crate::boa_realm::set_child_proc_violation(violation); return Err(JsNativeError::error().with_message(msg).into()); } } diff --git a/crates/slice-engine/src/bindings/core.rs b/crates/slice-engine/src/bindings/core.rs index 4e157e1..97128c9 100644 --- a/crates/slice-engine/src/bindings/core.rs +++ b/crates/slice-engine/src/bindings/core.rs @@ -13,8 +13,8 @@ use crate::event_loop::{ cancel_timer, refresh_timer, schedule_immediate, schedule_timer, set_timer_ref, }; use crate::intrinsics::{ - base64_decode, base64_encode, bytes_to_hex, hmac_sha256_bytes, hmac_sha256_hex, sha256_bytes, - sha256_hex, + base64_decode, base64_decoded_len_bytes, base64_encode, bytes_to_hex, hmac_sha256_bytes, + hmac_sha256_hex, sha256_bytes, sha256_hex, }; use crate::js_preludes::eval_lazy_prelude_shard; use crate::node_builtins::eval_lazy_builtin_module; @@ -340,8 +340,9 @@ pub(crate) fn register_slice_native_host_functions(ctx: &mut boa_engine::Context js_string!("__slice_utf8_byte_len"), 2, NativeFunction::from_fn_ptr(|_this, args, context| { + use boa_engine::builtins::dataview::DataView; let Some(first) = args.first() else { - return Ok(BoaVal::from(0.0)); + return Ok(BoaVal::from(0)); }; if let Some(obj) = first.as_object() { if let Some(ta) = obj.downcast_ref::() { @@ -353,6 +354,11 @@ pub(crate) fn register_slice_native_host_functions(ctx: &mut boa_engine::Context let bl = ab.data().map(|d| d.len()).unwrap_or(0); return Ok(BoaVal::from(bl as f64)); } + if let Some(dv) = obj.downcast_ref::() { + if let Some(bl) = dv.with_bytes(|b| b.len()) { + return Ok(BoaVal::from(bl as f64)); + } + } if let Ok(bl) = obj.get(js_string!("byteLength"), context) { if let Some(n) = bl.as_number() { return Ok(BoaVal::from(n)); @@ -364,30 +370,89 @@ pub(crate) fn register_slice_native_host_functions(ctx: &mut boa_engine::Context } } } - let s = first.to_string(context)?.to_std_string_escaped(); + let js_s = match first.as_string() { + Some(s) => s, + None => first.to_string(context)?, + }; + // Encoding kind: 0 = utf8, 1 = latin1/ascii/binary, 2 = utf16le/ucs2, 3 = hex, 4 = base64/base64url + let mut enc_kind: u8 = 0; if let Some(enc_val) = args.get(1).filter(|v| !v.is_undefined() && !v.is_null()) { - let e = enc_val.to_string(context)?.to_std_string_escaped(); - if e.eq_ignore_ascii_case("hex") { - return Ok(BoaVal::from((s.len() >> 1) as f64)); + let enc_js = match enc_val.as_string() { + Some(s) => s, + None => enc_val.to_string(context)?, + }; + if let boa_engine::string::JsStrVariant::Latin1(eb) = enc_js.as_str().variant() { + if eb.eq_ignore_ascii_case(b"utf8") || eb.eq_ignore_ascii_case(b"utf-8") { + enc_kind = 0; + } else if eb.eq_ignore_ascii_case(b"latin1") + || eb.eq_ignore_ascii_case(b"binary") + || eb.eq_ignore_ascii_case(b"ascii") + { + enc_kind = 1; + } else if eb.eq_ignore_ascii_case(b"utf16le") + || eb.eq_ignore_ascii_case(b"utf-16le") + || eb.eq_ignore_ascii_case(b"ucs2") + || eb.eq_ignore_ascii_case(b"ucs-2") + { + enc_kind = 2; + } else if eb.eq_ignore_ascii_case(b"hex") { + enc_kind = 3; + } else if eb.eq_ignore_ascii_case(b"base64") + || eb.eq_ignore_ascii_case(b"base64url") + { + enc_kind = 4; + } + } else { + let e = enc_js.to_std_string_escaped(); + if e.eq_ignore_ascii_case("latin1") + || e.eq_ignore_ascii_case("binary") + || e.eq_ignore_ascii_case("ascii") + { + enc_kind = 1; + } else if e.eq_ignore_ascii_case("utf16le") + || e.eq_ignore_ascii_case("utf-16le") + || e.eq_ignore_ascii_case("ucs2") + || e.eq_ignore_ascii_case("ucs-2") + { + enc_kind = 2; + } else if e.eq_ignore_ascii_case("hex") { + enc_kind = 3; + } else if e.eq_ignore_ascii_case("base64") + || e.eq_ignore_ascii_case("base64url") + { + enc_kind = 4; + } } - if e.eq_ignore_ascii_case("base64") || e.eq_ignore_ascii_case("base64url") { - return Ok(BoaVal::from(base64_decode(&s).len() as f64)); + } + + let byte_len: usize = match (enc_kind, js_s.as_str().variant()) { + (0, boa_engine::string::JsStrVariant::Latin1(bytes)) => { + // In Latin-1 (`0x00..=0xFF`), `0x00..=0x7F` encodes to 1 UTF-8 byte + // and `0x80..=0xFF` encodes to 2 UTF-8 bytes. + let high_count: usize = bytes.iter().map(|&b| usize::from(b >> 7)).sum(); + bytes.len() + high_count } - if e.eq_ignore_ascii_case("latin1") - || e.eq_ignore_ascii_case("binary") - || e.eq_ignore_ascii_case("ascii") - { - return Ok(BoaVal::from(s.chars().count() as f64)); + (0, boa_engine::string::JsStrVariant::Utf16(units)) => { + char::decode_utf16(units.iter().copied()) + .map(|r| match r { + Ok(c) => c.len_utf8(), + Err(_) => 3, + }) + .sum() } - if e.eq_ignore_ascii_case("utf16le") - || e.eq_ignore_ascii_case("utf-16le") - || e.eq_ignore_ascii_case("ucs2") - || e.eq_ignore_ascii_case("ucs-2") - { - return Ok(BoaVal::from((s.encode_utf16().count() * 2) as f64)); + (1, _) => js_s.len(), + (2, _) => js_s.len() * 2, + (3, _) => js_s.len() >> 1, + (4, boa_engine::string::JsStrVariant::Latin1(bytes)) => { + base64_decoded_len_bytes(bytes) } - } - Ok(BoaVal::from(s.len() as f64)) + (4, boa_engine::string::JsStrVariant::Utf16(_)) => { + let owned = js_s.to_std_string_escaped(); + base64_decoded_len_bytes(owned.as_bytes()) + } + _ => js_s.len(), + }; + Ok(BoaVal::from(byte_len as f64)) }), ); @@ -485,21 +550,7 @@ pub(crate) fn register_slice_native_host_functions(ctx: &mut boa_engine::Context ); let _ = ctx.register_global_builtin_callable( - js_string!("__slice_timer_clear"), - 1, - NativeFunction::from_fn_ptr(|_this, args, _context| { - let id = args - .first() - .and_then(|v| v.as_number()) - .map(|n| n.max(0.0) as u32) - .unwrap_or(0); - cancel_timer(id); - Ok(BoaVal::undefined()) - }), - ); - - let _ = ctx.register_global_builtin_callable( - js_string!("__slice_timer_ref"), + js_string!("__slice_timer_ctl"), 2, NativeFunction::from_fn_ptr(|_this, args, _context| { let id = args @@ -507,22 +558,18 @@ pub(crate) fn register_slice_native_host_functions(ctx: &mut boa_engine::Context .and_then(|v| v.as_number()) .map(|n| n.max(0.0) as u32) .unwrap_or(0); - let refed = args.get(1).and_then(|v| v.as_boolean()).unwrap_or(true); - set_timer_ref(id, refed); - Ok(BoaVal::undefined()) - }), - ); - - let _ = ctx.register_global_builtin_callable( - js_string!("__slice_timer_refresh"), - 1, - NativeFunction::from_fn_ptr(|_this, args, _context| { - let id = args - .first() + let op = args + .get(1) .and_then(|v| v.as_number()) - .map(|n| n.max(0.0) as u32) + .map(|n| n as i32) .unwrap_or(0); - refresh_timer(id); + match op { + 0 => cancel_timer(id), + 1 => set_timer_ref(id, true), + 2 => set_timer_ref(id, false), + 3 => refresh_timer(id), + _ => {} + } Ok(BoaVal::undefined()) }), ); @@ -567,25 +614,39 @@ pub(crate) fn register_slice_native_host_functions(ctx: &mut boa_engine::Context ); let _ = ctx.register_global_builtin_callable( - js_string!("__slice_mark_proc_dirty"), - 0, - NativeFunction::from_fn_ptr(|_this, _args, _context| { - crate::boa_realm::mark_subsystem_dirty(crate::boa_realm::DIRTY_PROCESS); - Ok(BoaVal::undefined()) - }), - ); - - let _ = ctx.register_global_builtin_callable( - js_string!("__slice_process_exit"), - 1, + js_string!("__slice_process_ctl"), + 2, NativeFunction::from_fn_ptr(|_this, args, context| { + let op = args + .first() + .and_then(|v| v.as_number()) + .map(|n| n as i32) + .unwrap_or(0); crate::boa_realm::mark_subsystem_dirty(crate::boa_realm::DIRTY_PROCESS); + if op == 0 { + return Ok(BoaVal::undefined()); + } + if op == 1 { + let custom_opt = crate::boa_realm::BOA_CUSTOM_ARGV.with(|a| a.borrow().clone()); + let arr = if let Some(items) = custom_opt { + boa_engine::object::builtins::JsArray::from_iter( + items.iter().map(|s| BoaVal::from(js_string!(s.as_str()))), + context, + ) + } else { + boa_engine::object::builtins::JsArray::from_iter( + std::iter::once(BoaVal::from(js_string!("slice"))), + context, + ) + }; + return Ok(BoaVal::from(arr)); + } let proc_obj = context .global_object() .get(js_string!("process"), context) .ok() .and_then(|v| v.as_object()); - let mut code: i32 = match args.first() { + let mut code: i32 = match args.get(1) { Some(v) if !v.is_undefined() && !v.is_null() => v.to_i32(context).unwrap_or(0), _ => { if let Some(ref p) = proc_obj { @@ -630,8 +691,7 @@ pub(crate) fn register_slice_native_host_functions(ctx: &mut boa_engine::Context } } } - crate::boa_realm::BOA_PROCESS_EXIT.with(|e| e.set(Some(code))); - crate::boa_realm::BOA_LAST_EXIT_CODE.with(|e| e.set(Some(code))); + crate::boa_realm::set_process_exit(code); if crate::workers::is_worker_thread() { crate::workers::worker_self_set_listening(false, Some(code)); } diff --git a/crates/slice-engine/src/bindings/fs.rs b/crates/slice-engine/src/bindings/fs.rs index f8e9d08..d26a2bf 100644 --- a/crates/slice-engine/src/bindings/fs.rs +++ b/crates/slice-engine/src/bindings/fs.rs @@ -20,20 +20,40 @@ fn vfs_or_host_is_dir(norm: &str, raw_path: &str) -> bool { if norm == "/" || norm == "." { return true; } - if BOA_VFS_DIRS.with(|d| d.borrow().contains(norm)) { + if BOA_VFS_DIRS.with(|d| { + let dirs = d.borrow(); + !dirs.is_empty() && dirs.contains(norm) + }) { return true; } - if BOA_VFS_CACHE.with(|c| c.borrow().contains_key(norm)) { - return false; + let vfs_state = BOA_VFS_CACHE.with(|c| { + let map = c.borrow(); + if map.is_empty() { + return None; + } + if map.contains_key(norm) { + return Some(false); + } + let prefix = format!("{}/", norm); + if map.keys().any(|k| k.starts_with(&prefix)) { + Some(true) + } else { + None + } + }); + if let Some(res) = vfs_state { + return res; } - let prefix = format!("{}/", norm); - BOA_VFS_CACHE.with(|c| c.borrow().keys().any(|k| k.starts_with(&prefix))) - || std::path::Path::new(norm).is_dir() - || std::path::Path::new(raw_path).is_dir() + std::path::Path::new(norm).is_dir() + || (raw_path != norm && std::path::Path::new(raw_path).is_dir()) } -pub(crate) fn resolve_vfs_symlink_norm(norm: &str) -> String { - let mut current = norm.to_string(); +#[inline] +pub(crate) fn resolve_vfs_symlink_norm(mut current: String) -> String { + let has_vfs = BOA_VFS_CACHE.with(|c| !c.borrow().is_empty()); + if !has_vfs { + return current; + } for _ in 0..8 { let next_opt = BOA_VFS_CACHE.with(|c| { c.borrow().get(¤t).and_then(|bytes| { @@ -51,6 +71,55 @@ pub(crate) fn resolve_vfs_symlink_norm(norm: &str) -> String { current } +#[inline] +fn read_host_bytes(norm: &str, raw_path: &str) -> std::io::Result> { + std::fs::read(norm).or_else(|e| { + if raw_path == norm { + Err(e) + } else { + std::fs::read(raw_path) + } + }) +} + +#[inline] +fn host_metadata(norm: &str, raw_path: &str) -> std::io::Result { + std::fs::metadata(norm).or_else(|e| { + if raw_path == norm { + Err(e) + } else { + std::fs::metadata(raw_path) + } + }) +} + +#[inline] +fn utf8_slice_to_js_val(bytes: &[u8]) -> boa_engine::JsValue { + if bytes.is_ascii() { + return boa_engine::JsValue::from(boa_engine::js_string!( + boa_engine::string::JsStr::latin1(bytes) + )); + } + let content = String::from_utf8_lossy(bytes); + boa_engine::JsValue::from(boa_engine::js_string!(content.as_ref())) +} + +#[inline] +fn utf8_vec_to_js_val(bytes: Vec) -> boa_engine::JsValue { + if bytes.is_ascii() { + return boa_engine::JsValue::from(boa_engine::js_string!( + boa_engine::string::JsStr::latin1(&bytes) + )); + } + match String::from_utf8(bytes) { + Ok(s) => boa_engine::JsValue::from(boa_engine::js_string!(s)), + Err(e) => { + let content = String::from_utf8_lossy(e.as_bytes()); + boa_engine::JsValue::from(boa_engine::js_string!(content.as_ref())) + } + } +} + pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { use boa_engine::{js_string, JsNativeError, JsValue as BoaVal, NativeFunction}; if ctx @@ -74,20 +143,34 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return Ok(BoaVal::from(js_string!(""))); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_read_ocap(&norm) { return Ok(BoaVal::from(js_string!(""))); } - if let Some(arc_bytes) = BOA_VFS_CACHE.with(|c| c.borrow().get(&norm).cloned()) { - let content = String::from_utf8_lossy(&arc_bytes).into_owned(); - return Ok(BoaVal::from(js_string!(content))); + if let Some(arc_bytes) = BOA_VFS_CACHE.with(|c| { + let map = c.borrow(); + if map.is_empty() { + None + } else { + map.get(&norm).cloned() + } + }) { + return Ok(utf8_slice_to_js_val(&arc_bytes)); } - if vfs_or_host_is_dir(&norm, &path) { + if norm == "/" + || norm == "." + || BOA_VFS_DIRS.with(|d| { + let dirs = d.borrow(); + !dirs.is_empty() && dirs.contains(&norm) + }) + { return Ok(BoaVal::from(-21)); } - if let Ok(bytes) = std::fs::read(&norm).or_else(|_| std::fs::read(&path)) { - let content = String::from_utf8_lossy(&bytes).into_owned(); - return Ok(BoaVal::from(js_string!(content))); + if let Ok(bytes) = read_host_bytes(&norm, &path) { + return Ok(utf8_vec_to_js_val(bytes)); + } + if vfs_or_host_is_dir(&norm, &path) { + return Ok(BoaVal::from(-21)); } Ok(BoaVal::null()) }), @@ -106,19 +189,35 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return bytes_to_js_uint8_array(&[], context); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_read_ocap(&norm) { return bytes_to_js_uint8_array(&[], context); } - if let Some(arc_bytes) = BOA_VFS_CACHE.with(|c| c.borrow().get(&norm).cloned()) { + if let Some(arc_bytes) = BOA_VFS_CACHE.with(|c| { + let map = c.borrow(); + if map.is_empty() { + None + } else { + map.get(&norm).cloned() + } + }) { return bytes_to_js_uint8_array(&arc_bytes, context); } - if vfs_or_host_is_dir(&norm, &path) { + if norm == "/" + || norm == "." + || BOA_VFS_DIRS.with(|d| { + let dirs = d.borrow(); + !dirs.is_empty() && dirs.contains(&norm) + }) + { return Ok(BoaVal::from(-21)); } - if let Ok(bytes) = std::fs::read(&norm).or_else(|_| std::fs::read(&path)) { + if let Ok(bytes) = read_host_bytes(&norm, &path) { return bytes_to_js_uint8_array(&bytes, context); } + if vfs_or_host_is_dir(&norm, &path) { + return Ok(BoaVal::from(-21)); + } Ok(BoaVal::null()) }), ); @@ -136,8 +235,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_write_ocap(&path) { return Ok(BoaVal::undefined()); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_write_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_write_ocap(&norm) { return Ok(BoaVal::undefined()); } if BOA_VFS_DIRS.with(|d| d.borrow().contains(&norm)) { @@ -184,8 +283,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_write_ocap(&path) { return Ok(BoaVal::undefined()); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_write_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_write_ocap(&norm) { return Ok(BoaVal::undefined()); } if BOA_VFS_DIRS.with(|d| d.borrow().contains(&norm)) { @@ -234,19 +333,34 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return Ok(BoaVal::from(false)); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_read_ocap(&norm) { return Ok(BoaVal::from(false)); } - let prefix = format!("{}/", norm); - let exists = BOA_VFS_CACHE.with(|c| { + let vfs_exists = BOA_VFS_CACHE.with(|c| { let map = c.borrow(); - map.contains_key(&norm) || map.keys().any(|k| k.starts_with(&prefix)) + if map.is_empty() { + false + } else if map.contains_key(&norm) { + true + } else { + let prefix = format!("{}/", norm); + map.keys().any(|k| k.starts_with(&prefix)) + } }) || BOA_VFS_DIRS.with(|d| { let dirs = d.borrow(); - dirs.contains(&norm) || dirs.iter().any(|k| k.starts_with(&prefix)) - }) || std::path::Path::new(&norm).exists() - || std::path::Path::new(&path).exists(); + if dirs.is_empty() { + false + } else if dirs.contains(&norm) { + true + } else { + let prefix = format!("{}/", norm); + dirs.iter().any(|k| k.starts_with(&prefix)) + } + }); + let exists = vfs_exists + || std::path::Path::new(&norm).exists() + || (path != norm && std::path::Path::new(&path).exists()); Ok(BoaVal::from(exists)) }), ); @@ -294,8 +408,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return Ok(BoaVal::from(js_string!("[]"))); } - let norm_dir = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm_dir) { + let norm_dir = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm_dir != path && !check_boa_fs_read_ocap(&norm_dir) { return Ok(BoaVal::from(js_string!("[]"))); } let prefix = format!("{}/", norm_dir); @@ -350,19 +464,27 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return Ok(BoaVal::from(0)); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_read_ocap(&norm) { return Ok(BoaVal::from(0)); } - if let Some(size) = - BOA_VFS_CACHE.with(|c| c.borrow().get(&norm).map(|v| v.len() as u64)) - { + if let Some(size) = BOA_VFS_CACHE.with(|c| { + let map = c.borrow(); + if map.is_empty() { + None + } else { + map.get(&norm).map(|v| v.len() as u64) + } + }) { return Ok(BoaVal::from(size as f64)); } - if BOA_VFS_DIRS.with(|d| d.borrow().contains(&norm)) { + if BOA_VFS_DIRS.with(|d| { + let dirs = d.borrow(); + !dirs.is_empty() && dirs.contains(&norm) + }) { return Ok(BoaVal::from(0.0)); } - if let Ok(meta) = std::fs::metadata(&norm).or_else(|_| std::fs::metadata(&path)) { + if let Ok(meta) = host_metadata(&norm, &path) { return Ok(BoaVal::from(meta.len() as f64)); } if vfs_or_host_is_dir(&norm, &path) { @@ -385,8 +507,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return Ok(BoaVal::from(1_700_000_000_000.0)); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_read_ocap(&norm) { return Ok(BoaVal::from(1_700_000_000_000.0)); } if let Some(custom_mt) = BOA_VFS_MTIMES.with(|m| m.borrow().get(&norm).copied()) { @@ -395,8 +517,7 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if BOA_DET_STATE.with(|s| s.get().is_some()) { return Ok(BoaVal::from(1_700_000_000_000.0)); } - let mtime_ms = std::fs::metadata(&norm) - .or_else(|_| std::fs::metadata(&path)) + let mtime_ms = host_metadata(&norm, &path) .ok() .and_then(|m| m.modified().ok()) .and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok()) @@ -424,8 +545,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return Ok(BoaVal::from(false)); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_read_ocap(&norm) { return Ok(BoaVal::from(false)); } let is_dir = vfs_or_host_is_dir(&norm, &path); @@ -452,8 +573,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&src) || !check_boa_fs_write_ocap(&dest) { return Ok(BoaVal::undefined()); } - let norm_src = resolve_vfs_symlink_norm(&norm_vfs_path(&src)); - let norm_dest = resolve_vfs_symlink_norm(&norm_vfs_path(&dest)); + let norm_src = resolve_vfs_symlink_norm(norm_vfs_path(&src)); + let norm_dest = resolve_vfs_symlink_norm(norm_vfs_path(&dest)); if !check_boa_fs_read_ocap(&norm_src) || !check_boa_fs_write_ocap(&norm_dest) { return Ok(BoaVal::undefined()); } @@ -504,8 +625,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { { return Ok(BoaVal::undefined()); } - let norm_old = resolve_vfs_symlink_norm(&norm_vfs_path(&old_p)); - let norm_new = resolve_vfs_symlink_norm(&norm_vfs_path(&new_p)); + let norm_old = resolve_vfs_symlink_norm(norm_vfs_path(&old_p)); + let norm_new = resolve_vfs_symlink_norm(norm_vfs_path(&new_p)); if !check_boa_fs_read_ocap(&norm_old) || !check_boa_fs_write_ocap(&norm_new) { return Ok(BoaVal::undefined()); } @@ -586,8 +707,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) { return Ok(BoaVal::from(js_string!(""))); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_read_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_read_ocap(&norm) { return Ok(BoaVal::from(js_string!(""))); } if BOA_VFS_CACHE.with(|c| c.borrow().contains_key(&norm)) @@ -803,7 +924,7 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_read_ocap(&path) || !check_boa_fs_write_ocap(&path) { return Ok(BoaVal::undefined()); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); if !check_boa_fs_read_ocap(&norm) || !check_boa_fs_write_ocap(&norm) { return Ok(BoaVal::undefined()); } @@ -840,8 +961,8 @@ pub(crate) fn register_fs_host_functions(ctx: &mut boa_engine::Context) { if !check_boa_fs_write_ocap(&path) { return Ok(BoaVal::undefined()); } - let norm = resolve_vfs_symlink_norm(&norm_vfs_path(&path)); - if !check_boa_fs_write_ocap(&norm) { + let norm = resolve_vfs_symlink_norm(norm_vfs_path(&path)); + if norm != path && !check_boa_fs_write_ocap(&norm) { return Ok(BoaVal::undefined()); } let mtime_ms = args diff --git a/crates/slice-engine/src/intrinsics/encoding.rs b/crates/slice-engine/src/intrinsics/encoding.rs index 39f639b..402a11c 100644 --- a/crates/slice-engine/src/intrinsics/encoding.rs +++ b/crates/slice-engine/src/intrinsics/encoding.rs @@ -107,6 +107,17 @@ pub fn base64_encode(data: &[u8], url_safe: bool) -> String { unsafe { String::from_utf8_unchecked(out) } } +#[inline] +pub fn base64_decoded_len_bytes(bytes: &[u8]) -> usize { + let mut valid = 0usize; + for &b in bytes { + if B64_LENIENT_LUT[b as usize] != 0xFF { + valid += 1; + } + } + (valid * 3) >> 2 +} + pub fn base64_decode(input: &str) -> Vec { let mut out = Vec::with_capacity((input.len() * 3) / 4); let mut buf = 0u32; diff --git a/crates/slice-engine/src/isolate/exec_boa.rs b/crates/slice-engine/src/isolate/exec_boa.rs index 592aea1..5c905f9 100644 --- a/crates/slice-engine/src/isolate/exec_boa.rs +++ b/crates/slice-engine/src/isolate/exec_boa.rs @@ -2,13 +2,18 @@ //! Warm Realm Pool Management, and Shared OCap/DLP/SES Compartment Lifecycle Guards. use crate::boa_realm::{ - acquire_warm_boa_realm, create_bare_boa_realm, create_warm_boa_realm, ensure_realm_shards, - release_warm_boa_realm, try_acquire_pooled_boa_realm, WarmBoaRealm, BOA_ACTIVE_CAPS, - BOA_ACTIVE_TENANT, BOA_CHECKPOINT_STATS, BOA_CONTEXT_POOL, BOA_DET_STATE, BOA_DIRTY_SUBSYSTEMS, - BOA_EGRESS_SECRETS, BOA_ENV_MAP, BOA_EXEC_BINS, BOA_FETCH_MOCKS, BOA_FUEL_BUDGET, BOA_HTTP_REQ, - BOA_HTTP_RES, BOA_KV_MEM_BUDGET, BOA_LAST_CHILD_PROC_VIOLATION, BOA_NET_HOSTS, BOA_STDOUT, - BOA_VIOLATION, BOA_WAIT_UNTIL_COUNT, CHECKPOINT_SLAB, DIRTY_FETCH_MOCK, DIRTY_SOCKETS, - DIRTY_WASM, DIRTY_WEBSOCKET, DIRTY_WORKERS, + acquire_warm_boa_realm, call_realm_ctl, create_bare_boa_realm, create_warm_boa_realm, + ensure_realm_shards, eval_or_reuse_cached_script, has_process_exit, has_uncaught_error, + mark_exec_dirty, release_warm_boa_realm, try_acquire_pooled_boa_realm, WarmBoaRealm, + BOA_ACTIVE_CAPS, BOA_ACTIVE_TENANT, BOA_CHECKPOINT_STATS, BOA_CONTEXT_POOL, BOA_CUSTOM_ARGV, + BOA_DET_STATE, BOA_DIRTY_SUBSYSTEMS, BOA_EGRESS_SECRETS, BOA_ENV_MAP, BOA_EXEC_BINS, + BOA_EXEC_DIRTY, BOA_FETCH_MOCKS, BOA_FUEL_BUDGET, BOA_HTTP_REQ, BOA_HTTP_RES, + BOA_KV_MEM_BUDGET, BOA_LAST_CHILD_PROC_VIOLATION, BOA_LAST_EXIT_CODE, BOA_NET_HOSTS, + BOA_PROCESS_EXIT, BOA_STDOUT, BOA_UNCAUGHT_ERROR, BOA_UNHANDLED_REJECTIONS, BOA_VIOLATION, + BOA_WAIT_UNTIL_COUNT, CHECKPOINT_SLAB, DIRTY_FETCH_MOCK, DIRTY_SOCKETS, DIRTY_WASM, + DIRTY_WEBSOCKET, DIRTY_WORKERS, EXEC_DIRTY_ARGV, EXEC_DIRTY_CHILD_PROC, EXEC_DIRTY_EXIT, + EXEC_DIRTY_REJECTIONS, EXEC_DIRTY_UNCAUGHT, REALM_CTL_DISPATCH_HTTP_BRIDGE, REALM_CTL_RESET_MT, + REALM_CTL_RESET_WU, REALM_CTL_SET_DET_MODE, REALM_CTL_SET_NEXT_TICK, REALM_CTL_SYNC_ENV, }; use crate::boacas::{ BOACAS_FLAG_HAS_HTTP_BRIDGE, BOACAS_FLAG_HAS_KV_SANDBOX, BOACAS_FLAG_HAS_NEXT_TICK, @@ -96,9 +101,7 @@ impl SliceIsolate { BOA_CHECKPOINT_STATS.with(|s| s.set((0, 0, 0))); BOA_DIRTY_SUBSYSTEMS.with(|d| d.set(0)); if BOA_WAIT_UNTIL_COUNT.with(|c| c.get()) > 0 { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"if(globalThis.__slice_wu)globalThis.__slice_wu.length=0;", - )); + call_realm_ctl(&mut realm, REALM_CTL_RESET_WU, false); } BOA_STDOUT.with(|out| out.borrow_mut().clear()); BOA_HTTP_RES.with(|res| *res.borrow_mut() = None); @@ -172,9 +175,9 @@ impl SliceIsolate { CHECKPOINT_SLAB.with(|s| s.borrow_mut().clear()); BOA_CHECKPOINT_STATS.with(|s| s.set((0, 0, 0))); BOA_DIRTY_SUBSYSTEMS.with(|d| d.set(0)); - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"globalThis.__slice_wu.length=0;", - )); + if BOA_WAIT_UNTIL_COUNT.with(|c| c.get()) > 0 { + call_realm_ctl(&mut realm, REALM_CTL_RESET_WU, false); + } BOA_STDOUT.with(|out| out.borrow_mut().clear()); BOA_HTTP_RES.with(|res| *res.borrow_mut() = None); BOA_WAIT_UNTIL_COUNT.with(|c| c.set(0)); @@ -195,10 +198,29 @@ impl SliceIsolate { BOA_STDOUT.with(|out| out.borrow_mut().clear()); BOA_VIOLATION.with(|v| *v.borrow_mut() = None); BOA_DIRTY_SUBSYSTEMS.with(|d| d.set(0)); - crate::boa_realm::BOA_PROCESS_EXIT.with(|e| e.set(None)); - crate::boa_realm::BOA_LAST_EXIT_CODE.with(|e| e.set(None)); - crate::boa_realm::BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); - crate::boa_realm::BOA_UNCAUGHT_ERROR.with(|e| *e.borrow_mut() = None); + let stale_exec_dirty = BOA_EXEC_DIRTY.with(|c| c.replace(0)); + if stale_exec_dirty != 0 { + if (stale_exec_dirty & EXEC_DIRTY_EXIT) != 0 { + BOA_PROCESS_EXIT.with(|e| e.set(None)); + BOA_LAST_EXIT_CODE.with(|e| e.set(None)); + } + if (stale_exec_dirty & EXEC_DIRTY_REJECTIONS) != 0 { + BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); + } + if (stale_exec_dirty & EXEC_DIRTY_UNCAUGHT) != 0 { + BOA_UNCAUGHT_ERROR.with(|e| *e.borrow_mut() = None); + } + if (stale_exec_dirty & EXEC_DIRTY_CHILD_PROC) != 0 { + BOA_LAST_CHILD_PROC_VIOLATION.with(|v| *v.borrow_mut() = None); + } + if (stale_exec_dirty & EXEC_DIRTY_ARGV) != 0 { + BOA_CUSTOM_ARGV.with(|a| *a.borrow_mut() = None); + } + } + if !self.process_argv.is_empty() { + mark_exec_dirty(EXEC_DIRTY_ARGV); + BOA_CUSTOM_ARGV.with(|a| *a.borrow_mut() = Some(self.process_argv.clone())); + } BOA_ACTIVE_TENANT.with(|t| { let mut b = t.borrow_mut(); b.clear(); @@ -291,7 +313,6 @@ impl SliceIsolate { *b.borrow_mut() = self.compartment.capabilities.allowed_exec_binaries.clone(); }); } - BOA_LAST_CHILD_PROC_VIOLATION.with(|v| *v.borrow_mut() = None); BoaSessionFlags { has_fs_restrictions, @@ -325,16 +346,9 @@ impl SliceIsolate { has_next_tick: bool, ) { if self.deterministic_seed.is_some() { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_det_mode(false);", - )); + call_realm_ctl(realm, REALM_CTL_SET_DET_MODE, false); BOA_DET_STATE.with(|s| s.set(None)); } - if !self.process_argv.is_empty() { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"globalThis.__slice_argv=undefined;if(globalThis.process)globalThis.process.argv=[\"slice\"];", - )); - } if flags.has_fs_restrictions { BOA_ACTIVE_CAPS.with(|c| *c.borrow_mut() = None); } @@ -345,18 +359,14 @@ impl SliceIsolate { BOA_EGRESS_SECRETS.with(|s| s.borrow_mut().clear()); } if flags.has_env_keys { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_sync_process_env(false);", - )); + call_realm_ctl(realm, REALM_CTL_SYNC_ENV, false); BOA_ENV_MAP.with(|m| m.borrow_mut().clear()); } if flags.has_exec_bins { BOA_EXEC_BINS.with(|b| b.borrow_mut().clear()); } if has_next_tick { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_next_tick_hook(false);", - )); + call_realm_ctl(realm, REALM_CTL_SET_NEXT_TICK, false); } let dirty = BOA_DIRTY_SUBSYSTEMS.with(|d| d.replace(0)); if (dirty & DIRTY_FETCH_MOCK) != 0 { @@ -404,9 +414,8 @@ impl SliceIsolate { check_ses: bool, mut eval_res: boa_engine::JsResult, ) -> Result { - let last_cp_violation = BOA_LAST_CHILD_PROC_VIOLATION.with(|v| v.borrow_mut().take()); - if eval_res.is_err() { - if let Some(cp_v) = last_cp_violation { + if eval_res.is_err() && (BOA_EXEC_DIRTY.with(|c| c.get()) & EXEC_DIRTY_CHILD_PROC) != 0 { + if let Some(cp_v) = BOA_LAST_CHILD_PROC_VIOLATION.with(|v| v.borrow_mut().take()) { BOA_VIOLATION.with(|v| { if v.borrow().is_none() { *v.borrow_mut() = Some(cp_v); @@ -415,19 +424,19 @@ impl SliceIsolate { } } - if crate::boa_realm::BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { let _ = realm.ctx.run_jobs(); - crate::boa_realm::BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); + if (BOA_EXEC_DIRTY.with(|c| c.get()) & EXEC_DIRTY_REJECTIONS) != 0 { + BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); + } eval_res = Ok(boa_engine::JsValue::undefined()); } else if let Err(err) = eval_res { - let _ = realm - .ctx - .eval(boa_engine::Source::from_bytes(b"__slice_reset_mt();")); + call_realm_ctl(&mut realm, REALM_CTL_RESET_MT, false); if BOA_VIOLATION.with(|v| v.borrow().is_none()) && crate::event_loop::handle_uncaught_js_error(err, &mut realm.ctx) { eval_res = Ok(boa_engine::JsValue::undefined()); - if crate::boa_realm::BOA_PROCESS_EXIT.with(|e| e.get().is_none()) + if !has_process_exit() && (!BOA_HTTP_REQ.with(|r| r.borrow().active) || BOA_HTTP_RES.with(|res| res.borrow().is_none()) || has_pending_event_loop_work()) @@ -436,7 +445,9 @@ impl SliceIsolate { } } else { let _ = realm.ctx.run_jobs(); - crate::boa_realm::BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); + if (BOA_EXEC_DIRTY.with(|c| c.get()) & EXEC_DIRTY_REJECTIONS) != 0 { + BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); + } eval_res = Ok(boa_engine::JsValue::undefined()); } } else if !BOA_HTTP_REQ.with(|r| r.borrow().active) @@ -447,13 +458,11 @@ impl SliceIsolate { } if is_http_req - && crate::boa_realm::BOA_PROCESS_EXIT.with(|e| e.get().is_none()) - && crate::boa_realm::BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_none()) + && !has_process_exit() + && !has_uncaught_error() && BOA_HTTP_RES.with(|res| res.borrow().is_none()) { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"if(globalThis.__slice_active_http_server&&typeof globalThis.__slice_active_http_server._dispatchActiveHttpBridge==='function'){globalThis.__slice_active_http_server._dispatchActiveHttpBridge();}", - )); + call_realm_ctl(&mut realm, REALM_CTL_DISPATCH_HTTP_BRIDGE, false); drive_event_loop_to_completion(&mut realm.ctx); } clear_event_loop_state(); @@ -502,8 +511,7 @@ impl SliceIsolate { .unwrap_or_default(); if st == 1 { val = tla_v; - } else if crate::boa_realm::BOA_PROCESS_EXIT.with(|e| e.get().is_none()) - { + } else if !has_process_exit() { let tla_err = boa_engine::JsError::from_opaque(tla_v); let _ = crate::event_loop::handle_uncaught_js_error( tla_err, @@ -528,17 +536,40 @@ impl SliceIsolate { self.teardown_boa_compartment_thread_locals(&mut realm, flags, has_next_tick); self.harvest_boa_stdout(); let (cp_taken, cp_restored, cp_restore_ns) = - crate::boa_realm::BOA_CHECKPOINT_STATS.with(|s| s.replace((0, 0, 0))); + BOA_CHECKPOINT_STATS.with(|s| s.replace((0, 0, 0))); self.checkpoints_taken = cp_taken; self.restores_performed = cp_restored; self.restore_time_ns = cp_restore_ns; - let exit_code_opt = crate::boa_realm::BOA_PROCESS_EXIT - .with(|e| e.replace(None)) - .or_else(|| crate::boa_realm::BOA_LAST_EXIT_CODE.with(|e| e.replace(None))); - self.last_exit_code = exit_code_opt; - let uncaught_err_opt = crate::boa_realm::BOA_UNCAUGHT_ERROR.with(|e| e.borrow_mut().take()); - crate::boa_realm::BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); + let final_exec_dirty = BOA_EXEC_DIRTY.with(|c| c.replace(0)); + let (exit_code_opt, uncaught_err_opt) = if final_exec_dirty == 0 { + self.last_exit_code = None; + (None, None) + } else { + if (final_exec_dirty & EXEC_DIRTY_ARGV) != 0 { + BOA_CUSTOM_ARGV.with(|a| *a.borrow_mut() = None); + } + if (final_exec_dirty & EXEC_DIRTY_CHILD_PROC) != 0 { + BOA_LAST_CHILD_PROC_VIOLATION.with(|v| *v.borrow_mut() = None); + } + let exit_opt = if (final_exec_dirty & EXEC_DIRTY_EXIT) != 0 { + BOA_PROCESS_EXIT + .with(|e| e.replace(None)) + .or_else(|| BOA_LAST_EXIT_CODE.with(|e| e.replace(None))) + } else { + None + }; + self.last_exit_code = exit_opt; + let err_opt = if (final_exec_dirty & EXEC_DIRTY_UNCAUGHT) != 0 { + BOA_UNCAUGHT_ERROR.with(|e| e.borrow_mut().take()) + } else { + None + }; + if (final_exec_dirty & EXEC_DIRTY_REJECTIONS) != 0 { + BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); + } + (exit_opt, err_opt) + }; if let Some(mut violation) = BOA_VIOLATION.with(|v| v.borrow_mut().take()) { if let SandboxViolation::CpuFuelExhausted { ref mut limit, .. } = violation { @@ -634,39 +665,6 @@ impl SliceIsolate { result } - #[inline] - fn apply_process_argv_to_realm(&self, realm: &mut WarmBoaRealm) { - if self.process_argv.is_empty() { - return; - } - let argv_arr = boa_engine::object::builtins::JsArray::from_iter( - self.process_argv - .iter() - .map(|s| boa_engine::JsValue::from(boa_engine::js_string!(s.as_str()))), - &mut realm.ctx, - ); - let _ = realm.ctx.global_object().set( - boa_engine::js_string!("__slice_argv"), - boa_engine::JsValue::from(argv_arr.clone()), - false, - &mut realm.ctx, - ); - if let Some(proc_obj) = realm - .ctx - .global_object() - .get(boa_engine::js_string!("process"), &mut realm.ctx) - .ok() - .and_then(|v| v.as_object()) - { - let _ = proc_obj.set( - boa_engine::js_string!("argv"), - boa_engine::JsValue::from(argv_arr), - false, - &mut realm.ctx, - ); - } - } - /// Executes full ES2024+ JavaScript inside the production **Boa (`boa_engine`)** ECMAScript VM, /// reusing pre-warmed contexts from `BOA_CONTEXT_POOL`, capturing `console.log` / `print` output /// via zero-eval native host hooks, and enforcing SES compartment limits. @@ -682,24 +680,17 @@ impl SliceIsolate { } let mut realm = acquire_warm_boa_realm(); - self.apply_process_argv_to_realm(&mut realm); if flags.has_env_keys { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_sync_process_env(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SYNC_ENV, true); } if self.deterministic_seed.is_some() { crate::host_bindings::register_deterministic_host_functions(&mut realm.ctx); - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_det_mode(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SET_DET_MODE, true); } let has_next_tick = js_code.contains("nextTick"); if has_next_tick { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_next_tick_hook(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SET_NEXT_TICK, true); } if flags.is_worker { ensure_realm_shards(&mut realm, (1 << 8) | (1 << 13) | (1 << 2), false); @@ -789,9 +780,7 @@ impl SliceIsolate { needs_lazy_global_getters(js_code), ); self.apply_boa_realm_runtime_limits(&mut realm); - realm - .ctx - .eval(boa_engine::Source::from_bytes(js_code.as_bytes())) + eval_or_reuse_cached_script(&mut realm, js_code) } else { ensure_realm_shards( &mut realm, @@ -804,9 +793,7 @@ impl SliceIsolate { } else { format!("{{{}\n}}", js_code) }; - realm - .ctx - .eval(boa_engine::Source::from_bytes(scoped_code.as_bytes())) + eval_or_reuse_cached_script(&mut realm, &scoped_code) }; let need_ses_scan = should_check_ses || BOA_WAIT_UNTIL_COUNT.with(|c| c.get()) > 0; @@ -849,7 +836,6 @@ impl SliceIsolate { Some(r) => (r, false), None => (create_bare_boa_realm(), true), }; - self.apply_process_argv_to_realm(&mut realm); let has_next_tick = (header.feature_flags & BOACAS_FLAG_HAS_NEXT_TICK) != 0; if is_cold_bare_realm && header.approach_kind >= 1 && !precompiled_slice.is_empty() { @@ -880,26 +866,18 @@ impl SliceIsolate { } } else { if is_cold_bare_realm { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - crate::js_preludes::ULTRA_CORE_PRELUDE, - )); + let _ = crate::js_preludes::eval_ultra_core_prelude(&mut realm.ctx); crate::boa_realm::populate_realm_cached_handles(&mut realm); } if flags.has_env_keys { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_sync_process_env(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SYNC_ENV, true); } if self.deterministic_seed.is_some() { crate::host_bindings::register_deterministic_host_functions(&mut realm.ctx); - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_det_mode(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SET_DET_MODE, true); } if has_next_tick { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_next_tick_hook(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SET_NEXT_TICK, true); } if flags.is_worker { ensure_realm_shards(&mut realm, (1 << 8) | (1 << 13) | (1 << 2), false); diff --git a/crates/slice-engine/src/isolate/exec_bytecode.rs b/crates/slice-engine/src/isolate/exec_bytecode.rs index 3156eca..bd155b7 100644 --- a/crates/slice-engine/src/isolate/exec_bytecode.rs +++ b/crates/slice-engine/src/isolate/exec_bytecode.rs @@ -11,12 +11,15 @@ use slice_sandbox::SandboxViolation; use std::time::Instant; impl SliceIsolate { - /// Executes pre-compiled `SLICEBC\x01`, `SLICEBOA`, or `SLICESNP` bytecode directly from an in-memory or `mmap` CAS slice. - pub fn execute_bytecode( + /// Internal zero-clone execution core shared by `execute_bytecode` and `execute_http_request_fast`. + /// When `need_return_str` is `false` and `egress_audit_secrets` is empty, skips formatting `last_val` + /// into a heap `String` (saving `"undefined".to_string()` on every `Slice.respond` HTTP request). + pub(crate) fn execute_bytecode_core( &mut self, bytecode: &[u8], cas: Option<&MappedCasArchive>, - ) -> Result { + need_return_str: bool, + ) -> Result<(u64, u64, String), SandboxViolation> { let start = Instant::now(); self.compartment.pkey_domain.enter_domain(); @@ -55,8 +58,18 @@ impl SliceIsolate { let js_code = std::str::from_utf8(&bytecode[8..]).unwrap_or_default(); self.exec_boa_full_es_vm(js_code)? }; - let ret_str = last_val.to_string(); - if !self.egress_audit_secrets.is_empty() { + let has_secrets = !self.egress_audit_secrets.is_empty(); + let has_custom_http_res = + !need_return_str && BOA_HTTP_RES.with(|res| res.borrow().is_some()); + let ret_str = if need_return_str + || has_secrets + || (!has_custom_http_res && self.stdout.is_empty()) + { + last_val.to_string() + } else { + String::new() + }; + if has_secrets { for line in &self.stdout { self.verify_egress_not_leaked(line)?; } @@ -75,25 +88,7 @@ impl SliceIsolate { })?; } let total_ns = start.elapsed().as_nanos() as u64; - let exec_ns = total_ns.saturating_sub(instantiate_ns).max(1); - return Ok(ExecutionMetrics { - tenant_id: self.compartment.tenant_id.clone(), - highest_tier_reached: self.current_tier, - instantiate_time_ns: instantiate_ns, - execution_time_ns: exec_ns, - total_time_ns: total_ns, - fuel_consumed: self.compartment.fuel_consumed, - memory_used_bytes: self.compartment.memory_used_bytes, - pkey_domain: self.compartment.pkey_domain.pkey, - cas_modules_resolved: self.cas_modules_resolved, - os_stat_syscalls: 0, - stdout: self.stdout.clone(), - return_value: ret_str, - checkpoints_taken: self.checkpoints_taken, - restores_performed: self.restores_performed, - restore_time_ns: self.restore_time_ns, - exit_code: self.last_exit_code, - }); + return Ok((instantiate_ns, total_ns, ret_str)); } let module = decode_slicesnp_cached(bytecode); @@ -287,13 +282,17 @@ impl SliceIsolate { } let total_ns = start.elapsed().as_nanos() as u64; - let exec_ns = total_ns.saturating_sub(instantiate_ns).max(1); if self.capture_return_json && self.last_return_json.is_none() { self.last_return_json = crate::value_and_ast::js_value_to_optional_json_string(&last_val); } - let ret_str = last_val.to_string(); - if !self.egress_audit_secrets.is_empty() { + let has_secrets = !self.egress_audit_secrets.is_empty(); + let ret_str = if need_return_str || has_secrets || self.stdout.is_empty() { + last_val.to_string() + } else { + String::new() + }; + if has_secrets { for line in &self.stdout { self.verify_egress_not_leaked(line)?; } @@ -303,6 +302,18 @@ impl SliceIsolate { } } + Ok((instantiate_ns, total_ns, ret_str)) + } + + /// Executes pre-compiled `SLICEBC\x01`, `SLICEBOA`, or `SLICESNP` bytecode directly from an in-memory or `mmap` CAS slice. + pub fn execute_bytecode( + &mut self, + bytecode: &[u8], + cas: Option<&MappedCasArchive>, + ) -> Result { + let (instantiate_ns, total_ns, ret_str) = + self.execute_bytecode_core(bytecode, cas, true)?; + let exec_ns = total_ns.saturating_sub(instantiate_ns).max(1); Ok(ExecutionMetrics { tenant_id: self.compartment.tenant_id.clone(), highest_tier_reached: self.current_tier, diff --git a/crates/slice-engine/src/isolate/http_and_ws.rs b/crates/slice-engine/src/isolate/http_and_ws.rs index a9e62db..827fc3e 100644 --- a/crates/slice-engine/src/isolate/http_and_ws.rs +++ b/crates/slice-engine/src/isolate/http_and_ws.rs @@ -2,11 +2,13 @@ //! Task Draining (`drain_wait_until_tasks`), and Server WebSocket Frame Dispatch (`execute_websocket_event`). use crate::boa_realm::{ - acquire_warm_boa_realm, ensure_realm_shards, BOA_HTTP_REQ, BOA_HTTP_RES, BOA_WAIT_UNTIL_COUNT, + acquire_warm_boa_realm, call_realm_ctl, ensure_realm_shards, BOA_HTTP_REQ, BOA_HTTP_RES, + BOA_WAIT_UNTIL_COUNT, REALM_CTL_SET_DET_MODE, REALM_CTL_SYNC_ENV, }; use crate::isolate::{ExecutionMetrics, SliceIsolate}; use slice_cas::MappedCasArchive; use slice_sandbox::SandboxViolation; +use std::borrow::Cow; /// Zero-copy HTTP/1.1 request view borrowed directly from the worker thread's 64 KB socket read buffer. #[derive(Debug, Clone, Copy)] @@ -24,12 +26,55 @@ pub struct HttpRequestContext<'a> { pub struct HttpExecutionOutcome { pub metrics: ExecutionMetrics, pub status_code: u16, - pub content_type: String, + pub content_type: Cow<'static, str>, pub response_body: String, pub response_headers: Vec<(String, String)>, pub wait_until_count: usize, } +/// Zero-clone HTTP outcome used on the hot `slice serve` worker path (`execute_http_request_fast`). +#[derive(Debug, Clone)] +pub struct HttpFastOutcome { + pub total_time_ns: u64, + pub fuel_consumed: u64, + pub status_code: u16, + pub content_type: Cow<'static, str>, + pub response_body: String, + pub response_headers: Vec<(String, String)>, + pub wait_until_count: usize, +} + +#[inline] +fn populate_boa_http_req(req: &HttpRequestContext<'_>) { + BOA_HTTP_REQ.with(|r| { + let mut borrow = r.borrow_mut(); + borrow.active = true; + borrow.method.clear(); + borrow.method.push_str(req.method); + borrow.path.clear(); + borrow.path.push_str(req.path); + borrow.query.clear(); + borrow.query.push_str(req.query); + borrow.tenant_id.clear(); + borrow.tenant_id.push_str(req.tenant_id); + borrow.body.clear(); + borrow.body.push_str(req.body); + borrow.headers_len = req.headers.len(); + for (idx, &(k, v)) in req.headers.iter().enumerate() { + if idx < borrow.headers.len() { + borrow.headers[idx].0.clear(); + borrow.headers[idx].0.push_str(k); + borrow.headers[idx].1.clear(); + borrow.headers[idx].1.push_str(v); + } else { + borrow.headers.push((k.to_string(), v.to_string())); + } + } + }); + BOA_HTTP_RES.with(|res| *res.borrow_mut() = None); + BOA_WAIT_UNTIL_COUNT.with(|c| c.set(0)); +} + impl SliceIsolate { /// Executes an HTTP request inside this `SliceIsolate` with zero-copy request metadata /// (`HttpRequestContext`), custom status/content-type response capture (`Slice.respond`), @@ -43,52 +88,24 @@ impl SliceIsolate { if bytecode.len() >= 8 && (&bytecode[0..8] == b"SLICEBOA" || &bytecode[0..8] == crate::boacas::BOACAS_MAGIC) { - BOA_HTTP_REQ.with(|r| { - let mut borrow = r.borrow_mut(); - borrow.active = true; - borrow.method.clear(); - borrow.method.push_str(req.method); - borrow.path.clear(); - borrow.path.push_str(req.path); - borrow.query.clear(); - borrow.query.push_str(req.query); - borrow.tenant_id.clear(); - borrow.tenant_id.push_str(req.tenant_id); - borrow.body.clear(); - borrow.body.push_str(req.body); - borrow.headers_len = req.headers.len(); - for (idx, &(k, v)) in req.headers.iter().enumerate() { - if idx < borrow.headers.len() { - borrow.headers[idx].0.clear(); - borrow.headers[idx].0.push_str(k); - borrow.headers[idx].1.clear(); - borrow.headers[idx].1.push_str(v); - } else { - borrow.headers.push((k.to_string(), v.to_string())); - } - } - }); - BOA_HTTP_RES.with(|res| *res.borrow_mut() = None); - BOA_WAIT_UNTIL_COUNT.with(|c| c.set(0)); - + populate_boa_http_req(req); let metrics_res = self.execute_bytecode(bytecode, cas); - BOA_HTTP_REQ.with(|r| r.borrow_mut().active = false); - let metrics = metrics_res?; + let mut metrics = metrics_res?; let custom_res = BOA_HTTP_RES.with(|res| res.borrow_mut().take()); let wait_until_count = BOA_WAIT_UNTIL_COUNT.with(|c| c.get()); let (status_code, content_type, response_body, response_headers) = if let Some((st, body, ct, hdrs)) = custom_res { - (st, ct, body, hdrs) + (st, Cow::Owned(ct), body, hdrs) } else { let body = if !metrics.stdout.is_empty() { metrics.stdout.join("\n") } else { - metrics.return_value.clone() + std::mem::take(&mut metrics.return_value) }; - (200, "application/json".to_string(), body, Vec::new()) + (200, Cow::Borrowed("application/json"), body, Vec::new()) }; return Ok(HttpExecutionOutcome { @@ -101,16 +118,76 @@ impl SliceIsolate { }); } - let metrics = self.execute_bytecode(bytecode, cas)?; + let mut metrics = self.execute_bytecode(bytecode, cas)?; let body = if !metrics.stdout.is_empty() { metrics.stdout.join("\n") } else { - metrics.return_value.clone() + std::mem::take(&mut metrics.return_value) }; Ok(HttpExecutionOutcome { metrics, status_code: 200, - content_type: "application/json".to_string(), + content_type: Cow::Borrowed("application/json"), + response_body: body, + response_headers: Vec::new(), + wait_until_count: 0, + }) + } + + /// Zero-clone HTTP request dispatcher for `slice serve` worker loops. + /// Avoids cloning `tenant_id`, `stdout`, `"application/json"`, and `"undefined"` on every request. + pub fn execute_http_request_fast( + &mut self, + bytecode: &[u8], + cas: Option<&MappedCasArchive>, + req: &HttpRequestContext<'_>, + ) -> Result { + if bytecode.len() >= 8 + && (&bytecode[0..8] == b"SLICEBOA" || &bytecode[0..8] == crate::boacas::BOACAS_MAGIC) + { + populate_boa_http_req(req); + let core_res = self.execute_bytecode_core(bytecode, cas, false); + BOA_HTTP_REQ.with(|r| r.borrow_mut().active = false); + let (_instantiate_ns, total_time_ns, ret_str) = core_res?; + + let custom_res = BOA_HTTP_RES.with(|res| res.borrow_mut().take()); + let wait_until_count = BOA_WAIT_UNTIL_COUNT.with(|c| c.get()); + + let (status_code, content_type, response_body, response_headers) = + if let Some((st, body, ct, hdrs)) = custom_res { + (st, Cow::Owned(ct), body, hdrs) + } else { + let body = if !self.stdout.is_empty() { + self.stdout.join("\n") + } else { + ret_str + }; + (200, Cow::Borrowed("application/json"), body, Vec::new()) + }; + + return Ok(HttpFastOutcome { + total_time_ns, + fuel_consumed: self.compartment.fuel_consumed, + status_code, + content_type, + response_body, + response_headers, + wait_until_count, + }); + } + + let (_instantiate_ns, total_time_ns, ret_str) = + self.execute_bytecode_core(bytecode, cas, false)?; + let body = if !self.stdout.is_empty() { + self.stdout.join("\n") + } else { + ret_str + }; + Ok(HttpFastOutcome { + total_time_ns, + fuel_consumed: self.compartment.fuel_consumed, + status_code: 200, + content_type: Cow::Borrowed("application/json"), response_body: body, response_headers: Vec::new(), wait_until_count: 0, @@ -131,15 +208,11 @@ impl SliceIsolate { let mut realm = acquire_warm_boa_realm(); if flags.has_env_keys { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_sync_process_env(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SYNC_ENV, true); } if self.deterministic_seed.is_some() { crate::host_bindings::register_deterministic_host_functions(&mut realm.ctx); - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_det_mode(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SET_DET_MODE, true); } self.apply_boa_realm_runtime_limits(&mut realm); @@ -187,31 +260,40 @@ impl SliceIsolate { ensure_realm_shards(&mut realm, (1 << 13) | (1 << 7), false); if flags.has_env_keys { - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_sync_process_env(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SYNC_ENV, true); } if self.deterministic_seed.is_some() { crate::host_bindings::register_deterministic_host_functions(&mut realm.ctx); - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - b"__slice_set_det_mode(true);", - )); + call_realm_ctl(&mut realm, REALM_CTL_SET_DET_MODE, true); } self.apply_boa_realm_runtime_limits(&mut realm); let prev_stdout_len = self.stdout.len(); - let js_call = format!( - "globalThis.__slice_dispatch_server_ws({}, {}, {}, {}, {});", - serde_json::to_string(event_type).unwrap_or_else(|_| "\"message\"".to_string()), - if is_binary { "true" } else { "false" }, - serde_json::to_string(&payload_arg).unwrap_or_else(|_| "\"\"".to_string()), - code, - serde_json::to_string(reason).unwrap_or_else(|_| "\"\"".to_string()), - ); - let eval_res = realm + let dispatch_fn = realm .ctx - .eval(boa_engine::Source::from_bytes(js_call.as_bytes())); + .global_object() + .get( + boa_engine::js_string!("__slice_dispatch_server_ws"), + &mut realm.ctx, + ) + .ok() + .and_then(|v| v.as_object()); + let eval_res = if let Some(fn_obj) = dispatch_fn { + fn_obj.call( + &boa_engine::JsValue::undefined(), + &[ + boa_engine::JsValue::from(boa_engine::js_string!(event_type)), + boa_engine::JsValue::from(is_binary), + boa_engine::JsValue::from(boa_engine::js_string!(payload_arg)), + boa_engine::JsValue::from(i32::from(code)), + boa_engine::JsValue::from(boa_engine::js_string!(reason)), + ], + &mut realm.ctx, + ) + } else { + Ok(boa_engine::JsValue::undefined()) + }; // Drive microtasks/timers before draining the server WebSocket outbox (since // `finish_boa_compartment_execution` clears thread-local WebSocket state on teardown). diff --git a/crates/slice-engine/src/isolate/mod.rs b/crates/slice-engine/src/isolate/mod.rs index 0e76092..bf77abf 100644 --- a/crates/slice-engine/src/isolate/mod.rs +++ b/crates/slice-engine/src/isolate/mod.rs @@ -17,7 +17,7 @@ pub(crate) mod http_and_ws; pub(crate) mod kv_and_sandbox; pub mod state_and_kv; -pub use self::http_and_ws::{HttpExecutionOutcome, HttpRequestContext}; +pub use self::http_and_ws::{HttpExecutionOutcome, HttpFastOutcome, HttpRequestContext}; pub use self::kv_and_sandbox::{SandboxEvalOptions, SandboxEvalOutcome}; use crate::parser_and_compiler::compile_source_to_bytecode; diff --git a/crates/slice-engine/src/lib.rs b/crates/slice-engine/src/lib.rs index 6e2f0d6..17d6730 100644 --- a/crates/slice-engine/src/lib.rs +++ b/crates/slice-engine/src/lib.rs @@ -17,7 +17,7 @@ //! and sandboxed `wasmi` [`wasm`] engine. //! - [`net`]: Outbound `fetch()` HTTP/1.1 & HTTPS engine ([`outbound_http`]), OCap TCP/TLS/UDP [`sockets`], //! and RFC 6455 [`websocket`] codec. -//! - [`preludes`]: Sharded JavaScript micro-preludes (`00_ultra_core.js` .. `18_intl.js`), Aho-Corasick shard +//! - [`preludes`]: Sharded JavaScript micro-preludes (`00_ultra_core.js` .. `19_process_cli.js`), Aho-Corasick shard //! detector ([`js_preludes`]), compile-time minifier ([`js_minifier`]), and lazy `node:*` built-ins ([`node_builtins`]). pub mod bindings; @@ -56,8 +56,8 @@ pub use event_loop::{ reset_virtual_time_warped_ms, virtual_time_warped_ms, MAX_FETCH_REACTOR_WORKERS, }; pub use isolate::{ - run_source_isolated, ExecutionMetrics, HttpExecutionOutcome, HttpRequestContext, - SandboxEvalOptions, SandboxEvalOutcome, SliceIsolate, + run_source_isolated, ExecutionMetrics, HttpExecutionOutcome, HttpFastOutcome, + HttpRequestContext, SandboxEvalOptions, SandboxEvalOutcome, SliceIsolate, }; pub use outbound_http::{ clear_outbound_conn_pool, clear_outbound_conn_pool_for_tenant, diff --git a/crates/slice-engine/src/preludes/00_ultra_core.js b/crates/slice-engine/src/preludes/00_ultra_core.js index 5079d4d..9ad9e24 100644 --- a/crates/slice-engine/src/preludes/00_ultra_core.js +++ b/crates/slice-engine/src/preludes/00_ultra_core.js @@ -31,7 +31,8 @@ (id === 15 && globalThis.FormData) || (id === 16 && globalThis.structuredClone) || (id === 17 && globalThis.Buffer && globalThis.Buffer.prototype._hasBinRW) || - (id === 18 && globalThis.Intl) + (id === 18 && globalThis.Intl) || + (id === 29 && globalThis.navigator) ) { globalThis.__shMask |= (1 << id); return; @@ -100,29 +101,16 @@ }; var __pExitCode = undefined; + var __argvCache = null; function __pLazy(m) { return function() { - __slice_mark_proc_dirty(); - __loadShard(18); + __slice_process_ctl(0); + __loadShard(29); return globalThis.process[m].apply(globalThis.process, arguments); }; } - globalThis.process = { - pid: 1, - env: { NODE_ENV: "production" }, - cwd: function() { return "."; }, - get platform() { return __slice_os_platform(); }, - get arch() { return __slice_os_arch(); }, - get exitCode() { return __pExitCode; }, - set exitCode(v) { - __pExitCode = v; - if (v !== undefined) __slice_mark_proc_dirty(); - }, - _resetExitCode: function() { __pExitCode = undefined; }, - version: "v24.0.0", - versions: { node: "24.0.0" }, - argv: globalThis.__slice_argv || ["slice"], + var __ProcProto = { on: __pLazy("on"), once: __pLazy("once"), off: __pLazy("off"), @@ -131,15 +119,54 @@ removeAllListeners: __pLazy("removeAllListeners"), listeners: __pLazy("listeners"), listenerCount: __pLazy("listenerCount"), - emitWarning: __pLazy("emitWarning"), - exit: function(code) { - __ntQ.length = 0; - __qmQ.length = 0; - __mtS = false; - __slice_process_exit(code); - } + emitWarning: __pLazy("emitWarning") }; + var __proc = Object.create(__ProcProto); + __proc.pid = 1; + __proc.env = { NODE_ENV: "production" }; + __proc.cwd = function() { return "."; }; + __proc._exited = false; + __proc._resetExitCode = function() { + __pExitCode = undefined; + __argvCache = null; + __proc._exited = false; + }; + __proc.version = "v24.0.0"; + __proc.versions = { node: "24.0.0" }; + __proc.exit = function(code) { + __ntQ.length = 0; + __qmQ.length = 0; + __mtS = false; + __slice_process_ctl(2, code); + }; + Object.defineProperties(__proc, { + platform: { get: __slice_os_platform, enumerable: true, configurable: true }, + arch: { get: __slice_os_arch, enumerable: true, configurable: true }, + exitCode: { + get: function() { return __pExitCode; }, + set: function(v) { + __pExitCode = v; + if (v !== undefined) __slice_process_ctl(0); + }, + enumerable: true, + configurable: true + }, + argv: { + get: function() { + if (!__argvCache) __argvCache = __slice_process_ctl(1); + return __argvCache; + }, + set: function(v) { + __slice_process_ctl(0); + __argvCache = v; + }, + enumerable: true, + configurable: true + } + }); + globalThis.process = __proc; + globalThis.__slice_check_ses = function() { var p = [Object.prototype, Array.prototype, Function.prototype, String.prototype]; var n = ["Object.prototype", "Array.prototype", "Function.prototype", "String.prototype"]; @@ -209,7 +236,8 @@ if (__ntQ.length > 0) { while (__ntQ.length > 0) { var n = __ntQ.shift(); - n.f.apply(undefined, n.a); + if (n.a) n.f.apply(undefined, n.a); + else n.f(); } } return onF(v); @@ -218,7 +246,8 @@ if (__ntQ.length > 0) { while (__ntQ.length > 0) { var n = __ntQ.shift(); - n.f.apply(undefined, n.a); + if (n.a) n.f.apply(undefined, n.a); + else n.f(); } } return onR(e); @@ -242,6 +271,27 @@ __mtS = false; }; + globalThis.__slice_ctl = function(op, flag) { + if (op === 0) { + __ntQ.length = 0; + __qmQ.length = 0; + __mtS = false; + } else if (op === 1) { + globalThis.__slice_set_det_mode(flag); + } else if (op === 2) { + globalThis.__slice_sync_process_env(flag); + } else if (op === 3) { + globalThis.__slice_set_next_tick_hook(flag); + } else if (op === 4) { + if (globalThis.__slice_wu) globalThis.__slice_wu.length = 0; + } else if (op === 5) { + var s = globalThis.__slice_active_http_server; + if (s && typeof s._dispatchActiveHttpBridge === "function") { + s._dispatchActiveHttpBridge(); + } + } + }; + globalThis.__slice_set_als_wrap = function(wrapFn) { __alsWrap = wrapFn || null; }; @@ -256,7 +306,8 @@ while (__ntQ.length > 0 || __qmQ.length > 0) { while (__ntQ.length > 0) { var n = __ntQ.shift(); - n.f.apply(undefined, n.a); + if (n.a) n.f.apply(undefined, n.a); + else n.f(); } if (__qmQ.length > 0) { var q = __qmQ.shift(); @@ -275,8 +326,11 @@ __ntHooked = true; Promise.prototype.then = __wrappedThen; } - var a = []; - for (var i = 1; i < arguments.length; i++) a.push(arguments[i]); + var a = undefined; + if (arguments.length > 1) { + a = []; + for (var i = 1; i < arguments.length; i++) a.push(arguments[i]); + } __ntQ.push({ f: __alsWrap ? __alsWrap(cb) : cb, a: a }); __schedMt(); }; @@ -295,19 +349,19 @@ } __Timeout.prototype.unref = function() { this._refed = false; - __slice_timer_ref(this._id, false); + __slice_timer_ctl(this._id, 2); return this; }; __Timeout.prototype.ref = function() { this._refed = true; - __slice_timer_ref(this._id, true); + __slice_timer_ctl(this._id, 1); return this; }; __Timeout.prototype.hasRef = function() { return this._refed; }; __Timeout.prototype.refresh = function() { - __slice_timer_refresh(this._id); + __slice_timer_ctl(this._id, 3); return this; }; __Timeout.prototype[Symbol.toPrimitive] = function() { @@ -318,17 +372,23 @@ }; globalThis.setTimeout = function(cb, ms) { - var a = []; - for (var i = 2; i < arguments.length; i++) a.push(arguments[i]); + var a = undefined; + if (arguments.length > 2) { + a = []; + for (var i = 2; i < arguments.length; i++) a.push(arguments[i]); + } return new __Timeout(__slice_timer_set(cb, Number(ms) || 0, false, a)); }; globalThis.clearTimeout = function(id) { if (id == null) return; - __slice_timer_clear(typeof id === "object" ? (id._id | 0) : (Number(id) || 0)); + __slice_timer_ctl(typeof id === "object" ? (id._id | 0) : (Number(id) || 0), 0); }; globalThis.setInterval = function(cb, ms) { - var a = []; - for (var i = 2; i < arguments.length; i++) a.push(arguments[i]); + var a = undefined; + if (arguments.length > 2) { + a = []; + for (var i = 2; i < arguments.length; i++) a.push(arguments[i]); + } return new __Timeout(__slice_timer_set(cb, Number(ms) || 0, true, a)); }; globalThis.clearInterval = globalThis.clearTimeout; @@ -336,8 +396,11 @@ if (typeof cb !== "function") { throw new TypeError("setImmediate requires a callback function"); } - var a = []; - for (var i = 1; i < arguments.length; i++) a.push(arguments[i]); + var a = undefined; + if (arguments.length > 1) { + a = []; + for (var i = 1; i < arguments.length; i++) a.push(arguments[i]); + } return new __Timeout(__slice_immediate_set(cb, a)); }; globalThis.clearImmediate = globalThis.clearTimeout; diff --git a/crates/slice-engine/src/preludes/03_streams_formdata.js b/crates/slice-engine/src/preludes/03_streams_formdata.js index 3287836..ef958ac 100644 --- a/crates/slice-engine/src/preludes/03_streams_formdata.js +++ b/crates/slice-engine/src/preludes/03_streams_formdata.js @@ -5,8 +5,8 @@ function ReadableStream(underlyingSource) { var self = this; this._chunks = []; - this._waiters = []; - this._closeWaiters = []; + this._waiters = null; + this._closeWaiters = null; this._closed = false; this._errored = null; this.locked = false; @@ -19,28 +19,36 @@ throw new RangeError("ReadableStream buffer limit exceeded (" + MAX_STREAM_CHUNKS + " chunks)"); } self._chunks.push(chunk); - if (self._waiters.length > 0) { + if (self._waiters && self._waiters.length > 0) { var w = self._waiters.shift(); w.res({ value: self._chunks[w.idx()], done: false }); } }, close: function() { self._closed = true; - while (self._waiters.length > 0) { - self._waiters.shift().res({ value: undefined, done: true }); + if (self._waiters) { + while (self._waiters.length > 0) { + self._waiters.shift().res({ value: undefined, done: true }); + } } - while (self._closeWaiters.length > 0) { - self._closeWaiters.shift().res(undefined); + if (self._closeWaiters) { + while (self._closeWaiters.length > 0) { + self._closeWaiters.shift().res(undefined); + } } }, error: function(e) { self._errored = e || new Error("ReadableStream error"); self._closed = true; - while (self._waiters.length > 0) { - self._waiters.shift().rej(self._errored); + if (self._waiters) { + while (self._waiters.length > 0) { + self._waiters.shift().rej(self._errored); + } } - while (self._closeWaiters.length > 0) { - self._closeWaiters.shift().rej(self._errored); + if (self._closeWaiters) { + while (self._closeWaiters.length > 0) { + self._closeWaiters.shift().rej(self._errored); + } } } }; @@ -135,7 +143,7 @@ } if (!self._closed) { return new Promise(function(res, rej) { - self._waiters.push({ + (self._waiters || (self._waiters = [])).push({ idx: function() { return idx++; }, res: res, rej: rej diff --git a/crates/slice-engine/src/preludes/05_full_buffer.js b/crates/slice-engine/src/preludes/05_full_buffer.js index 9923d3f..ced0c15 100644 --- a/crates/slice-engine/src/preludes/05_full_buffer.js +++ b/crates/slice-engine/src/preludes/05_full_buffer.js @@ -94,20 +94,7 @@ return Buffer.alloc(size); }; - Buffer.byteLength = function(str, encoding) { - if (typeof str !== "string") { - if (str && typeof str.byteLength === "number") return str.byteLength; - str = String(str); - } - if (!encoding) return __slice_utf8_byte_len(str); - var e = String(encoding).toLowerCase(); - if (e === "utf8" || e === "utf-8") return __slice_utf8_byte_len(str); - if (e === "utf16le" || e === "utf-16le" || e === "ucs2" || e === "ucs-2") return str.length * 2; - if (e === "latin1" || e === "binary" || e === "ascii") return str.length; - if (e === "hex") return str.length >>> 1; - if (e === "base64" || e === "base64url") return __slice_base64_decode_bytes(str).byteLength; - return __slice_utf8_byte_len(str); - }; + Buffer.byteLength = __slice_utf8_byte_len; Buffer.concat = function(list, totalLength) { if (!Array.isArray(list)) throw new TypeError("The \"list\" argument must be an instance of Array"); diff --git a/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js b/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js index 992d915..1b0781a 100644 --- a/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js +++ b/crates/slice-engine/src/preludes/11_fetch_headers_req_res.js @@ -396,10 +396,10 @@ this.bodyUsed = true; if (this._stream) { var st = this._stream, self = this; - st._drainSync(); + if (!st._closed) st._drainSync(); if (st._startPromise || !st._closed) { var waitP = st._startPromise ? st._startPromise : new Promise(function(res, rej) { - st._closeWaiters.push({ res: res, rej: rej }); + (st._closeWaiters || (st._closeWaiters = [])).push({ res: res, rej: rej }); }); return waitP.then(function() { self._body = st._toText(); diff --git a/crates/slice-engine/src/preludes/13_dom_events.js b/crates/slice-engine/src/preludes/13_dom_events.js index 08a73f6..1cc8d31 100644 --- a/crates/slice-engine/src/preludes/13_dom_events.js +++ b/crates/slice-engine/src/preludes/13_dom_events.js @@ -39,7 +39,7 @@ CustomEvent.prototype.constructor = CustomEvent; function EventTarget() { - this._et = Object.create(null); + this._et = null; } EventTarget.prototype._ensureEt = function() { if (!this._et) this._et = Object.create(null); @@ -158,17 +158,23 @@ this.message = message === undefined ? "" : String(message); this.name = name === undefined ? "Error" : String(name); this.code = __domCodes[this.name] || 0; - var err = new Error(this.message); - err.name = this.name; - if (err.stack) { - Object.defineProperty(this, "stack", { value: err.stack, writable: true, configurable: true }); - } } DOMException.prototype = Object.create(Error.prototype); DOMException.prototype.constructor = DOMException; - for (var __dk in __domConsts) { - DOMException[__dk] = DOMException.prototype[__dk] = __domConsts[__dk]; - } + Object.defineProperty(DOMException.prototype, "stack", { + get: function() { + var nm = this && this.name ? String(this.name) : "Error"; + var msg = this && this.message ? String(this.message) : ""; + return msg ? (nm + ": " + msg) : nm; + }, + set: function(v) { + Object.defineProperty(this, "stack", { value: v, writable: true, configurable: true }); + }, + configurable: true, + enumerable: false + }); + Object.assign(DOMException, __domConsts); + Object.assign(DOMException.prototype, __domConsts); globalThis.DOMException = DOMException; globalThis.Event = Event; diff --git a/crates/slice-engine/src/preludes/18_intl.js b/crates/slice-engine/src/preludes/18_intl.js index 90e0ac3..a497735 100644 --- a/crates/slice-engine/src/preludes/18_intl.js +++ b/crates/slice-engine/src/preludes/18_intl.js @@ -1,224 +1,5 @@ -// Slice (Nexus-JS) Prelude Shard 18: WinterTC `navigator`, `location`, `Intl`, and Complete `process` CLI Surface +// Slice (Nexus-JS) Prelude Shard 18: WinterTC `Intl` (`18_intl.js`) (function() { - var p = globalThis.process; - if (p && !p.stdout) { - p.ppid = 0; - p.argv0 = "slice"; - p.execArgv = []; - p.execPath = "/usr/bin/slice"; - var __t0 = Date.now(); - p.uptime = function() { - return Math.max(0, (Date.now() - __t0) / 1000); - }; - function __hrtime(prev) { - var ns = BigInt(Math.round(performance.now() * 1e6)); - if (Array.isArray(prev) && prev.length === 2) { - var pNs = BigInt(prev[0]) * 1000000000n + BigInt(prev[1]); - ns -= pNs; - if (ns < 0n) ns = 0n; - } - return [Number(ns / 1000000000n), Number(ns % 1000000000n)]; - } - __hrtime.bigint = function() { - return BigInt(Math.round(performance.now() * 1e6)); - }; - p.hrtime = __hrtime; - - function __memUsage() { - var used = __slice_http_is_active(1) || 0; - var rem = __slice_http_is_active(2) || 67108864; - var total = Math.min(used + rem, 134217728); - var heapUsed = Math.max(262144, used + 262144); - var heapTotal = Math.max(heapUsed, Math.min(total, 16777216)); - var rss = Math.max(heapTotal, 8388608); - return { - rss: rss, - heapTotal: heapTotal, - heapUsed: heapUsed, - external: used, - arrayBuffers: 0 - }; - } - __memUsage.rss = function() { - return __memUsage().rss; - }; - p.memoryUsage = __memUsage; - - function __mkWritable(fd) { - return { - fd: fd, - isTTY: false, - columns: 80, - rows: 24, - write: function(chunk, enc, cb) { - var fn = typeof enc === "function" ? enc : cb; - var s = (chunk instanceof Uint8Array) - ? __slice_buf_to_utf8(chunk) - : String(chunk === undefined ? "" : chunk); - if (s.endsWith("\r\n")) s = s.slice(0, -2); - else if (s.endsWith("\n")) s = s.slice(0, -1); - __slice_console_log(s); - if (typeof fn === "function") fn(null); - return true; - }, - end: function(chunk, enc, cb) { - var fn = typeof chunk === "function" ? chunk : (typeof enc === "function" ? enc : cb); - if (chunk !== undefined && chunk !== null && typeof chunk !== "function") { - this.write(chunk, enc); - } - if (typeof fn === "function") fn(); - return this; - }, - on: function() { return this; }, - once: function() { return this; }, - off: function() { return this; }, - removeListener: function() { return this; }, - emit: function() { return false; } - }; - } - p.stdout = __mkWritable(1); - p.stderr = __mkWritable(2); - p.stdin = { - fd: 0, - isTTY: false, - readable: false, - on: function(ev, cb) { - if (ev === "end" && typeof cb === "function") queueMicrotask(cb); - return this; - }, - once: function(ev, cb) { - if (ev === "end" && typeof cb === "function") queueMicrotask(cb); - return this; - }, - off: function() { return this; }, - removeListener: function() { return this; }, - resume: function() { return this; }, - pause: function() { return this; }, - setEncoding: function() { return this; }, - read: function() { return null; } - }; - - var __pEv = Object.create(null); - var __pEvCount = 0; - p._exited = false; - p.on = p.addListener = function(ev, fn) { - if (typeof fn === "function") { - __slice_mark_proc_dirty(); - var k = String(ev); - (__pEv[k] || (__pEv[k] = [])).push(fn); - __pEvCount++; - } - return p; - }; - p.once = function(ev, fn) { - if (typeof fn === "function") { - var g = function() { - p.off(ev, g); - fn.apply(p, arguments); - }; - g.listener = fn; - p.on(ev, g); - } - return p; - }; - p.off = p.removeListener = function(ev, fn) { - var k = String(ev), list = __pEv[k]; - if (list) { - var prevLen = list.length; - __pEv[k] = list.filter(function(f) { return f !== fn && f.listener !== fn; }); - __pEvCount = Math.max(0, __pEvCount - (prevLen - __pEv[k].length)); - } - return p; - }; - p.removeAllListeners = function(ev) { - if (arguments.length === 0) { - __pEv = Object.create(null); - __pEvCount = 0; - } else { - var k = String(ev); - if (__pEv[k]) { - __pEvCount = Math.max(0, __pEvCount - __pEv[k].length); - delete __pEv[k]; - } - } - return p; - }; - p.listeners = function(ev) { - return (__pEv[String(ev)] || []).slice(); - }; - p.listenerCount = function(ev) { - var l = __pEv[String(ev)]; - return l ? l.length : 0; - }; - p._hasListeners = function(ev) { - if (__pEvCount === 0) return false; - if (!ev) return true; - var l = __pEv[String(ev)]; - return Boolean(l && l.length > 0); - }; - p._resetProcessState = function() { - if (__pEvCount > 0) { - __pEv = Object.create(null); - __pEvCount = 0; - } - if (p._resetExitCode) p._resetExitCode(); - else p.exitCode = undefined; - p._exited = false; - }; - p.emit = function(ev) { - if (__pEvCount === 0) return false; - var list = __pEv[String(ev)]; - if (!list || list.length === 0) return false; - var args = []; - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - var snap = list.slice(); - for (var j = 0; j < snap.length; j++) snap[j].apply(p, args); - return true; - }; - p.emitWarning = function(warning, type, code) { - var msg = (warning && typeof warning === "object" && warning.message) - ? warning.message - : String(warning); - var t = typeof type === "string" - ? type - : (type && typeof type === "object" && type.type ? type.type : "Warning"); - var c = typeof code === "string" - ? code - : (type && typeof type === "object" && type.code ? type.code : undefined); - var w = new Error(msg); - w.name = t; - if (c) w.code = c; - p.emit("warning", w); - }; - } - - if (!globalThis.navigator) { - globalThis.navigator = { - userAgent: "Slice-NexusJS/0.10.0", - hardwareConcurrency: 4, - language: "en-US", - languages: ["en-US", "en"], - onLine: true, - platform: "Slice", - maxTouchPoints: 0 - }; - } - - if (!globalThis.location) { - globalThis.location = { - href: "http://localhost/", - origin: "http://localhost", - protocol: "http:", - host: "localhost", - hostname: "localhost", - port: "", - pathname: "/", - search: "", - hash: "", - toString: function() { return this.href; } - }; - } - function __normLocale(loc) { if (!loc) return "en-US"; var first = Array.isArray(loc) ? loc[0] : loc; diff --git a/crates/slice-engine/src/preludes/19_process_cli.js b/crates/slice-engine/src/preludes/19_process_cli.js new file mode 100644 index 0000000..c41182f --- /dev/null +++ b/crates/slice-engine/src/preludes/19_process_cli.js @@ -0,0 +1,221 @@ +// Slice (Nexus-JS) Prelude Shard 29: `navigator`, `location`, and Complete `process` CLI Surface (`19_process_cli.js`) +(function() { + var p = globalThis.process; + if (p && !p.stdout) { + p.ppid = 0; + p.argv0 = "slice"; + p.execArgv = []; + p.execPath = "/usr/bin/slice"; + var __t0 = Date.now(); + p.uptime = function() { + return Math.max(0, (Date.now() - __t0) / 1000); + }; + function __hrtime(prev) { + var ns = BigInt(Math.round(performance.now() * 1e6)); + if (Array.isArray(prev) && prev.length === 2) { + var pNs = BigInt(prev[0]) * 1000000000n + BigInt(prev[1]); + ns -= pNs; + if (ns < 0n) ns = 0n; + } + return [Number(ns / 1000000000n), Number(ns % 1000000000n)]; + } + __hrtime.bigint = function() { + return BigInt(Math.round(performance.now() * 1e6)); + }; + p.hrtime = __hrtime; + + function __memUsage() { + var used = __slice_http_is_active(1) || 0; + var rem = __slice_http_is_active(2) || 67108864; + var total = Math.min(used + rem, 134217728); + var heapUsed = Math.max(262144, used + 262144); + var heapTotal = Math.max(heapUsed, Math.min(total, 16777216)); + var rss = Math.max(heapTotal, 8388608); + return { + rss: rss, + heapTotal: heapTotal, + heapUsed: heapUsed, + external: used, + arrayBuffers: 0 + }; + } + __memUsage.rss = function() { + return __memUsage().rss; + }; + p.memoryUsage = __memUsage; + + function __mkWritable(fd) { + return { + fd: fd, + isTTY: false, + columns: 80, + rows: 24, + write: function(chunk, enc, cb) { + var fn = typeof enc === "function" ? enc : cb; + var s = (chunk instanceof Uint8Array) + ? __slice_buf_to_utf8(chunk) + : String(chunk === undefined ? "" : chunk); + if (s.endsWith("\r\n")) s = s.slice(0, -2); + else if (s.endsWith("\n")) s = s.slice(0, -1); + __slice_console_log(s); + if (typeof fn === "function") fn(null); + return true; + }, + end: function(chunk, enc, cb) { + var fn = typeof chunk === "function" ? chunk : (typeof enc === "function" ? enc : cb); + if (chunk !== undefined && chunk !== null && typeof chunk !== "function") { + this.write(chunk, enc); + } + if (typeof fn === "function") fn(); + return this; + }, + on: function() { return this; }, + once: function() { return this; }, + off: function() { return this; }, + removeListener: function() { return this; }, + emit: function() { return false; } + }; + } + p.stdout = __mkWritable(1); + p.stderr = __mkWritable(2); + p.stdin = { + fd: 0, + isTTY: false, + readable: false, + on: function(ev, cb) { + if (ev === "end" && typeof cb === "function") queueMicrotask(cb); + return this; + }, + once: function(ev, cb) { + if (ev === "end" && typeof cb === "function") queueMicrotask(cb); + return this; + }, + off: function() { return this; }, + removeListener: function() { return this; }, + resume: function() { return this; }, + pause: function() { return this; }, + setEncoding: function() { return this; }, + read: function() { return null; } + }; + + var __pEv = Object.create(null); + var __pEvCount = 0; + p._exited = false; + p.on = p.addListener = function(ev, fn) { + if (typeof fn === "function") { + __slice_process_ctl(0); + var k = String(ev); + (__pEv[k] || (__pEv[k] = [])).push(fn); + __pEvCount++; + } + return p; + }; + p.once = function(ev, fn) { + if (typeof fn === "function") { + var g = function() { + p.off(ev, g); + fn.apply(p, arguments); + }; + g.listener = fn; + p.on(ev, g); + } + return p; + }; + p.off = p.removeListener = function(ev, fn) { + var k = String(ev), list = __pEv[k]; + if (list) { + var prevLen = list.length; + __pEv[k] = list.filter(function(f) { return f !== fn && f.listener !== fn; }); + __pEvCount = Math.max(0, __pEvCount - (prevLen - __pEv[k].length)); + } + return p; + }; + p.removeAllListeners = function(ev) { + if (arguments.length === 0) { + __pEv = Object.create(null); + __pEvCount = 0; + } else { + var k = String(ev); + if (__pEv[k]) { + __pEvCount = Math.max(0, __pEvCount - __pEv[k].length); + delete __pEv[k]; + } + } + return p; + }; + p.listeners = function(ev) { + return (__pEv[String(ev)] || []).slice(); + }; + p.listenerCount = function(ev) { + var l = __pEv[String(ev)]; + return l ? l.length : 0; + }; + p._hasListeners = function(ev) { + if (__pEvCount === 0) return false; + if (!ev) return true; + var l = __pEv[String(ev)]; + return Boolean(l && l.length > 0); + }; + p._resetProcessState = function() { + if (__pEvCount > 0) { + __pEv = Object.create(null); + __pEvCount = 0; + } + if (p._resetExitCode) p._resetExitCode(); + else p.exitCode = undefined; + p._exited = false; + }; + p.emit = function(ev) { + if (__pEvCount === 0) return false; + var list = __pEv[String(ev)]; + if (!list || list.length === 0) return false; + var args = []; + for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); + var snap = list.slice(); + for (var j = 0; j < snap.length; j++) snap[j].apply(p, args); + return true; + }; + p.emitWarning = function(warning, type, code) { + var msg = (warning && typeof warning === "object" && warning.message) + ? warning.message + : String(warning); + var t = typeof type === "string" + ? type + : (type && typeof type === "object" && type.type ? type.type : "Warning"); + var c = typeof code === "string" + ? code + : (type && typeof type === "object" && type.code ? type.code : undefined); + var w = new Error(msg); + w.name = t; + if (c) w.code = c; + p.emit("warning", w); + }; + } + + if (!globalThis.navigator) { + globalThis.navigator = { + userAgent: "Slice-NexusJS/0.10.0", + hardwareConcurrency: 4, + language: "en-US", + languages: ["en-US", "en"], + onLine: true, + platform: "Slice", + maxTouchPoints: 0 + }; + } + + if (!globalThis.location) { + globalThis.location = { + href: "http://localhost/", + origin: "http://localhost", + protocol: "http:", + host: "localhost", + hostname: "localhost", + port: "", + pathname: "/", + search: "", + hash: "", + toString: function() { return this.href; } + }; + } +})(); diff --git a/crates/slice-engine/src/preludes/js_preludes.rs b/crates/slice-engine/src/preludes/js_preludes.rs index e356b30..758cd2f 100644 --- a/crates/slice-engine/src/preludes/js_preludes.rs +++ b/crates/slice-engine/src/preludes/js_preludes.rs @@ -52,20 +52,22 @@ pub const STRUCTURED_CLONE_PRELUDE_SRC: &str = include_str!("16_structured_clone pub const BUFFER_BINARY_RW_PRELUDE_SRC: &str = include_str!("17_buffer_binary_rw.js"); /// Human-readable source for Shard 18: `INTL_PRELUDE` (`src/preludes/18_intl.js`). pub const INTL_PRELUDE_SRC: &str = include_str!("18_intl.js"); +/// Human-readable source for Shard 29: `PROCESS_CLI_PRELUDE` (`src/preludes/19_process_cli.js`). +pub const PROCESS_CLI_PRELUDE_SRC: &str = include_str!("19_process_cli.js"); /// On-demand self-replacing lazy property getter registration (`__defLazy`) evaluated ONLY when /// `needs_lazy_global_getters(js_code)` is true (`globalThis.*` dynamic probes). -pub(crate) const LAZY_GETTERS_INIT_PRELUDE: &[u8] = br#"(function(){var __loadShard=globalThis.__slice_ensure_shard,__shardProps=globalThis.__shardProps,__shMask=globalThis.__shMask;globalThis.__slice_mark_lazy_inited();function __defLazy(names,shardId){__shardProps[shardId]=names;for(var i=0;i &'static [u8] { match shard_id { @@ -87,6 +89,7 @@ pub(crate) fn shard_prelude_bytes(shard_id: u32) -> &'static [u8] { 16 => STRUCTURED_CLONE_PRELUDE, 17 => BUFFER_BINARY_RW_PRELUDE, 18 => INTL_PRELUDE, + 29 => PROCESS_CLI_PRELUDE, _ => b"", } } @@ -217,7 +220,7 @@ pub(crate) fn build_fused_prelude_and_bundle( static ULTRA_CORE_SLICEBC: OnceLock> = OnceLock::new(); static LAZY_GETTERS_SLICEBC: OnceLock> = OnceLock::new(); -static SHARD_SLICEBC: [OnceLock>; 19] = [const { OnceLock::new() }; 19]; +static SHARD_SLICEBC: [OnceLock>; 30] = [const { OnceLock::new() }; 30]; #[inline] pub(crate) fn compile_static_js_to_slicebc(bytes: &[u8]) -> Vec { @@ -288,14 +291,14 @@ pub(crate) fn eval_lazy_getters_init_prelude( context.eval(boa_engine::Source::from_bytes(LAZY_GETTERS_INIT_PRELUDE)) } -/// Evaluates a compile-time minified lazy prelude shard (`1..=18`) on demand inside `context` +/// Evaluates a compile-time minified lazy prelude shard (`1..=18` or `29`) on demand inside `context` /// using cached precompiled `SLICEBC\x01` `CodeBlock` bytecode. #[inline] pub(crate) fn eval_lazy_prelude_shard( shard_id: u32, context: &mut boa_engine::Context, ) -> boa_engine::JsResult { - if !(1..=18).contains(&shard_id) { + if !((1..=18).contains(&shard_id) || shard_id == 29) { return Ok(boa_engine::JsValue::undefined()); } register_shard_host_functions_for_mask(1u32 << shard_id, context); @@ -366,11 +369,11 @@ const SHARD_PATTERNS: &[(&str, ShardTriggerAction)] = &[ ), ( "AbortController", - ShardTriggerAction::Mask((1 << 10) | (1 << 11) | (1 << 13) | (1 << 6)), + ShardTriggerAction::Mask((1 << 10) | (1 << 11) | (1 << 13)), ), ( "AbortSignal", - ShardTriggerAction::Mask((1 << 10) | (1 << 11) | (1 << 13) | (1 << 6)), + ShardTriggerAction::Mask((1 << 10) | (1 << 11) | (1 << 13)), ), // HTTP Request / Response / Headers (`1 << 11`) (".fetch(", ShardTriggerAction::Mask(1 << 11)), @@ -455,7 +458,11 @@ const SHARD_PATTERNS: &[(&str, ShardTriggerAction)] = &[ ("randomUUID", ShardTriggerAction::Mask(1 << 4)), ("webcrypto", ShardTriggerAction::Mask(1 << 4)), ("CryptoKey", ShardTriggerAction::Mask(1 << 4)), - ("crypto.", ShardTriggerAction::Mask(1 << 4)), + ("SubtleCrypto", ShardTriggerAction::Mask(1 << 4)), + ("typeof crypto", ShardTriggerAction::Mask(1 << 4)), + ("globalThis.crypto", ShardTriggerAction::Mask(1 << 4)), + ("window.crypto", ShardTriggerAction::Mask(1 << 4)), + ("self.crypto", ShardTriggerAction::Mask(1 << 4)), // structuredClone (`1 << 16`) ("structuredClone", ShardTriggerAction::Mask(1 << 16)), // Buffer & Binary R/W (`1 << 5`, `1 << 17`, & builtin `1 << 26`) @@ -584,45 +591,45 @@ const SHARD_PATTERNS: &[(&str, ShardTriggerAction)] = &[ ), // WebAssembly (`1 << 9`) ("WebAssembly", ShardTriggerAction::Mask(1 << 9)), - // Shard 18: WinterTC `Intl`, `navigator`, `location`, & Complete `process` CLI Surface (`1 << 18`) + // Shard 18: WinterTC `Intl` (`1 << 18`) ("Intl", ShardTriggerAction::Mask(1 << 18)), ("toLocaleString", ShardTriggerAction::Mask(1 << 18)), ("toLocaleDateString", ShardTriggerAction::Mask(1 << 18)), ("toLocaleTimeString", ShardTriggerAction::Mask(1 << 18)), ("localeCompare", ShardTriggerAction::Mask(1 << 18)), - ("navigator", ShardTriggerAction::Mask(1 << 18)), - ("location.", ShardTriggerAction::Mask(1 << 18)), - ("globalThis.location", ShardTriggerAction::Mask(1 << 18)), - ("stdout", ShardTriggerAction::Mask(1 << 18)), - ("stderr", ShardTriggerAction::Mask(1 << 18)), - ("stdin", ShardTriggerAction::Mask(1 << 18)), - ("memoryUsage", ShardTriggerAction::Mask(1 << 18)), - ("hrtime", ShardTriggerAction::Mask(1 << 18)), - ("uptime", ShardTriggerAction::Mask(1 << 18)), - ("emitWarning", ShardTriggerAction::Mask(1 << 18)), - ("exitCode", ShardTriggerAction::Mask(1 << 18)), - ("argv0", ShardTriggerAction::Mask(1 << 18)), - ("execPath", ShardTriggerAction::Mask(1 << 18)), - ("ppid", ShardTriggerAction::Mask(1 << 18)), - ("process.exit", ShardTriggerAction::Mask(1 << 18)), - ("process.on", ShardTriggerAction::Mask(1 << 18)), - ("process.once", ShardTriggerAction::Mask(1 << 18)), - ("process.off", ShardTriggerAction::Mask(1 << 18)), - ("process.emit", ShardTriggerAction::Mask(1 << 18)), - ("process.listeners", ShardTriggerAction::Mask(1 << 18)), - ("process.removeListener", ShardTriggerAction::Mask(1 << 18)), + // Shard 29: `navigator`, `location`, & Complete `process` CLI Surface (`1 << 29`) + ("navigator", ShardTriggerAction::Mask(1 << 29)), + ("location.", ShardTriggerAction::Mask(1 << 29)), + ("globalThis.location", ShardTriggerAction::Mask(1 << 29)), + ("stdout", ShardTriggerAction::Mask(1 << 29)), + ("stderr", ShardTriggerAction::Mask(1 << 29)), + ("stdin", ShardTriggerAction::Mask(1 << 29)), + ("memoryUsage", ShardTriggerAction::Mask(1 << 29)), + ("hrtime", ShardTriggerAction::Mask(1 << 29)), + ("uptime", ShardTriggerAction::Mask(1 << 29)), + ("emitWarning", ShardTriggerAction::Mask(1 << 29)), + ("argv0", ShardTriggerAction::Mask(1 << 29)), + ("execArgv", ShardTriggerAction::Mask(1 << 29)), + ("execPath", ShardTriggerAction::Mask(1 << 29)), + ("ppid", ShardTriggerAction::Mask(1 << 29)), + ("process.on", ShardTriggerAction::Mask(1 << 29)), + ("process.once", ShardTriggerAction::Mask(1 << 29)), + ("process.off", ShardTriggerAction::Mask(1 << 29)), + ("process.emit", ShardTriggerAction::Mask(1 << 29)), + ("process.listeners", ShardTriggerAction::Mask(1 << 29)), + ("process.removeListener", ShardTriggerAction::Mask(1 << 29)), ( "process.removeAllListeners", - ShardTriggerAction::Mask(1 << 18), - ), - ("process.addListener", ShardTriggerAction::Mask(1 << 18)), - ("process.listenerCount", ShardTriggerAction::Mask(1 << 18)), - ("unhandledRejection", ShardTriggerAction::Mask(1 << 18)), - ("uncaughtException", ShardTriggerAction::Mask(1 << 18)), - ("beforeExit", ShardTriggerAction::Mask(1 << 18)), - ("node:process", ShardTriggerAction::Mask(1 << 18)), - ("\"process\"", ShardTriggerAction::BuiltinMask(1 << 18)), - ("'process'", ShardTriggerAction::BuiltinMask(1 << 18)), + ShardTriggerAction::Mask(1 << 29), + ), + ("process.addListener", ShardTriggerAction::Mask(1 << 29)), + ("process.listenerCount", ShardTriggerAction::Mask(1 << 29)), + ("unhandledRejection", ShardTriggerAction::Mask(1 << 29)), + ("uncaughtException", ShardTriggerAction::Mask(1 << 29)), + ("beforeExit", ShardTriggerAction::Mask(1 << 29)), + ("node:process", ShardTriggerAction::Mask(1 << 29)), + ("\"process\"", ShardTriggerAction::BuiltinMask(1 << 29)), + ("'process'", ShardTriggerAction::BuiltinMask(1 << 29)), // Pre-fused `node:*` builtin module triggers (`19..=28`) ("node:crypto", ShardTriggerAction::BuiltinMask(1 << 19)), ("\"crypto\"", ShardTriggerAction::BuiltinMask(1 << 19)), @@ -824,13 +831,13 @@ pub(crate) fn detect_shards_and_boacas_flags( (flags, mask) } -/// Computes a bitmask of lazy prelude shards (`1..=18`) referenced by `raw_js_code` in a single +/// Computes a bitmask of lazy prelude shards (`1..=18` and `29`) referenced by `raw_js_code` in a single /// zero-allocation `O(N)` SIMD multi-pattern pass so top-level execution pre-loads only the shards /// actually used by a script before entering async/generator frames. #[inline] pub(crate) fn detect_needed_shards(raw_js_code: &str, is_http: bool) -> u32 { let (_, mask) = detect_shards_and_boacas_flags(raw_js_code, is_http, false); - mask & ((1 << 19) - 1) + (mask & ((1 << 19) - 1)) | (mask & (1 << 29)) } /// Returns `true` only when `js_code` may dynamically probe unreferenced `globalThis` shard properties diff --git a/crates/slice-engine/src/preludes/node_builtins.rs b/crates/slice-engine/src/preludes/node_builtins.rs index 27c576e..80bd21b 100644 --- a/crates/slice-engine/src/preludes/node_builtins.rs +++ b/crates/slice-engine/src/preludes/node_builtins.rs @@ -10,7 +10,7 @@ use std::sync::{Arc, OnceLock}; const BUILTIN_CRYPTO_SNIPPET: &[u8] = br#"(function(){var __U8=globalThis.Uint8Array,__ext=false;function __ensExt(){if(!__ext){__ext=true;__slice_init_crypto_ext();}}function __toBytes(d,enc){if(d instanceof __U8)return d;if(d instanceof ArrayBuffer)return new __U8(d);if(d&&d.buffer instanceof ArrayBuffer)return new __U8(d.buffer,d.byteOffset||0,d.byteLength);__slice_ensure_shard(5);return Buffer.from(String(d),enc||"utf8");}function __catBytes(chunks){if(chunks.length===0)return new __U8(0);if(chunks.length===1)return chunks[0];__slice_ensure_shard(5);return Buffer.concat(chunks);}function __encOut(rawBuf,enc){__slice_ensure_shard(5);var b=Buffer.isBuffer(rawBuf)?rawBuf:Buffer.from(rawBuf);return(!enc||enc==="buffer")?b:b.toString(enc);}function KeyObject(type,alg,crv,id,raw,meta,details){this.type=type;this.asymmetricKeyType=alg;this.asymmetricKeyDetails=details||(crv?{namedCurve:crv}:{});this._id=id||0;this._raw=raw||null;this._meta=meta||null;}KeyObject.prototype.export=function(opts){__ensExt();__slice_ensure_shard(5);var o=opts||{};var fmt=String(o.format||"der").toLowerCase();if(this.type==="secret")return Buffer.from(this._raw);var derB64=(this.type==="private")?(this._meta&&this._meta.pkcs8):(this._meta&&this._meta.spki);var der=derB64?Buffer.from(__slice_base64_decode_bytes(derB64)):Buffer.from(this._raw||[]);if(fmt==="pem"){var label=this.type==="private"?"PRIVATE KEY":"PUBLIC KEY";return"-----BEGIN "+label+"-----\n"+der.toString("base64")+"\n-----END "+label+"-----\n";}if(fmt==="jwk"&&this._meta){if(this.asymmetricKeyType==="ed25519"||this.asymmetricKeyType==="x25519"){var j={kty:"OKP",crv:this.asymmetricKeyType==="x25519"?"X25519":"Ed25519",x:this._meta.x};if(this.type==="private")j.d=this._meta.d;return j;}var je={kty:"EC",crv:this._meta.crv||"P-256",x:this._meta.x,y:this._meta.y};if(this.type==="private")je.d=this._meta.d;return je;}return der;};function __importDerKey(der,fmt){try{var impEd=JSON.parse(__slice_crypto_asym_import("Ed25519","",fmt,der));return new KeyObject(impEd.type,"ed25519",undefined,impEd.id,der,impEd);}catch(_e1){try{var impX=JSON.parse(__slice_crypto_asym_import("X25519","",fmt,der));return new KeyObject(impX.type,"x25519",undefined,impX.id,der,impX);}catch(_eX){try{var impRsa=JSON.parse(__slice_crypto_asym_import("RSA","",fmt,der));return new KeyObject(impRsa.type,"rsa",undefined,impRsa.id,der,impRsa,{modulusLength:2048,publicExponent:65537n});}catch(_eR){try{var impEc256=JSON.parse(__slice_crypto_asym_import("ECDSA","P-256",fmt,der));return new KeyObject(impEc256.type,"ec","P-256",impEc256.id,der,impEc256);}catch(_e2){var impEc384=JSON.parse(__slice_crypto_asym_import("ECDSA","P-384",fmt,der));return new KeyObject(impEc384.type,"ec","P-384",impEc384.id,der,impEc384);}}}}}function __parseKeyObj(k,isPriv){__ensExt();if(k instanceof KeyObject)return k;if(k&&typeof k==="object"&&k._id!==undefined&&k.algorithm){var kn=String(k.algorithm.name||"").toLowerCase();return new KeyObject(k.type,kn==="ecdsa"?"ec":kn,k.algorithm.namedCurve,k._id,k._raw,k._meta);}if(k&&typeof k==="object"&&k.key!==undefined)return __parseKeyObj(k.key,isPriv);var fmt=isPriv?"pkcs8":"spki";if(typeof k==="string"&&k.indexOf("-----BEGIN")!==-1){var body=k.replace(/-----BEGIN [^-]+-----/g,"").replace(/-----END [^-]+-----/g,"").replace(/\s+/g,"");var der=__slice_base64_decode_bytes(body);return __importDerKey(der,fmt);}return __importDerKey(__toBytes(k),fmt);}function __mkHash(a,isSha256,initChunks,initFast,initSBuf){var chunks=initChunks?initChunks.slice():[],strFast=initFast!==undefined?initFast:isSha256,sBuf=initSBuf||"";return{update:function(d,enc){if(strFast&&typeof d==="string"&&(!enc||enc==="utf8"||enc==="utf-8")&&chunks.length===0){sBuf+=d;}else{if(sBuf.length>0){__slice_ensure_shard(5);chunks.push(Buffer.from(sBuf,"utf8"));sBuf="";}strFast=false;chunks.push(__toBytes(d,enc));}return this;},copy:function(){return __mkHash(a,isSha256,chunks,strFast,sBuf);},digest:function(enc){if(isSha256&&(enc==="hex"||enc==="base64"||enc==="base64url")){if(strFast&&chunks.length===0){var h=__slice_crypto_sha256(sBuf,enc);sBuf="";return h;}if(sBuf.length===0&&chunks.length===1){var hb=__slice_crypto_sha256(chunks[0],enc);chunks=[];return hb;}}__ensExt();__slice_ensure_shard(5);if(sBuf.length>0){chunks.push(Buffer.from(sBuf,"utf8"));sBuf="";}var raw=Buffer.from(__slice_crypto_digest_bytes(a,__catBytes(chunks)));chunks=[];return(!enc||enc==="buffer")?raw:raw.toString(enc);}};}function __mkHmac(a,isSha256,key,initChunks,initFast,initSBuf){var kBytes=null,chunks=initChunks?initChunks.slice():[],strFast=initFast!==undefined?initFast:(isSha256&&typeof key==="string"),kStr=typeof key==="string"?key:"",sBuf=initSBuf||"";return{update:function(d,enc){if(strFast&&typeof d==="string"&&(!enc||enc==="utf8"||enc==="utf-8")&&chunks.length===0){sBuf+=d;}else{if(sBuf.length>0){__slice_ensure_shard(5);chunks.push(Buffer.from(sBuf,"utf8"));sBuf="";}strFast=false;chunks.push(__toBytes(d,enc));}return this;},copy:function(){return __mkHmac(a,isSha256,key,chunks,strFast,sBuf);},digest:function(enc){if(isSha256&&(enc==="hex"||enc==="base64"||enc==="base64url")){if(strFast&&chunks.length===0){var h=__slice_crypto_hmac_sha256(kStr,sBuf,enc);sBuf="";return h;}if(sBuf.length===0&&chunks.length===1){if(!kBytes)kBytes=(typeof key==="string")?key:__toBytes(key);var hb=__slice_crypto_hmac_sha256(kBytes,chunks[0],enc);chunks=[];return hb;}}__ensExt();__slice_ensure_shard(5);if(sBuf.length>0){chunks.push(Buffer.from(sBuf,"utf8"));sBuf="";}if(!kBytes)kBytes=__toBytes(key);var raw=Buffer.from(__slice_crypto_hmac_bytes(a,kBytes,__catBytes(chunks)));chunks=[];return(!enc||enc==="buffer")?raw:raw.toString(enc);}};}var m={KeyObject:KeyObject,createHash:function(alg){var a=String(alg||"sha256").toLowerCase(),isSha256=(a==="sha256"||a==="sha-256");return __mkHash(a,isSha256);},createHmac:function(alg,key){var a=String(alg||"sha256").toLowerCase(),isSha256=(a==="sha256"||a==="sha-256");return __mkHmac(a,isSha256,key);},randomBytes:function(size,cb){__ensExt();__slice_ensure_shard(5);var b=Buffer.from(__slice_crypto_random_bytes(Number(size)||0));if(typeof cb==="function"){cb(null,b);return;}return b;},randomFillSync:function(buf,offset,size){__ensExt();if(!buf||typeof buf.byteLength!=="number")throw new TypeError("buf must be an ArrayBufferView");var off=offset!==undefined?Number(offset):0;var sz=size!==undefined?Number(size):(buf.byteLength-off);if(off<0||sz<0||off+sz>buf.byteLength)throw new RangeError("offset or size out of bounds");var u8=new __U8(buf.buffer||buf,(buf.byteOffset||0)+off,sz);var rnd=__slice_crypto_random_bytes(sz);u8.set(rnd);return buf;},randomFill:function(buf,offset,size,cb){if(typeof offset==="function"){cb=offset;offset=0;size=buf.byteLength;}else if(typeof size==="function"){cb=size;size=buf.byteLength-Number(offset||0);}try{var r=m.randomFillSync(buf,offset,size);if(typeof cb==="function")queueMicrotask(function(){cb(null,r);});}catch(e){if(typeof cb==="function")queueMicrotask(function(){cb(e);});else throw e;}},randomInt:function(min,max,cb){__ensExt();if(typeof max==="function"||max===undefined){cb=max;max=min;min=0;}var lo=Math.ceil(Number(min)),hi=Math.floor(Number(max));if(!(hi>lo))throw new RangeError("max must be greater than min");var range=hi-lo,rb=__slice_crypto_random_bytes(4),u=((rb[0]<<24)>>>0)+((rb[1]<<16)>>>0)+((rb[2]<<8)>>>0)+(rb[3]>>>0);var val=lo+(u%range);if(typeof cb==="function"){queueMicrotask(function(){cb(null,val);});return;}return val;},randomUUID:function(){__ensExt();return __slice_crypto_random_uuid();},getRandomValues:function(ta){__ensExt();return __slice_crypto_get_random_values(ta);},timingSafeEqual:function(a,b){__ensExt();return __slice_crypto_timing_safe_equal(a,b);},pbkdf2Sync:function(password,salt,iterations,keylen,digest){__ensExt();__slice_ensure_shard(5);var ab=__slice_crypto_kdf("PBKDF2",String(digest||"sha256"),__toBytes(password),__toBytes(salt),null,Number(iterations),Number(keylen));return Buffer.from(ab);},pbkdf2:function(password,salt,iterations,keylen,digest,cb){if(typeof digest==="function"){cb=digest;digest="sha1";}try{var b=m.pbkdf2Sync(password,salt,iterations,keylen,digest);if(typeof cb==="function")queueMicrotask(function(){cb(null,b);});}catch(e){if(typeof cb==="function")queueMicrotask(function(){cb(e);});else throw e;}},hkdfSync:function(digest,ikm,salt,info,keylen){__ensExt();var ab=__slice_crypto_kdf("HKDF",String(digest||"sha256"),__toBytes(ikm),__toBytes(salt),__toBytes(info),1,Number(keylen));return ab;},hkdf:function(digest,ikm,salt,info,keylen,cb){try{var ab=m.hkdfSync(digest,ikm,salt,info,keylen);if(typeof cb==="function")queueMicrotask(function(){cb(null,ab);});}catch(e){if(typeof cb==="function")queueMicrotask(function(){cb(e);});else throw e;}},scryptSync:function(password,salt,keylen,options){__ensExt();__slice_ensure_shard(5);var o=options||{};var N=Number(o.N||o.cost||16384),r=Number(o.r||o.blockSize||8),p=Number(o.p||o.parallelization||1),maxmem=Number(o.maxmem||(32*1024*1024));var ab=__slice_crypto_kdf("SCRYPT","SHA-256",__toBytes(password),__toBytes(salt),null,N,Number(keylen),r,p,maxmem);return Buffer.from(ab);},scrypt:function(password,salt,keylen,options,cb){if(typeof options==="function"){cb=options;options={};}try{var b=m.scryptSync(password,salt,keylen,options);if(typeof cb==="function")queueMicrotask(function(){cb(null,b);});}catch(e){if(typeof cb==="function")queueMicrotask(function(){cb(e);});else throw e;}},createCipheriv:function(algorithm,key,iv,options){__ensExt();__slice_ensure_shard(5);var alg=String(algorithm||"").toLowerCase(),isGcm=alg.indexOf("gcm")!==-1,kB=__toBytes(key),ivB=__toBytes(iv),aadB=null,chunks=[],tagBuf=null,autoPad=true,tagLen=(options&&options.authTagLength)?Number(options.authTagLength)*8:128;var hid=__slice_crypto_key_register(isGcm?"AES-GCM":"AES-CBC","",kB);return{setAAD:function(buf){aadB=__toBytes(buf);return this;},setAutoPadding:function(ap){autoPad=(ap===undefined)?true:Boolean(ap);return this;},update:function(data,inEnc,outEnc){chunks.push(__toBytes(data,inEnc));return __encOut(new __U8(0),outEnc);},final:function(outEnc){var plain=__catBytes(chunks);chunks=[];var ab=__slice_crypto_cipher(isGcm?"AES-GCM":"AES-CBC",true,hid,kB,ivB,aadB,tagLen,plain,autoPad);var full=new __U8(ab);if(isGcm){var tBytes=tagLen/8;var cLen=full.byteLength-tBytes;tagBuf=Buffer.from(full.subarray(cLen));return __encOut(full.subarray(0,cLen),outEnc);}return __encOut(full,outEnc);},getAuthTag:function(){if(!isGcm||!tagBuf)throw new Error("ERR_CRYPTO_INVALID_STATE: getAuthTag requires finalized GCM cipher");return tagBuf;}};},createDecipheriv:function(algorithm,key,iv,options){__ensExt();__slice_ensure_shard(5);var alg=String(algorithm||"").toLowerCase(),isGcm=alg.indexOf("gcm")!==-1,kB=__toBytes(key),ivB=__toBytes(iv),aadB=null,chunks=[],authTag=null,autoPad=true,tagLen=(options&&options.authTagLength)?Number(options.authTagLength)*8:128;var hid=__slice_crypto_key_register(isGcm?"AES-GCM":"AES-CBC","",kB);return{setAAD:function(buf){aadB=__toBytes(buf);return this;},setAuthTag:function(buf,enc){authTag=__toBytes(buf,enc);return this;},setAutoPadding:function(ap){autoPad=(ap===undefined)?true:Boolean(ap);return this;},update:function(data,inEnc,outEnc){chunks.push(__toBytes(data,inEnc));return __encOut(new __U8(0),outEnc);},final:function(outEnc){var ciph=__catBytes(chunks);chunks=[];if(isGcm){if(!authTag)throw new Error("ERR_CRYPTO_INVALID_STATE: Unsupported state or unable to authenticate data (missing authTag)");var combined=new __U8(ciph.byteLength+authTag.byteLength);combined.set(ciph,0);combined.set(authTag,ciph.byteLength);var ab=__slice_crypto_cipher("AES-GCM",false,hid,kB,ivB,aadB,tagLen,combined,true);return __encOut(new __U8(ab),outEnc);}var abC=__slice_crypto_cipher("AES-CBC",false,hid,kB,ivB,null,128,ciph,autoPad);return __encOut(new __U8(abC),outEnc);}};},generateKeyPairSync:function(type,options){__ensExt();__slice_ensure_shard(5);var t=typeof type==="string"?type.toLowerCase():"";if(t!=="ed25519"&&t!=="x25519"&&t!=="ec"&&t!=="rsa"&&t!=="rsa-pss"&&t!=="dsa"){var eType=new TypeError("The argument 'type' must be a supported key type. Received '"+String(type)+"'");eType.code="ERR_INVALID_ARG_VALUE";throw eType;}var o=options||{};var info,details=undefined;if(t==="ed25519"){info=JSON.parse(__slice_crypto_asym_keygen("Ed25519",""));}else if(t==="x25519"){info=JSON.parse(__slice_crypto_asym_keygen("X25519",""));}else if(t==="rsa"||t==="rsa-pss"){info=JSON.parse(__slice_crypto_asym_keygen("RSA",""));details={modulusLength:Number(o.modulusLength)||2048,publicExponent:BigInt(o.publicExponent||65537)};}else if(t==="dsa"){info=JSON.parse(__slice_crypto_asym_keygen("ECDSA","P-256"));details={modulusLength:Number(o.modulusLength)||2048,divisorLength:Number(o.divisorLength)||256};}else{info=JSON.parse(__slice_crypto_asym_keygen("ECDSA",String(o.namedCurve||"P-256")));}var crv=(t==="ec")?(info.crv||"P-256"):undefined;var pubKO=new KeyObject("public",t,crv,info.pubId,__slice_base64_decode_bytes(info.spki),info,details);var privKO=new KeyObject("private",t,crv,info.privId,__slice_base64_decode_bytes(info.pkcs8),info,details);var pubOut=o.publicKeyEncoding?pubKO.export(o.publicKeyEncoding):pubKO;var privOut=o.privateKeyEncoding?privKO.export(o.privateKeyEncoding):privKO;return{publicKey:pubOut,privateKey:privOut};},generateKeyPair:function(type,options,cb){if(typeof options==="function"){cb=options;options={};}try{var kp=m.generateKeyPairSync(type,options);if(typeof cb==="function")queueMicrotask(function(){cb(null,kp.publicKey,kp.privateKey);});}catch(e){if(typeof cb==="function")queueMicrotask(function(){cb(e);});else throw e;}},createPrivateKey:function(k){return __parseKeyObj(k,true);},createPublicKey:function(k){return __parseKeyObj(k,false);},createSecretKey:function(k,enc){__slice_ensure_shard(5);var b=__toBytes(k,enc);return new KeyObject("secret","secret",undefined,0,b,null);},sign:function(alg,data,key,cb){__ensExt();__slice_ensure_shard(5);try{var ko=__parseKeyObj(key,true);var dsaEnc=(key&&typeof key==="object"&&key.dsaEncoding)?String(key.dsaEncoding):"der";var hostAlg=ko.asymmetricKeyType==="ed25519"?"Ed25519":((ko.asymmetricKeyType==="rsa"||ko.asymmetricKeyType==="rsa-pss")?"RSA":"ECDSA");var ab=__slice_crypto_asym_sign(hostAlg,ko.asymmetricKeyDetails.namedCurve||"P-256",ko._id,ko._raw,__toBytes(data),dsaEnc!=="ieee-p1363");var b=Buffer.from(ab);if(typeof cb==="function"){queueMicrotask(function(){cb(null,b);});return;}return b;}catch(e){if(typeof cb==="function"){queueMicrotask(function(){cb(e);});return;}throw e;}},verify:function(alg,data,key,sig,cb){__ensExt();try{var ko=__parseKeyObj(key,false);var hostAlg=ko.asymmetricKeyType==="ed25519"?"Ed25519":((ko.asymmetricKeyType==="rsa"||ko.asymmetricKeyType==="rsa-pss")?"RSA":"ECDSA");var ok=Boolean(__slice_crypto_asym_verify(hostAlg,ko.asymmetricKeyDetails.namedCurve||"P-256",ko._id,ko._raw,__toBytes(sig),__toBytes(data)));if(typeof cb==="function"){queueMicrotask(function(){cb(null,ok);});return;}return ok;}catch(e){if(typeof cb==="function"){queueMicrotask(function(){cb(e);});return;}throw e;}},createSign:function(_alg){var chunks=[];return{update:function(d,enc){chunks.push(__toBytes(d,enc));return this;},sign:function(key,outEnc){var sig=m.sign(null,__catBytes(chunks),key);chunks=[];return(!outEnc||outEnc==="buffer")?sig:sig.toString(outEnc);}};},createVerify:function(_alg){var chunks=[];return{update:function(d,enc){chunks.push(__toBytes(d,enc));return this;},verify:function(key,sig,sigEnc){var sB=typeof sig==="string"?__toBytes(sig,sigEnc||"base64"):__toBytes(sig);var ok=m.verify(null,__catBytes(chunks),key,sB);chunks=[];return ok;}};},getHashes:function(){return["sha1","sha256","sha384","sha512","md5"];},getCiphers:function(){return["aes-128-gcm","aes-256-gcm","aes-128-cbc","aes-256-cbc"];},get subtle(){__slice_ensure_shard(4);return globalThis.crypto.subtle;},get webcrypto(){__slice_ensure_shard(4);return globalThis.crypto;}};m.default=m;m.__esModule=true;return __slice_builtins["crypto"]=__slice_builtins["node:crypto"]=m;})();"#; -const BUILTIN_FS_SNIPPET: &[u8] = br#"(function(){var __watchers=[],__fds=Object.create(null),__nextFd=10;function __fsErr(code,syscall,p,dest){var map={ENOENT:[-2,"no such file or directory"],EEXIST:[-17,"file already exists"],EISDIR:[-21,"illegal operation on a directory"],ENOTDIR:[-20,"not a directory"],ENOTEMPTY:[-39,"directory not empty"],EBADF:[-9,"bad file descriptor"],EACCES:[-13,"permission denied"],EINVAL:[-22,"invalid argument"]},info=map[code]||[-1,"unknown error"],msg=code+": "+info[1]+", "+syscall+(p!==undefined?" '"+p+"'":"")+(dest!==undefined?" -> '"+dest+"'":""),e=new Error(msg);e.code=code;e.errno=info[0];e.syscall=syscall;if(p!==undefined)e.path=String(p);if(dest!==undefined)e.dest=String(dest);return e;}function __getFd(fd,syscall){var e=__fds[Number(fd)];if(!e)throw __fsErr("EBADF",syscall);return e;}function __normW(p){return String(p||"").replace(/\\/g,"/").replace(/\/+$/,"")||"/";}function __notifyWatch(rawP,evType){if(__watchers.length===0)return;var np=__normW(rawP),sl=np.lastIndexOf("/"),dir=sl>0?np.slice(0,sl):"/",base=sl>=0?np.slice(sl+1):np;for(var i=0;i<__watchers.length;i++){var w=__watchers[i];if(w._closed)continue;var wp=w._path;if(np===wp||dir===wp||(w._rec&&np.indexOf(wp+"/")===0)){var rel=(np===wp)?base:(np.slice(wp.length+1)||base);w._emit(evType,rel);}}}function __fsData(d){if(typeof d==="string")return d;if(d instanceof Uint8Array)return d;if(d instanceof ArrayBuffer)return new Uint8Array(d);if(d&&d.buffer instanceof ArrayBuffer)return new Uint8Array(d.buffer,d.byteOffset||0,d.byteLength);return String(d);}function __toMs(t){if(t instanceof Date)return t.getTime();var n=Number(t);if(!Number.isFinite(n))return Date.now();return n<1e11?n*1000:n;}function __mkStats(sp,followSym,opts){var isSym=Boolean(__slice_fs_is_symlink_sync(sp)),sz=__slice_fs_stat_sync(sp);if(sz<0&&!(!followSym&&isSym)){if(opts&&typeof opts==="object"&&opts.throwIfNoEntry===false)return undefined;throw __fsErr("ENOENT",followSym?"stat":"lstat",sp);}if(sz<0)sz=0;var mt=__slice_fs_mtime_sync(sp),isDir=(!followSym&&isSym)?false:Boolean(__slice_fs_is_dir_sync(sp)),d=new Date(mt),bi=Boolean(opts&&typeof opts==="object"&&opts.bigint),vSz=bi?BigInt(Math.floor(sz)):sz,vMt=bi?BigInt(Math.floor(mt)):mt,vMode=bi?BigInt((!followSym&&isSym)?41471:(isDir?16877:33188)):((!followSym&&isSym)?41471:(isDir?16877:33188));return{size:vSz,mtimeMs:vMt,ctimeMs:vMt,atimeMs:vMt,birthtimeMs:vMt,mtime:d,ctime:d,atime:d,birthtime:d,mode:vMode,isFile:function(){return(!followSym&&isSym)?false:!isDir;},isDirectory:function(){return(!followSym&&isSym)?false:isDir;},isSymbolicLink:function(){return !followSym&&isSym;},isBlockDevice:function(){return false;},isCharacterDevice:function(){return false;},isFIFO:function(){return false;},isSocket:function(){return false;}};}function __cbWrap(syncFn){return function(){var args=[],cb=null;for(var i=0;i=0?n.slice(sl+1):n,par=sl>=0?((base==="/"?"":base)+"/"+n.slice(0,sl)):base,isD=Boolean(__slice_fs_is_dir_sync(fp)),isS=Boolean(__slice_fs_is_symlink_sync(fp));return{name:bn,parentPath:par,path:par,isFile:function(){return !isD&&!isS;},isDirectory:function(){return isD&&!isS;},isSymbolicLink:function(){return isS;},isBlockDevice:function(){return false;},isCharacterDevice:function(){return false;},isFIFO:function(){return false;},isSocket:function(){return false;}};});}if(o.encoding==="buffer"){__slice_ensure_shard(5);return names.map(function(n){return Buffer.from(n,"utf8");});}return names;},statSync:function(p,opts){return __mkStats(String(p),true,opts);},lstatSync:function(p,opts){return __mkStats(String(p),false,opts);},fstatSync:function(fd,opts){var e=__getFd(fd,"fstat");return __mkStats(e.path,true,opts);},openSync:function(p,flags,mode){var sp=String(p),fl=(flags===undefined||flags===null)?"r":String(flags),isR=fl==="r"||fl==="rs"||fl==="0",hasX=fl.indexOf("x")!==-1,isW=fl.charCodeAt(0)===119||fl==="1"||fl==="577",isA=fl.charCodeAt(0)===97||fl.indexOf("1024")!==-1,isPlus=fl.indexOf("+")!==-1||fl==="2";if(hasX&&m.existsSync(sp))throw __fsErr("EEXIST","open",sp);if(isR&&!isPlus){var raw=__slice_fs_read_bytes_sync(sp);if(raw===null)throw __fsErr("ENOENT","open",sp);}else if(isW){var wr=__slice_fs_write_file_sync(sp,new Uint8Array(0));if(wr===-21)throw __fsErr("EISDIR","open",sp);__notifyWatch(sp,"change");}else if(isA){if(!m.existsSync(sp))__slice_fs_write_file_sync(sp,new Uint8Array(0));else __slice_fs_append_file_sync(sp,new Uint8Array(0));}else if(isR&&isPlus){if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","open",sp);}var fd=__nextFd++;__fds[fd]={path:sp,flags:fl,mode:mode||438,pos:0,readable:isR||isPlus,writable:isW||isA||isPlus,append:isA};return fd;},closeSync:function(fd){__getFd(fd,"close");delete __fds[Number(fd)];},readSync:function(fd,buf,offOrOpts,len,pos){var e=__getFd(fd,"read");if(!e.readable)throw __fsErr("EBADF","read");var offset=0,length=buf?buf.byteLength:0,position=null;if(offOrOpts&&typeof offOrOpts==="object"){offset=Number(offOrOpts.offset)||0;length=offOrOpts.length!==undefined?Number(offOrOpts.length):(buf.byteLength-offset);position=offOrOpts.position!==undefined?offOrOpts.position:null;}else{offset=Number(offOrOpts)||0;length=len!==undefined?Number(len):(buf.byteLength-offset);position=pos!==undefined?pos:null;}var raw=__slice_fs_read_bytes_sync(e.path);if(!raw||raw===-21)return 0;var readPos=(position!==null&&position!==undefined&&Number(position)>=0)?Number(position):e.pos;if(readPos>=raw.byteLength||length<=0)return 0;var avail=Math.min(length,raw.byteLength-readPos);var target=new Uint8Array(buf.buffer||buf,(buf.byteOffset||0)+offset,avail);target.set(raw.subarray(readPos,readPos+avail),0);if(position===null||position===undefined||Number(position)<0)e.pos=readPos+avail;return avail;},writeSync:function(fd,bufOrStr,offOrPos,lenOrEnc,pos){var e=__getFd(fd,"write");if(!e.writable)throw __fsErr("EBADF","write");__slice_ensure_shard(5);var src,writePos=null;if(typeof bufOrStr==="string"){var enc=typeof lenOrEnc==="string"?lenOrEnc:(typeof offOrPos==="string"?offOrPos:"utf8");if(typeof offOrPos==="number")writePos=offOrPos;src=Buffer.from(bufOrStr,enc);}else{var u8=__fsData(bufOrStr),off=offOrPos!==undefined?Number(offOrPos):0,ln=lenOrEnc!==undefined?Number(lenOrEnc):(u8.byteLength-off);if(pos!==undefined&&pos!==null)writePos=Number(pos);src=u8.subarray(off,off+ln);}if(e.append){__slice_fs_append_file_sync(e.path,src);e.pos+=src.byteLength;__notifyWatch(e.path,"change");return src.byteLength;}var rawCur=__slice_fs_read_bytes_sync(e.path),cur=(rawCur&&rawCur!==-21)?rawCur:new Uint8Array(0);var p=(writePos!==null&&writePos>=0)?writePos:e.pos,nLen=Math.max(cur.byteLength,p+src.byteLength),out=new Uint8Array(nLen);out.set(cur,0);out.set(src,p);__slice_fs_write_file_sync(e.path,out);if(writePos===null||writePos<0)e.pos=p+src.byteLength;__notifyWatch(e.path,"change");return src.byteLength;},fsyncSync:function(fd){__getFd(fd,"fsync");},fdatasyncSync:function(fd){__getFd(fd,"fdatasync");},ftruncateSync:function(fd,len){var e=__getFd(fd,"ftruncate");return m.truncateSync(e.path,len);},futimesSync:function(fd,atime,mtime){var e=__getFd(fd,"futime");return m.utimesSync(e.path,atime,mtime);},fchmodSync:function(fd,mode){var e=__getFd(fd,"fchmod");return m.chmodSync(e.path,mode);},realpathSync:function(p){var sp=String(p);if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","realpath",sp);var r=__slice_fs_realpath_sync(sp);if(!r)throw __fsErr("ENOENT","realpath",sp);return r;},readlinkSync:function(p,opts){var sp=String(p),r=__slice_fs_readlink_sync(sp);if(!r)throw __fsErr("ENOENT","readlink",sp);if(opts==="buffer"||(opts&&opts.encoding==="buffer")){__slice_ensure_shard(5);return Buffer.from(r,"utf8");}return r;},truncateSync:function(p,len){var sp=String(p);if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","truncate",sp);var r=__slice_fs_truncate_sync(sp,len===undefined?0:Number(len));__notifyWatch(sp,"change");return r;},utimesSync:function(p,atime,mtime){var sp=String(p);if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","utime",sp);return __slice_fs_utimes_sync(sp,__toMs(atime),__toMs(mtime));},lutimesSync:function(p,atime,mtime){return m.utimesSync(p,atime,mtime);},mkdtempSync:function(prefix){var r=__slice_fs_mkdtemp_sync(String(prefix||"/tmp/slice-"));if(!r)throw __fsErr("EACCES","mkdtemp",prefix);return r;},chmodSync:function(p,mode){return __slice_fs_chmod_sync(String(p),Number(mode)||0);},symlinkSync:function(target,p){var sp=String(p),r=__slice_fs_symlink_sync(String(target),sp);__notifyWatch(sp,"rename");return r;},opendirSync:function(p){var sp=String(p),names=m.readdirSync(sp,{withFileTypes:true}),idx=0;return{path:sp,readSync:function(){return idx0)throw __fsErr("ENOTEMPTY","rmdir",sp);var r=__slice_fs_rm_sync(sp);__notifyWatch(sp,"rename");return r;},copyFileSync:function(s,d,mode){var ss=String(s),sd=String(d);if(__slice_fs_stat_sync(ss)<0)throw __fsErr("ENOENT","copyfile",ss,sd);if((Number(mode)&1)&&m.existsSync(sd))throw __fsErr("EEXIST","copyfile",ss,sd);var r=__slice_fs_copy_file_sync(ss,sd);__notifyWatch(sd,"change");return r;},cpSync:function(src,dest,opts){var s=String(src).replace(/\/+$/,""),d=String(dest).replace(/\/+$/,""),o=opts||{};if(typeof o.filter==="function"&&!o.filter(s,d))return;if(!m.existsSync(s))throw __fsErr("ENOENT","cp",s);if(Boolean(__slice_fs_is_symlink_sync(s))&&!o.dereference){var linkTarget=m.readlinkSync(s);m.symlinkSync(linkTarget,d);return;}if(Boolean(__slice_fs_is_dir_sync(s))){if(o.recursive===false)throw __fsErr("EISDIR","cp",s);m.mkdirSync(d,{recursive:true});var entries=m.readdirSync(s);for(var i=0;i=0;i--){var w=__watchers[i];if(w._path===np&&(!listener||w._wfListener===listener))w.close();}},createReadStream:function(p,opts){__slice_ensure_shard(5);var st=__slice_builtins["node:stream"]||__slice_load_builtin("node:stream");var o=(typeof opts==="string")?{encoding:opts}:(opts||{});var enc=o.encoding||null,hwm=Number(o.highWaterMark)||65536,start=o.start!==undefined?Number(o.start):0,end=o.end!==undefined?Number(o.end):Infinity;var rs=new st.Readable({highWaterMark:hwm,encoding:enc});rs.path=String(p);rs.bytesRead=0;rs.pending=true;queueMicrotask(function(){try{if(rs.destroyed)return;if(!m.existsSync(rs.path)){rs.emit("error",__fsErr("ENOENT","open",rs.path));return;}rs.pending=false;rs.emit("open",3);rs.emit("ready");var raw=Buffer.from(__slice_fs_read_bytes_sync(rs.path));var sliceEnd=Math.min(raw.length,end===Infinity?raw.length:end+1);var view=raw.subarray(start,sliceEnd);for(var off=0;off0)waiters.shift().res({value:ev,done:false});else q.push(ev);});w.on("close",function(){done=true;while(waiters.length>0)waiters.shift().res({value:undefined,done:true});});return{[Symbol.asyncIterator]:function(){return{next:function(){if(q.length>0)return Promise.resolve({value:q.shift(),done:false});if(done||w._closed)return Promise.resolve({value:undefined,done:true});return new Promise(function(res,rej){waiters.push({res:res,rej:rej});});},return:function(){w.close();return Promise.resolve({value:undefined,done:true});}};}};}};fp.default=fp;fp.__esModule=true;m.promises=fp;m.default=m;m.__esModule=true;__slice_builtins["fs/promises"]=__slice_builtins["node:fs/promises"]=fp;return __slice_builtins["fs"]=__slice_builtins["node:fs"]=m;})();"#; +const BUILTIN_FS_SNIPPET: &[u8] = br#"(function(){var __watchers=[],__fds=Object.create(null),__nextFd=10;function __fsErr(code,syscall,p,dest){var map={ENOENT:[-2,"no such file or directory"],EEXIST:[-17,"file already exists"],EISDIR:[-21,"illegal operation on a directory"],ENOTDIR:[-20,"not a directory"],ENOTEMPTY:[-39,"directory not empty"],EBADF:[-9,"bad file descriptor"],EACCES:[-13,"permission denied"],EINVAL:[-22,"invalid argument"]},info=map[code]||[-1,"unknown error"],msg=code+": "+info[1]+", "+syscall+(p!==undefined?" '"+p+"'":"")+(dest!==undefined?" -> '"+dest+"'":""),e=new Error(msg);e.code=code;e.errno=info[0];e.syscall=syscall;if(p!==undefined)e.path=String(p);if(dest!==undefined)e.dest=String(dest);return e;}function __getFd(fd,syscall){var e=__fds[Number(fd)];if(!e)throw __fsErr("EBADF",syscall);return e;}function __normW(p){return String(p||"").replace(/\\/g,"/").replace(/\/+$/,"")||"/";}function __notifyWatch(rawP,evType){if(__watchers.length===0)return;var np=__normW(rawP),sl=np.lastIndexOf("/"),dir=sl>0?np.slice(0,sl):"/",base=sl>=0?np.slice(sl+1):np;for(var i=0;i<__watchers.length;i++){var w=__watchers[i];if(w._closed)continue;var wp=w._path;if(np===wp||dir===wp||(w._rec&&np.indexOf(wp+"/")===0)){var rel=(np===wp)?base:(np.slice(wp.length+1)||base);w._emit(evType,rel);}}}function __fsData(d){if(typeof d==="string")return d;if(d instanceof Uint8Array)return d;if(d instanceof ArrayBuffer)return new Uint8Array(d);if(d&&d.buffer instanceof ArrayBuffer)return new Uint8Array(d.buffer,d.byteOffset||0,d.byteLength);return String(d);}function __toMs(t){if(t instanceof Date)return t.getTime();var n=Number(t);if(!Number.isFinite(n))return Date.now();return n<1e11?n*1000:n;}function __mkStats(sp,followSym,opts){var isSym=Boolean(__slice_fs_is_symlink_sync(sp)),sz=__slice_fs_stat_sync(sp);if(sz<0&&!(!followSym&&isSym)){if(opts&&typeof opts==="object"&&opts.throwIfNoEntry===false)return undefined;throw __fsErr("ENOENT",followSym?"stat":"lstat",sp);}if(sz<0)sz=0;var mt=__slice_fs_mtime_sync(sp),isDir=(!followSym&&isSym)?false:Boolean(__slice_fs_is_dir_sync(sp)),d=new Date(mt),bi=Boolean(opts&&typeof opts==="object"&&opts.bigint),vSz=bi?BigInt(Math.floor(sz)):sz,vMt=bi?BigInt(Math.floor(mt)):mt,vMode=bi?BigInt((!followSym&&isSym)?41471:(isDir?16877:33188)):((!followSym&&isSym)?41471:(isDir?16877:33188));return{size:vSz,mtimeMs:vMt,ctimeMs:vMt,atimeMs:vMt,birthtimeMs:vMt,mtime:d,ctime:d,atime:d,birthtime:d,mode:vMode,isFile:function(){return(!followSym&&isSym)?false:!isDir;},isDirectory:function(){return(!followSym&&isSym)?false:isDir;},isSymbolicLink:function(){return !followSym&&isSym;},isBlockDevice:function(){return false;},isCharacterDevice:function(){return false;},isFIFO:function(){return false;},isSocket:function(){return false;}};}function __cbWrap(syncFn){return function(){var args=[],cb=null;for(var i=0;i=0?n.slice(sl+1):n,par=sl>=0?((base==="/"?"":base)+"/"+n.slice(0,sl)):base,isD=Boolean(__slice_fs_is_dir_sync(fp)),isS=Boolean(__slice_fs_is_symlink_sync(fp));return{name:bn,parentPath:par,path:par,isFile:function(){return !isD&&!isS;},isDirectory:function(){return isD&&!isS;},isSymbolicLink:function(){return isS;},isBlockDevice:function(){return false;},isCharacterDevice:function(){return false;},isFIFO:function(){return false;},isSocket:function(){return false;}};});}if(o.encoding==="buffer"){__slice_ensure_shard(5);return names.map(function(n){return Buffer.from(n,"utf8");});}return names;},statSync:function(p,opts){return __mkStats(String(p),true,opts);},lstatSync:function(p,opts){return __mkStats(String(p),false,opts);},fstatSync:function(fd,opts){var e=__getFd(fd,"fstat");return __mkStats(e.path,true,opts);},openSync:function(p,flags,mode){var sp=String(p),fl=(flags===undefined||flags===null)?"r":String(flags),isR=fl==="r"||fl==="rs"||fl==="0",hasX=fl.indexOf("x")!==-1,isW=fl.charCodeAt(0)===119||fl==="1"||fl==="577",isA=fl.charCodeAt(0)===97||fl.indexOf("1024")!==-1,isPlus=fl.indexOf("+")!==-1||fl==="2";if(hasX&&m.existsSync(sp))throw __fsErr("EEXIST","open",sp);if(isR&&!isPlus){var raw=__slice_fs_read_bytes_sync(sp);if(raw===null)throw __fsErr("ENOENT","open",sp);}else if(isW){var wr=__slice_fs_write_file_sync(sp,new Uint8Array(0));if(wr===-21)throw __fsErr("EISDIR","open",sp);__notifyWatch(sp,"change");}else if(isA){if(!m.existsSync(sp))__slice_fs_write_file_sync(sp,new Uint8Array(0));else __slice_fs_append_file_sync(sp,new Uint8Array(0));}else if(isR&&isPlus){if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","open",sp);}var fd=__nextFd++;__fds[fd]={path:sp,flags:fl,mode:mode||438,pos:0,readable:isR||isPlus,writable:isW||isA||isPlus,append:isA};return fd;},closeSync:function(fd){__getFd(fd,"close");delete __fds[Number(fd)];},readSync:function(fd,buf,offOrOpts,len,pos){var e=__getFd(fd,"read");if(!e.readable)throw __fsErr("EBADF","read");var offset=0,length=buf?buf.byteLength:0,position=null;if(offOrOpts&&typeof offOrOpts==="object"){offset=Number(offOrOpts.offset)||0;length=offOrOpts.length!==undefined?Number(offOrOpts.length):(buf.byteLength-offset);position=offOrOpts.position!==undefined?offOrOpts.position:null;}else{offset=Number(offOrOpts)||0;length=len!==undefined?Number(len):(buf.byteLength-offset);position=pos!==undefined?pos:null;}var raw=__slice_fs_read_bytes_sync(e.path);if(!raw||raw===-21)return 0;var readPos=(position!==null&&position!==undefined&&Number(position)>=0)?Number(position):e.pos;if(readPos>=raw.byteLength||length<=0)return 0;var avail=Math.min(length,raw.byteLength-readPos);var target=new Uint8Array(buf.buffer||buf,(buf.byteOffset||0)+offset,avail);target.set(raw.subarray(readPos,readPos+avail),0);if(position===null||position===undefined||Number(position)<0)e.pos=readPos+avail;return avail;},writeSync:function(fd,bufOrStr,offOrPos,lenOrEnc,pos){var e=__getFd(fd,"write");if(!e.writable)throw __fsErr("EBADF","write");__slice_ensure_shard(5);var src,writePos=null;if(typeof bufOrStr==="string"){var enc=typeof lenOrEnc==="string"?lenOrEnc:(typeof offOrPos==="string"?offOrPos:"utf8");if(typeof offOrPos==="number")writePos=offOrPos;src=Buffer.from(bufOrStr,enc);}else{var u8=__fsData(bufOrStr),off=offOrPos!==undefined?Number(offOrPos):0,ln=lenOrEnc!==undefined?Number(lenOrEnc):(u8.byteLength-off);if(pos!==undefined&&pos!==null)writePos=Number(pos);src=u8.subarray(off,off+ln);}if(e.append){__slice_fs_append_file_sync(e.path,src);e.pos+=src.byteLength;__notifyWatch(e.path,"change");return src.byteLength;}var rawCur=__slice_fs_read_bytes_sync(e.path),cur=(rawCur&&rawCur!==-21)?rawCur:new Uint8Array(0);var p=(writePos!==null&&writePos>=0)?writePos:e.pos,nLen=Math.max(cur.byteLength,p+src.byteLength),out=new Uint8Array(nLen);out.set(cur,0);out.set(src,p);__slice_fs_write_file_sync(e.path,out);if(writePos===null||writePos<0)e.pos=p+src.byteLength;__notifyWatch(e.path,"change");return src.byteLength;},fsyncSync:function(fd){__getFd(fd,"fsync");},fdatasyncSync:function(fd){__getFd(fd,"fdatasync");},ftruncateSync:function(fd,len){var e=__getFd(fd,"ftruncate");return m.truncateSync(e.path,len);},futimesSync:function(fd,atime,mtime){var e=__getFd(fd,"futime");return m.utimesSync(e.path,atime,mtime);},fchmodSync:function(fd,mode){var e=__getFd(fd,"fchmod");return m.chmodSync(e.path,mode);},realpathSync:function(p){var sp=String(p);if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","realpath",sp);var r=__slice_fs_realpath_sync(sp);if(!r)throw __fsErr("ENOENT","realpath",sp);return r;},readlinkSync:function(p,opts){var sp=String(p),r=__slice_fs_readlink_sync(sp);if(!r)throw __fsErr("ENOENT","readlink",sp);if(opts==="buffer"||(opts&&opts.encoding==="buffer")){__slice_ensure_shard(5);return Buffer.from(r,"utf8");}return r;},truncateSync:function(p,len){var sp=String(p);if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","truncate",sp);var r=__slice_fs_truncate_sync(sp,len===undefined?0:Number(len));__notifyWatch(sp,"change");return r;},utimesSync:function(p,atime,mtime){var sp=String(p);if(__slice_fs_stat_sync(sp)<0)throw __fsErr("ENOENT","utime",sp);return __slice_fs_utimes_sync(sp,__toMs(atime),__toMs(mtime));},lutimesSync:function(p,atime,mtime){return m.utimesSync(p,atime,mtime);},mkdtempSync:function(prefix){var r=__slice_fs_mkdtemp_sync(String(prefix||"/tmp/slice-"));if(!r)throw __fsErr("EACCES","mkdtemp",prefix);return r;},chmodSync:function(p,mode){return __slice_fs_chmod_sync(String(p),Number(mode)||0);},symlinkSync:function(target,p){var sp=String(p),r=__slice_fs_symlink_sync(String(target),sp);__notifyWatch(sp,"rename");return r;},opendirSync:function(p){var sp=String(p),names=m.readdirSync(sp,{withFileTypes:true}),idx=0;return{path:sp,readSync:function(){return idx0)throw __fsErr("ENOTEMPTY","rmdir",sp);var r=__slice_fs_rm_sync(sp);__notifyWatch(sp,"rename");return r;},copyFileSync:function(s,d,mode){var ss=String(s),sd=String(d);if(__slice_fs_stat_sync(ss)<0)throw __fsErr("ENOENT","copyfile",ss,sd);if((Number(mode)&1)&&m.existsSync(sd))throw __fsErr("EEXIST","copyfile",ss,sd);var r=__slice_fs_copy_file_sync(ss,sd);__notifyWatch(sd,"change");return r;},cpSync:function(src,dest,opts){var s=String(src).replace(/\/+$/,""),d=String(dest).replace(/\/+$/,""),o=opts||{};if(typeof o.filter==="function"&&!o.filter(s,d))return;if(!m.existsSync(s))throw __fsErr("ENOENT","cp",s);if(Boolean(__slice_fs_is_symlink_sync(s))&&!o.dereference){var linkTarget=m.readlinkSync(s);m.symlinkSync(linkTarget,d);return;}if(Boolean(__slice_fs_is_dir_sync(s))){if(o.recursive===false)throw __fsErr("EISDIR","cp",s);m.mkdirSync(d,{recursive:true});var entries=m.readdirSync(s);for(var i=0;i=0;i--){var w=__watchers[i];if(w._path===np&&(!listener||w._wfListener===listener))w.close();}},createReadStream:function(p,opts){__slice_ensure_shard(5);var st=__slice_builtins["node:stream"]||__slice_load_builtin("node:stream");var o=(typeof opts==="string")?{encoding:opts}:(opts||{});var enc=o.encoding||null,hwm=Number(o.highWaterMark)||65536,start=o.start!==undefined?Number(o.start):0,end=o.end!==undefined?Number(o.end):Infinity;var rs=new st.Readable({highWaterMark:hwm,encoding:enc});rs.path=String(p);rs.bytesRead=0;rs.pending=true;queueMicrotask(function(){try{if(rs.destroyed)return;if(!m.existsSync(rs.path)){rs.emit("error",__fsErr("ENOENT","open",rs.path));return;}rs.pending=false;rs.emit("open",3);rs.emit("ready");var raw=Buffer.from(__slice_fs_read_bytes_sync(rs.path));var sliceEnd=Math.min(raw.length,end===Infinity?raw.length:end+1);var view=raw.subarray(start,sliceEnd);for(var off=0;off0)waiters.shift().res({value:ev,done:false});else q.push(ev);});w.on("close",function(){done=true;while(waiters.length>0)waiters.shift().res({value:undefined,done:true});});return{[Symbol.asyncIterator]:function(){return{next:function(){if(q.length>0)return Promise.resolve({value:q.shift(),done:false});if(done||w._closed)return Promise.resolve({value:undefined,done:true});return new Promise(function(res,rej){waiters.push({res:res,rej:rej});});},return:function(){w.close();return Promise.resolve({value:undefined,done:true});}};}};}};__fp.default=__fp;__fp.__esModule=true;Object.defineProperty(m,"promises",{value:__fp,writable:true,enumerable:true,configurable:true});Object.defineProperty(__slice_builtins,"fs/promises",{value:__fp,writable:true,enumerable:true,configurable:true});Object.defineProperty(__slice_builtins,"node:fs/promises",{value:__fp,writable:true,enumerable:true,configurable:true});}return __fp;}Object.defineProperty(m,"promises",{get:__getFp,enumerable:true,configurable:true});Object.defineProperty(__slice_builtins,"fs/promises",{get:__getFp,enumerable:true,configurable:true});Object.defineProperty(__slice_builtins,"node:fs/promises",{get:__getFp,enumerable:true,configurable:true});m.default=m;m.__esModule=true;return __slice_builtins["fs"]=__slice_builtins["node:fs"]=m;})();"#; const BUILTIN_PATH_SNIPPET: &[u8] = br#"(function(){function __normPath(p){var s=String(p||"").replace(/\\/g,"/");if(s.length===0)return ".";var isAbs=s.charCodeAt(0)===47,trailing=s.length>1&&s.charCodeAt(s.length-1)===47,parts=s.split("/"),out=[];for(var i=0;i0&&out[out.length-1]!=="..")out.pop();else if(!isAbs)out.push("..");}else out.push(seg);}var res=(isAbs?"/":"")+out.join("/");if(!res)res=isAbs?"/":".";if(trailing&&res!=="/")res+="/";return res;}var m={sep:"/",delimiter:":",normalize:__normPath,isAbsolute:function(p){var s=String(p||"");return s.length>0&&(s.charCodeAt(0)===47||s.charCodeAt(0)===92||(s.length>2&&s.charCodeAt(1)===58));},join:function(){var parts=[];for(var i=0;i=-1&&!resolvedAbs;i--){var p=i>=0?String(arguments[i]||""):"/";if(!p)continue;p=p.replace(/\\/g,"/");resolved=p+"/"+resolved;resolvedAbs=p.charCodeAt(0)===47;}var norm=__normPath(resolved);return(norm.length>1&&norm.charCodeAt(norm.length-1)===47)?norm.slice(0,-1):norm;},dirname:function(p){var s=String(p||"").replace(/\\/g,"/").replace(/\/+$/,"");if(!s)return ".";var i=s.lastIndexOf("/");return i>0?s.slice(0,i):(i===0?"/":".");},basename:function(p,ext){var s=String(p||"").replace(/\\/g,"/").replace(/\/+$/,""),i=s.lastIndexOf("/"),b=i>=0?s.slice(i+1):s;return(ext&&b.endsWith(ext))?b.slice(0,b.length-ext.length):b;},extname:function(p){var b=m.basename(p),i=b.lastIndexOf(".");return i>0?b.slice(i):"";},relative:function(from,to){var f=m.resolve(from),t=m.resolve(to);if(f===t)return "";var fs=f.split("/").filter(Boolean),ts=t.split("/").filter(Boolean),len=Math.min(fs.length,ts.length),same=len;for(var i=0;i0){var w=this._waiters.shift();w.res({value:fmt,done:false});return true;}this._buf.push(fmt);this._drainFlowing();return this._buf.length0)this._enqueueFmt(rem);}this._eof=true;this._drainFlowing();return false;}var fmt=this._formatChunk(chunk);if(!this.readableObjectMode&&this._encoding&&typeof fmt==="string"&&fmt.length===0&&chunk&&((chunk.byteLength||chunk.length||0)>0))return true;return this._enqueueFmt(fmt);};Readable.prototype.unshift=function(chunk){if(chunk!==null&&chunk!==undefined){this._buf.unshift(this._formatChunk(chunk));this._drainFlowing();}return true;};Readable.prototype._drainFlowing=function(){if(this.readableFlowing===true){while(this._buf.length>0&&this.readableFlowing===true&&!this.destroyed){var c=this._buf.shift();this.emit("data",c);}if(this._buf.length===0&&!this._eof)this._kickRead();}else if(this._buf.length>0&&this.listenerCount("readable")>0){this.emit("readable");}if(this._eof&&this._buf.length===0&&!this._emittedEnd){this._emittedEnd=true;this.readable=false;this.readableEnded=true;while(this._waiters.length>0){this._waiters.shift().res({value:undefined,done:true});}var self=this;queueMicrotask(function(){if(!self.destroyed){self.emit("end");self.emit("close");}});}};Readable.prototype.read=function(){if(this._buf.length>0){var c=this._buf.shift();if(this._buf.length===0&&!this._eof)this._kickRead();if(this._eof&&this._buf.length===0)this._drainFlowing();return c;}if(!this._eof)this._kickRead();if(this._eof)this._drainFlowing();return null;};Readable.prototype.pause=function(){if(this.readableFlowing!==false){this.readableFlowing=false;this.emit("pause");}return this;};Readable.prototype.resume=function(){if(!this.readableEnded){this.readableFlowing=true;this.emit("resume");this._kickRead();this._drainFlowing();}return this;};Readable.prototype.isPaused=function(){return this.readableFlowing===false;};Readable.prototype[Symbol.asyncIterator]=function(){var self=this;this.readableFlowing=false;this._kickRead();return{next:function(){if(self.destroyed&&self.errored)return Promise.reject(self.errored);if(self._buf.length>0){var c=self._buf.shift();if(self._buf.length===0&&!self._eof)self._kickRead();return Promise.resolve({value:c,done:false});}if(self._eof||self.readableEnded||self.destroyed)return Promise.resolve({value:undefined,done:true});self._kickRead();return new Promise(function(res,rej){self._waiters.push({res:res,rej:rej});});},return:function(){self.destroy();return Promise.resolve({value:undefined,done:true});}};};Readable.from=function(iterable,opts){var r=new Readable(Object.assign({objectMode:true},opts||{}));queueMicrotask(function(){try{if(iterable&&typeof iterable[Symbol.asyncIterator]==="function"){var ait=iterable[Symbol.asyncIterator]();(function pump(){ait.next().then(function(step){if(r.destroyed)return;if(step.done){r.push(null);}else{r.push(step.value);pump();}},function(err){r.destroy(err);});})();}else{var arr=Array.from(iterable||[]);for(var i=0;i0)this._corked--;if(this._corked===0&&this._corkBuf.length>0){var q=this._corkBuf.slice();this._corkBuf=[];for(var i=0;i0){this._corkBuf.push({c:chunk,e:e,cb:cb,len:len});return ret;}this._doWrite(chunk,e,cb,len);return ret;};Writable.prototype.end=function(chunk,enc,cb){if(typeof chunk==="function"){cb=chunk;chunk=undefined;enc=undefined;}else if(typeof enc==="function"){cb=enc;enc=undefined;}if(chunk!==undefined&&chunk!==null)this.write(chunk,enc);while(this._corked>0)this.uncork();if(this.writableEnded){if(typeof cb==="function"){if(this.writableFinished)queueMicrotask(cb);else this.once("finish",cb);}return this;}this.writableEnded=true;this.writable=false;var self=this;function finishNow(err){if(err){self.destroy(err);if(typeof cb==="function")cb(err);return;}self.writableFinished=true;self.emit("finish");if(typeof cb==="function")cb(null);if(!self.destroyed&&!(self instanceof Duplex))self.emit("close");}if(typeof this._final==="function"){try{this._final(finishNow);}catch(e){finishNow(e);}}else{queueMicrotask(function(){finishNow(null);});}return this;};Writable.fromWeb=function(webWs,opts){var w=webWs.getWriter();return new Writable(Object.assign({},opts||{},{write:function(c,_e,cb){w.write(c).then(function(){cb(null);},function(e){cb(e);});},final:function(cb){w.close().then(function(){cb(null);},function(e){cb(e);});}}));};Writable.toWeb=function(nodeWs){__slice_ensure_shard(3);return new globalThis.WritableStream({write:function(c){return new Promise(function(res,rej){nodeWs.write(c,function(e){if(e)rej(e);else res();});});},close:function(){return new Promise(function(res,rej){nodeWs.end(function(e){if(e)rej(e);else res();});});},abort:function(r){nodeWs.destroy(r instanceof Error?r:new Error(String(r||"Aborted")));}});};function Duplex(opts){if(!(this instanceof Duplex))return new Duplex(opts);Readable.call(this,opts);Writable.call(this,opts);this.allowHalfOpen=!opts||opts.allowHalfOpen!==false;}Duplex.prototype=Object.create(Readable.prototype);Object.assign(Duplex.prototype,Writable.prototype);Duplex.prototype.constructor=Duplex;function Transform(opts){if(!(this instanceof Transform))return new Transform(opts);Duplex.call(this,opts);var o=opts||{};if(typeof o.transform==="function")this._transform=o.transform;if(typeof o.flush==="function")this._flush=o.flush;}Transform.prototype=Object.create(Duplex.prototype);Transform.prototype.constructor=Transform;Transform.prototype._transform=function(c,_e,cb){this.push(c);if(cb)cb(null);};Transform.prototype._write=function(chunk,enc,cb){var self=this;this._transform(chunk,enc,function(err,out){if(err){if(cb)cb(err);else self.destroy(err);return;}if(out!==undefined&&out!==null)self.push(out);if(cb)cb(null);});};Transform.prototype._final=function(cb){var self=this;if(typeof this._flush==="function"){this._flush(function(err,out){if(err){cb(err);return;}if(out!==undefined&&out!==null)self.push(out);self.push(null);cb(null);});}else{this.push(null);cb(null);}};function PassThrough(opts){if(!(this instanceof PassThrough))return new PassThrough(opts);Transform.call(this,opts);}PassThrough.prototype=Object.create(Transform.prototype);PassThrough.prototype.constructor=PassThrough;function finished(stream,opts,cb){if(typeof opts==="function"){cb=opts;opts={};}var o=opts||{},sig=o.signal,settled=false;function done(err){if(settled)return;settled=true;if(typeof cb==="function")cb(err||null);}if(sig&&sig.aborted){queueMicrotask(function(){done(sig.reason||new Error("AbortError"));});return function(){};}if(stream.destroyed||stream.writableFinished||stream.readableEnded){queueMicrotask(function(){done(stream.errored||null);});return function(){};}function onEnd(){done(null);}function onErr(e){done(e||new Error("Stream error"));}function onClose(){if(!stream.writableFinished&&stream.writableEnded===false&&stream.readableEnded===false&&stream.errored){done(stream.errored);}else{done(null);}}if(stream.once){stream.once("finish",onEnd);stream.once("end",onEnd);stream.once("error",onErr);stream.once("close",onClose);}if(sig&&typeof sig.addEventListener==="function"){sig.addEventListener("abort",function(){var ae=sig.reason||new Error("AbortError");if(stream.destroy)stream.destroy(ae);done(ae);});}return function(){if(stream.removeListener){stream.removeListener("finish",onEnd);stream.removeListener("end",onEnd);stream.removeListener("error",onErr);stream.removeListener("close",onClose);}};}function pipeline(){var args=Array.from(arguments),cb=typeof args[args.length-1]==="function"?args.pop():null;if(args.length===1&&Array.isArray(args[0]))args=args[0];var opts=(args.length>1&&args[args.length-1]&&typeof args[args.length-1]==="object"&&typeof args[args.length-1].pipe!=="function"&&typeof args[args.length-1].write!=="function")?args.pop():{};var sig=opts&&opts.signal,settled=false;function finishAll(err){if(settled)return;settled=true;if(err){for(var k=0;k0){var w=this._waiters.shift();w.res({value:fmt,done:false});return true;}this._buf.push(fmt);this._drainFlowing();return this._buf.length0)this._enqueueFmt(rem);}this._eof=true;this._drainFlowing();return false;}var fmt=this._formatChunk(chunk);if(!this.readableObjectMode&&this._encoding&&typeof fmt==="string"&&fmt.length===0&&chunk&&((chunk.byteLength||chunk.length||0)>0))return true;return this._enqueueFmt(fmt);};Readable.prototype.unshift=function(chunk){if(chunk!==null&&chunk!==undefined){this._buf.unshift(this._formatChunk(chunk));this._drainFlowing();}return true;};Readable.prototype._drainFlowing=function(){if(this.readableFlowing===true){while(this._buf.length>0&&this.readableFlowing===true&&!this.destroyed){var c=this._buf.shift();this.emit("data",c);}if(this._buf.length===0&&!this._eof)this._kickRead();}else if(this._buf.length>0&&this.listenerCount("readable")>0){this.emit("readable");}if(this._eof&&this._buf.length===0&&!this._emittedEnd){this._emittedEnd=true;this.readable=false;this.readableEnded=true;if(this._waiters){while(this._waiters.length>0){this._waiters.shift().res({value:undefined,done:true});}}var self=this;queueMicrotask(function(){if(!self.destroyed){self.emit("end");self.emit("close");}});}};Readable.prototype.read=function(){if(this._buf.length>0){var c=this._buf.shift();if(this._buf.length===0&&!this._eof)this._kickRead();if(this._eof&&this._buf.length===0)this._drainFlowing();return c;}if(!this._eof)this._kickRead();if(this._eof)this._drainFlowing();return null;};Readable.prototype.pause=function(){if(this.readableFlowing!==false){this.readableFlowing=false;this.emit("pause");}return this;};Readable.prototype.resume=function(){if(!this.readableEnded){this.readableFlowing=true;this.emit("resume");this._kickRead();this._drainFlowing();}return this;};Readable.prototype.isPaused=function(){return this.readableFlowing===false;};Readable.prototype[Symbol.asyncIterator]=function(){var self=this;this.readableFlowing=false;this._kickRead();return{next:function(){if(self.destroyed&&self.errored)return Promise.reject(self.errored);if(self._buf.length>0){var c=self._buf.shift();if(self._buf.length===0&&!self._eof)self._kickRead();return Promise.resolve({value:c,done:false});}if(self._eof||self.readableEnded||self.destroyed)return Promise.resolve({value:undefined,done:true});self._kickRead();return new Promise(function(res,rej){(self._waiters||(self._waiters=[])).push({res:res,rej:rej});});},return:function(){self.destroy();return Promise.resolve({value:undefined,done:true});}};};Readable.from=function(iterable,opts){var r=new Readable(Object.assign({objectMode:true},opts||{}));queueMicrotask(function(){try{if(iterable&&typeof iterable[Symbol.asyncIterator]==="function"){var ait=iterable[Symbol.asyncIterator]();(function pump(){ait.next().then(function(step){if(r.destroyed)return;if(step.done){r.push(null);}else{r.push(step.value);pump();}},function(err){r.destroy(err);});})();}else{var arr=Array.from(iterable||[]);for(var i=0;i0)this._corked--;if(this._corked===0&&this._corkBuf&&this._corkBuf.length>0){var q=this._corkBuf.slice();this._corkBuf=[];for(var i=0;i0){(this._corkBuf||(this._corkBuf=[])).push({c:chunk,e:e,cb:cb,len:len});return ret;}this._doWrite(chunk,e,cb,len);return ret;};Writable.prototype.end=function(chunk,enc,cb){if(typeof chunk==="function"){cb=chunk;chunk=undefined;enc=undefined;}else if(typeof enc==="function"){cb=enc;enc=undefined;}if(chunk!==undefined&&chunk!==null)this.write(chunk,enc);while(this._corked>0)this.uncork();if(this.writableEnded){if(typeof cb==="function"){if(this.writableFinished)queueMicrotask(cb);else this.once("finish",cb);}return this;}this.writableEnded=true;this.writable=false;var self=this;function finishNow(err){if(err){self.destroy(err);if(typeof cb==="function")cb(err);return;}self.writableFinished=true;self.emit("finish");if(typeof cb==="function")cb(null);if(!self.destroyed&&!(self instanceof Duplex))self.emit("close");}if(typeof this._final==="function"){try{this._final(finishNow);}catch(e){finishNow(e);}}else{queueMicrotask(function(){finishNow(null);});}return this;};Writable.fromWeb=function(webWs,opts){var w=webWs.getWriter();return new Writable(Object.assign({},opts||{},{write:function(c,_e,cb){w.write(c).then(function(){cb(null);},function(e){cb(e);});},final:function(cb){w.close().then(function(){cb(null);},function(e){cb(e);});}}));};Writable.toWeb=function(nodeWs){__slice_ensure_shard(3);return new globalThis.WritableStream({write:function(c){return new Promise(function(res,rej){nodeWs.write(c,function(e){if(e)rej(e);else res();});});},close:function(){return new Promise(function(res,rej){nodeWs.end(function(e){if(e)rej(e);else res();});});},abort:function(r){nodeWs.destroy(r instanceof Error?r:new Error(String(r||"Aborted")));}});};function Duplex(opts){if(!(this instanceof Duplex))return new Duplex(opts);Readable.call(this,opts);Writable.call(this,opts);this.allowHalfOpen=!opts||opts.allowHalfOpen!==false;}Duplex.prototype=Object.create(Readable.prototype);Object.assign(Duplex.prototype,Writable.prototype);Duplex.prototype.constructor=Duplex;function Transform(opts){if(!(this instanceof Transform))return new Transform(opts);Duplex.call(this,opts);var o=opts||{};if(typeof o.transform==="function")this._transform=o.transform;if(typeof o.flush==="function")this._flush=o.flush;}Transform.prototype=Object.create(Duplex.prototype);Transform.prototype.constructor=Transform;Transform.prototype._transform=function(c,_e,cb){this.push(c);if(cb)cb(null);};Transform.prototype._write=function(chunk,enc,cb){var self=this;this._transform(chunk,enc,function(err,out){if(err){if(cb)cb(err);else self.destroy(err);return;}if(out!==undefined&&out!==null)self.push(out);if(cb)cb(null);});};Transform.prototype._final=function(cb){var self=this;if(typeof this._flush==="function"){this._flush(function(err,out){if(err){cb(err);return;}if(out!==undefined&&out!==null)self.push(out);self.push(null);cb(null);});}else{this.push(null);cb(null);}};function PassThrough(opts){if(!(this instanceof PassThrough))return new PassThrough(opts);Transform.call(this,opts);}PassThrough.prototype=Object.create(Transform.prototype);PassThrough.prototype.constructor=PassThrough;function finished(stream,opts,cb){if(typeof opts==="function"){cb=opts;opts={};}var o=opts||{},sig=o.signal,settled=false;function done(err){if(settled)return;settled=true;if(typeof cb==="function")cb(err||null);}if(sig&&sig.aborted){queueMicrotask(function(){done(sig.reason||new Error("AbortError"));});return function(){};}if(stream.destroyed||stream.writableFinished||stream.readableEnded){queueMicrotask(function(){done(stream.errored||null);});return function(){};}function onEnd(){done(null);}function onErr(e){done(e||new Error("Stream error"));}function onClose(){if(!stream.writableFinished&&stream.writableEnded===false&&stream.readableEnded===false&&stream.errored){done(stream.errored);}else{done(null);}}if(stream.once){stream.once("finish",onEnd);stream.once("end",onEnd);stream.once("error",onErr);stream.once("close",onClose);}if(sig&&typeof sig.addEventListener==="function"){sig.addEventListener("abort",function(){var ae=sig.reason||new Error("AbortError");if(stream.destroy)stream.destroy(ae);done(ae);});}return function(){if(stream.removeListener){stream.removeListener("finish",onEnd);stream.removeListener("end",onEnd);stream.removeListener("error",onErr);stream.removeListener("close",onClose);}};}function pipeline(){var args=Array.from(arguments),cb=typeof args[args.length-1]==="function"?args.pop():null;if(args.length===1&&Array.isArray(args[0]))args=args[0];var opts=(args.length>1&&args[args.length-1]&&typeof args[args.length-1]==="object"&&typeof args[args.length-1].pipe!=="function"&&typeof args[args.length-1].write!=="function")?args.pop():{};var sig=opts&&opts.signal,settled=false;function finishAll(err){if(settled)return;settled=true;if(err){for(var k=0;k0)req.push(Buffer.from(bodyBytes));req.complete=true;req.push(null);});return req;}function Server(opts,listener){if(!(this instanceof Server))return new Server(opts,listener);EE.call(this);var fn=typeof opts==="function"?opts:listener;if(typeof fn==="function")this.on("request",fn);this.listening=false;this.maxHeadersCount=null;this.timeout=0;this.keepAliveTimeout=5000;this.headersTimeout=60000;this.requestTimeout=300000;this._port=0;this._host="127.0.0.1";}Server.prototype=Object.create(EE.prototype);Server.prototype.constructor=Server;Server.prototype.setTimeout=function(ms,cb){this.timeout=Number(ms)||0;if(typeof cb==="function")this.on("timeout",cb);return this;};Server.prototype.address=function(){return this.listening?{address:this._host,family:"IPv4",port:this._port}:null;};Server.prototype.ref=function(){return this;};Server.prototype.unref=function(){return this;};Server.prototype._dispatchActiveHttpBridge=function(){if(typeof __slice_http_is_active!=="function"||!__slice_http_is_active())return;var self=this,m=__slice_http_method(),p=__slice_http_path(),q=__slice_http_query(),url=q?(p+"?"+q):p,rawH=[];try{rawH=JSON.parse(__slice_http_headers_all());}catch(_e){}var bStr=__slice_http_body()||"";var req=__buildIncoming(m,url,rawH,bStr?Buffer.from(bStr,"utf8"):null);var res=new ServerResponse(req,function(sr,bodyBuf){var ct="text/plain;charset=UTF-8",outH=[],ks=Object.keys(sr._headers);for(var i=0;i0)res.push(resBody);res.complete=true;res.push(null);});});return;}__slice_ensure_shard(10);__slice_ensure_shard(11);var url=this.protocol+"//"+this.host+(this.port&&this.port!==80&&this.port!==443?(":"+this.port):"")+this.path;var fOpts={method:this.method,headers:hdrPairs};if(bodyBuf.length>0&&this.method!=="GET"&&this.method!=="HEAD")fOpts.body=bodyBuf.toString("utf8");globalThis.fetch(url,fOpts).then(function(fRes){if(fcb)fcb(null);var res=new IncomingMessage();res.statusCode=fRes.status;res.statusMessage=fRes.statusText||STATUS_CODES[fRes.status]||"OK";if(fRes.headers&&typeof fRes.headers.forEach==="function"){fRes.headers.forEach(function(val,key){var kl=String(key).toLowerCase();res.headers[kl]=String(val);res.rawHeaders.push(String(key),String(val));});}self.res=res;self.emit("response",res);return fRes.text().then(function(txt){if(txt&&txt.length>0)res.push(Buffer.from(txt,"utf8"));res.complete=true;res.push(null);});},function(err){if(fcb)fcb(null);self.emit("error",err instanceof Error?err:new Error(String(err)));});};function __mkHttpMod(defaultProto){var globalAgent=new Agent({keepAlive:true});var m={METHODS:METHODS,STATUS_CODES:STATUS_CODES,IncomingMessage:IncomingMessage,ServerResponse:ServerResponse,Server:Server,ClientRequest:function(a0,a1,a2){return new ClientRequest(defaultProto,a0,a1,a2);},Agent:Agent,globalAgent:globalAgent,maxHeaderSize:16384,createServer:function(opts,listener){return new Server(opts,listener);},request:function(a0,a1,a2){return new ClientRequest(defaultProto,a0,a1,a2);},get:function(a0,a1,a2){var req=new ClientRequest(defaultProto,a0,a1,a2);req.end();return req;},validateHeaderName:function(n){if(!n||!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(String(n)))throw new TypeError("ERR_INVALID_HTTP_TOKEN: Header name must be a valid HTTP token");},validateHeaderValue:function(n,v){if(v===undefined||/[\r\n\0]/.test(String(v)))throw new TypeError("ERR_INVALID_CHAR: Invalid character in header content");}};m.default=m;m.__esModule=true;return m;}var httpMod=__mkHttpMod("http:"),httpsMod=__mkHttpMod("https:");__slice_builtins["https"]=__slice_builtins["node:https"]=httpsMod;return __slice_builtins["http"]=__slice_builtins["node:http"]=httpMod;})();"#; @@ -96,7 +96,7 @@ pub(crate) fn eval_lazy_builtin_module( "buffer" | "node:buffer" => BUILTIN_BUFFER_SNIPPET, "url" | "node:url" => BUILTIN_URL_SNIPPET, "process" | "node:process" => { - br#"(__slice_ensure_shard(18),__slice_builtins["process"]=__slice_builtins["node:process"]=globalThis.process)"# + br#"(__slice_ensure_shard(29),__slice_builtins["process"]=__slice_builtins["node:process"]=globalThis.process)"# } "timers" | "node:timers" => BUILTIN_TIMERS_SNIPPET, "timers/promises" | "node:timers/promises" => { @@ -106,7 +106,7 @@ pub(crate) fn eval_lazy_builtin_module( br#"(function(){var __entries=[],__obs=[];function __notify(e){for(var i=0;i<__obs.length;i++){var o=__obs[i];if(o._active&&(o._types.indexOf(e.entryType)!==-1)){o._buf.push(e);if(!o._sched){o._sched=true;(function(ob){queueMicrotask(function(){ob._sched=false;if(!ob._active||ob._buf.length===0)return;var recs=ob._buf.slice();ob._buf=[];ob._cb({getEntries:function(){return recs;},getEntriesByName:function(n,t){return recs.filter(function(x){return x.name===String(n)&&(!t||x.entryType===String(t));});},getEntriesByType:function(t){return recs.filter(function(x){return x.entryType===String(t);});}},ob);});})(o);}}}}var perf=globalThis.performance||{now:function(){return Date.now()-1700000000000;}};perf.timeOrigin=1700000000000;perf.nodeTiming={name:"node",entryType:"node",startTime:0,duration:0,bootstrapComplete:0.05,environment:0.01,loopStart:0.05,loopExit:-1,idleTime:0};perf.mark=function(name,opts){var o=opts||{},st=o.startTime!==undefined?Number(o.startTime):perf.now(),e={name:String(name),entryType:"mark",startTime:st,duration:0,detail:o.detail!==undefined?o.detail:null,toJSON:function(){return{name:this.name,entryType:this.entryType,startTime:this.startTime,duration:this.duration,detail:this.detail};}};__entries.push(e);__notify(e);return e;};perf.measure=function(name,startOrOpts,endMark){var s=0,end=perf.now(),detail=null;if(startOrOpts&&typeof startOrOpts==="object"){if(startOrOpts.detail!==undefined)detail=startOrOpts.detail;if(startOrOpts.start!==undefined){if(typeof startOrOpts.start==="number")s=startOrOpts.start;else{for(var i=__entries.length-1;i>=0;i--)if(__entries[i].name===String(startOrOpts.start)){s=__entries[i].startTime;break;}}}if(startOrOpts.end!==undefined){if(typeof startOrOpts.end==="number")end=startOrOpts.end;else{for(var j=__entries.length-1;j>=0;j--)if(__entries[j].name===String(startOrOpts.end)){end=__entries[j].startTime;break;}}}else if(startOrOpts.duration!==undefined){end=s+Number(startOrOpts.duration);}}else{if(typeof startOrOpts==="string"){for(var k=__entries.length-1;k>=0;k--)if(__entries[k].name===startOrOpts){s=__entries[k].startTime;break;}}if(typeof endMark==="string"){for(var l=__entries.length-1;l>=0;l--)if(__entries[l].name===endMark){end=__entries[l].startTime;break;}}}var e={name:String(name),entryType:"measure",startTime:s,duration:end-s,detail:detail,toJSON:function(){return{name:this.name,entryType:this.entryType,startTime:this.startTime,duration:this.duration,detail:this.detail};}};__entries.push(e);__notify(e);return e;};perf.getEntries=function(){return __entries.slice();};perf.getEntriesByName=function(n,t){return __entries.filter(function(e){return e.name===String(n)&&(!t||e.entryType===String(t));});};perf.getEntriesByType=function(t){return __entries.filter(function(e){return e.entryType===String(t);});};perf.clearMarks=function(n){__entries=__entries.filter(function(e){return e.entryType!=="mark"||(n!==undefined&&e.name!==String(n));});};perf.clearMeasures=function(n){__entries=__entries.filter(function(e){return e.entryType!=="measure"||(n!==undefined&&e.name!==String(n));});};perf.timerify=function(fn){if(typeof fn!=="function")throw new TypeError("timerify requires a function");var w=function(){var t0=perf.now();try{return fn.apply(this,arguments);}finally{var t1=perf.now(),e={name:fn.name||"anonymous",entryType:"function",startTime:t0,duration:t1-t0,detail:Array.from(arguments)};__entries.push(e);__notify(e);}};Object.defineProperty(w,"name",{value:fn.name,configurable:true});return w;};perf.toJSON=function(){return{timeOrigin:this.timeOrigin,nodeTiming:this.nodeTiming};};function PerformanceObserver(cb){if(typeof cb!=="function")throw new TypeError("PerformanceObserver callback must be a function");this._cb=cb;this._types=[];this._buf=[];this._active=false;this._sched=false;}PerformanceObserver.supportedEntryTypes=["mark","measure","function","node"];PerformanceObserver.prototype.observe=function(opts){var o=opts||{};var ts=Array.isArray(o.entryTypes)?o.entryTypes:(o.type?[o.type]:[]);this._types=ts.map(String);this._active=true;if(__obs.indexOf(this)===-1)__obs.push(this);if(o.buffered){for(var i=0;i<__entries.length;i++){if(this._types.indexOf(__entries[i].entryType)!==-1)this._buf.push(__entries[i]);}}};PerformanceObserver.prototype.disconnect=function(){this._active=false;this._buf=[];};PerformanceObserver.prototype.takeRecords=function(){var r=this._buf.slice();this._buf=[];return r;};function monitorEventLoopDelay(){return{enable:function(){return true;},disable:function(){return true;},reset:function(){},percentile:function(){return 0;},percentiles:new Map(),min:0,max:0,mean:0,stddev:0,count:0,exceeds:0};}var m={performance:perf,PerformanceObserver:PerformanceObserver,monitorEventLoopDelay:monitorEventLoopDelay,createHistogram:monitorEventLoopDelay,constants:{NODE_PERFORMANCE_GC_MAJOR:4,NODE_PERFORMANCE_GC_MINOR:1}};m.default=m;m.__esModule=true;return __slice_builtins["perf_hooks"]=__slice_builtins["node:perf_hooks"]=m;})()"# } "tty" | "node:tty" => { - br#"(function(){__slice_ensure_shard(18);function ReadStream(){return globalThis.process.stdin;}function WriteStream(fd){return fd===2?globalThis.process.stderr:globalThis.process.stdout;}var m={isatty:function(){return false;},ReadStream:ReadStream,WriteStream:WriteStream};m.default=m;m.__esModule=true;return __slice_builtins["tty"]=__slice_builtins["node:tty"]=m;})()"# + br#"(function(){__slice_ensure_shard(29);function ReadStream(){return globalThis.process.stdin;}function WriteStream(fd){return fd===2?globalThis.process.stderr:globalThis.process.stdout;}var m={isatty:function(){return false;},ReadStream:ReadStream,WriteStream:WriteStream};m.default=m;m.__esModule=true;return __slice_builtins["tty"]=__slice_builtins["node:tty"]=m;})()"# } "module" | "node:module" => { br#"(function(){var __BM=["assert","assert/strict","async_hooks","buffer","child_process","cluster","console","crypto","dgram","diagnostics_channel","dns","dns/promises","events","fs","fs/promises","http","http2","https","inspector","inspector/promises","module","net","os","path","path/posix","path/win32","perf_hooks","process","querystring","readline","readline/promises","stream","stream/promises","stream/web","string_decoder","test","timers","timers/promises","tls","tty","url","util","util/types","v8","vm","wasi","worker_threads","zlib"];function isBuiltin(id){var s=String(id||"");if(s.slice(0,5)==="node:")return __BM.indexOf(s.slice(5))!==-1;if(s.slice(0,6)==="slice:"||s.slice(0,11)==="cloudflare:")return true;return __BM.indexOf(s)!==-1;}function createRequire(filename){var req=function(id){return globalThis.__slice_cjs_require(id);};req.resolve=function(id){return String(id);};req.resolve.paths=function(){return["/node_modules"];};req.cache=Object.create(null);req.main={id:String(filename||"/index.js"),filename:String(filename||"/index.js"),exports:{}};return req;}function Module(id,parent){this.id=id||"";this.filename=id||"";this.exports={};this.parent=parent||null;this.loaded=false;this.children=[];}Module.builtinModules=__BM;Module.isBuiltin=isBuiltin;Module.createRequire=createRequire;Module._load=function(id){return globalThis.__slice_cjs_require(id);};Module.default=Module;Module.__esModule=true;return __slice_builtins["module"]=__slice_builtins["node:module"]=Module;})()"# diff --git a/crates/slice-engine/src/runtime/boa_realm.rs b/crates/slice-engine/src/runtime/boa_realm.rs index 25f272b..75f00f0 100644 --- a/crates/slice-engine/src/runtime/boa_realm.rs +++ b/crates/slice-engine/src/runtime/boa_realm.rs @@ -15,6 +15,19 @@ pub(crate) const DIRTY_WORKERS: u8 = 1 << 5; pub(crate) const DIRTY_WASM: u8 = 1 << 6; pub(crate) const DIRTY_PROCESS: u8 = 1 << 7; +pub(crate) const EXEC_DIRTY_EXIT: u8 = 1 << 0; +pub(crate) const EXEC_DIRTY_REJECTIONS: u8 = 1 << 1; +pub(crate) const EXEC_DIRTY_UNCAUGHT: u8 = 1 << 2; +pub(crate) const EXEC_DIRTY_CHILD_PROC: u8 = 1 << 3; +pub(crate) const EXEC_DIRTY_ARGV: u8 = 1 << 4; + +pub(crate) const REALM_CTL_RESET_MT: i32 = 0; +pub(crate) const REALM_CTL_SET_DET_MODE: i32 = 1; +pub(crate) const REALM_CTL_SYNC_ENV: i32 = 2; +pub(crate) const REALM_CTL_SET_NEXT_TICK: i32 = 3; +pub(crate) const REALM_CTL_RESET_WU: i32 = 4; +pub(crate) const REALM_CTL_DISPATCH_HTTP_BRIDGE: i32 = 5; + #[derive(Default, Clone)] pub(crate) struct ActiveBoaHttpReq { pub(crate) active: bool, @@ -30,10 +43,12 @@ pub(crate) struct ActiveBoaHttpReq { pub(crate) struct WarmBoaRealm { pub(crate) ctx: boa_engine::Context, pub(crate) loaded_bundles: FxHashMap, + pub(crate) compiled_scripts: FxHashMap, pub(crate) ses_check_fn: Option, pub(crate) ensure_shard_fn: Option, pub(crate) init_worker_self_fn: Option, pub(crate) drain_wu_fn: Option, + pub(crate) ctl_fn: Option, pub(crate) loaded_shards_mask: u32, } @@ -101,6 +116,10 @@ thread_local! { const { std::cell::RefCell::new(Vec::new()) }; pub(crate) static BOA_DIRTY_SUBSYSTEMS: std::cell::Cell = const { std::cell::Cell::new(0) }; + pub(crate) static BOA_EXEC_DIRTY: std::cell::Cell = + const { std::cell::Cell::new(0) }; + pub(crate) static BOA_CUSTOM_ARGV: std::cell::RefCell>> = + const { std::cell::RefCell::new(None) }; pub(crate) static BOA_PROCESS_EXIT: std::cell::Cell> = const { std::cell::Cell::new(None) }; pub(crate) static BOA_LAST_EXIT_CODE: std::cell::Cell> = @@ -111,6 +130,48 @@ thread_local! { const { std::cell::RefCell::new(None) }; } +#[inline] +pub(crate) fn mark_exec_dirty(bit: u8) { + BOA_EXEC_DIRTY.with(|c| c.set(c.get() | bit)); +} + +#[inline] +pub(crate) fn set_process_exit(code: i32) { + mark_exec_dirty(EXEC_DIRTY_EXIT); + BOA_PROCESS_EXIT.with(|e| e.set(Some(code))); + BOA_LAST_EXIT_CODE.with(|e| e.set(Some(code))); +} + +#[inline] +pub(crate) fn set_last_exit_code(code: i32) { + mark_exec_dirty(EXEC_DIRTY_EXIT); + BOA_LAST_EXIT_CODE.with(|e| e.set(Some(code))); +} + +#[inline] +pub(crate) fn set_uncaught_error(err: String) { + mark_exec_dirty(EXEC_DIRTY_UNCAUGHT); + BOA_UNCAUGHT_ERROR.with(|e| *e.borrow_mut() = Some(err)); +} + +#[inline] +pub(crate) fn set_child_proc_violation(violation: SandboxViolation) { + mark_exec_dirty(EXEC_DIRTY_CHILD_PROC); + BOA_LAST_CHILD_PROC_VIOLATION.with(|v| *v.borrow_mut() = Some(violation)); +} + +#[inline] +pub(crate) fn has_process_exit() -> bool { + (BOA_EXEC_DIRTY.with(|c| c.get()) & EXEC_DIRTY_EXIT) != 0 + && BOA_PROCESS_EXIT.with(|e| e.get().is_some()) +} + +#[inline] +pub(crate) fn has_uncaught_error() -> bool { + (BOA_EXEC_DIRTY.with(|c| c.get()) & EXEC_DIRTY_UNCAUGHT) != 0 + && BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_some()) +} + #[derive(Debug, Clone)] struct AlsCapturedSnap(boa_engine::JsValue); @@ -152,19 +213,19 @@ impl boa_engine::context::HostHooks for SliceHostHooks { args: &[boa_engine::JsValue], context: &mut boa_engine::Context, ) -> boa_engine::JsResult { + if !BOA_ALS_ACTIVE.with(|a| a.get()) { + return job.callback().call(this, args, context); + } if let Some(captured) = job.host_defined().downcast_ref::() { let prev = BOA_ALS_SNAP.with(|s| s.replace(captured.0.clone())); let res = job.callback().call(this, args, context); BOA_ALS_SNAP.with(|s| *s.borrow_mut() = prev); return res; } - if BOA_ALS_ACTIVE.with(|a| a.get()) { - let prev = BOA_ALS_SNAP.with(|s| s.replace(boa_engine::JsValue::undefined())); - let res = job.callback().call(this, args, context); - BOA_ALS_SNAP.with(|s| *s.borrow_mut() = prev); - return res; - } - job.callback().call(this, args, context) + let prev = BOA_ALS_SNAP.with(|s| s.replace(boa_engine::JsValue::undefined())); + let res = job.callback().call(this, args, context); + BOA_ALS_SNAP.with(|s| *s.borrow_mut() = prev); + res } fn promise_rejection_tracker( @@ -173,9 +234,10 @@ impl boa_engine::context::HostHooks for SliceHostHooks { operation: boa_engine::builtins::promise::OperationType, _context: &mut boa_engine::Context, ) { - let upcast = promise.clone().upcast(); match operation { boa_engine::builtins::promise::OperationType::Reject => { + mark_exec_dirty(EXEC_DIRTY_REJECTIONS); + let upcast = promise.clone().upcast(); BOA_UNHANDLED_REJECTIONS.with(|list| { let mut b = list.borrow_mut(); if !b.contains(&upcast) { @@ -184,8 +246,16 @@ impl boa_engine::context::HostHooks for SliceHostHooks { }); } boa_engine::builtins::promise::OperationType::Handle => { + if (BOA_EXEC_DIRTY.with(|c| c.get()) & EXEC_DIRTY_REJECTIONS) == 0 { + return; + } BOA_UNHANDLED_REJECTIONS.with(|list| { - list.borrow_mut().retain(|p| p != &upcast); + let mut b = list.borrow_mut(); + if b.is_empty() { + return; + } + let upcast = promise.clone().upcast(); + b.retain(|p| p != &upcast); }); } } @@ -328,7 +398,7 @@ impl boa_engine::job::JobExecutor for SliceJobExecutor { self: std::rc::Rc, context: &mut boa_engine::Context, ) -> boa_engine::JsResult<()> { - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { self.promise_jobs.borrow_mut().clear(); return Ok(()); } @@ -336,14 +406,14 @@ impl boa_engine::job::JobExecutor for SliceJobExecutor { let next_job = self.promise_jobs.borrow_mut().pop_front(); if let Some(job) = next_job { let res = job.call(context); - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { self.promise_jobs.borrow_mut().clear(); return Ok(()); } res?; } else { self.fallback.clone().run_jobs(context)?; - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { self.promise_jobs.borrow_mut().clear(); return Ok(()); } @@ -460,16 +530,18 @@ pub(crate) fn create_bare_boa_realm() -> WarmBoaRealm { WarmBoaRealm { ctx, loaded_bundles: FxHashMap::default(), + compiled_scripts: FxHashMap::default(), ses_check_fn: None, ensure_shard_fn: None, init_worker_self_fn: None, drain_wu_fn: None, + ctl_fn: None, loaded_shards_mask: 0, } } -/// Refreshes the cached JS function handles (`__slice_check_ses`, `__slice_ensure_shard`, `__slice_drain_wu`) -/// on `realm` after `ULTRA_CORE_PRELUDE` has been evaluated. +/// Refreshes the cached JS function handles (`__slice_check_ses`, `__slice_ensure_shard`, +/// `__slice_drain_wu`, `__slice_ctl`) on `realm` after `ULTRA_CORE_PRELUDE` has been evaluated. #[inline] pub(crate) fn populate_realm_cached_handles(realm: &mut WarmBoaRealm) { let global = realm.ctx.global_object(); @@ -494,6 +566,66 @@ pub(crate) fn populate_realm_cached_handles(realm: &mut WarmBoaRealm) { .ok() .and_then(|v| v.as_object()); } + if realm.ctl_fn.is_none() { + realm.ctl_fn = global + .get(boa_engine::js_string!("__slice_ctl"), &mut realm.ctx) + .ok() + .and_then(|v| v.as_object()); + } +} + +#[inline] +pub(crate) fn call_realm_ctl(realm: &mut WarmBoaRealm, op: i32, flag: bool) { + if realm.ctl_fn.is_none() { + populate_realm_cached_handles(realm); + } + if let Some(ctl) = realm.ctl_fn.clone() { + let _ = ctl.call( + &boa_engine::JsValue::undefined(), + &[ + boa_engine::JsValue::from(op), + boa_engine::JsValue::from(flag), + ], + &mut realm.ctx, + ); + } +} + +#[inline] +fn fnv1a_script_key(bytes: &[u8]) -> u64 { + let mut h: u64 = 0xcbf2_9ce4_8422_2325 ^ (bytes.len() as u64); + for &b in bytes { + h ^= u64::from(b); + h = h.wrapping_mul(0x0100_0000_01b3); + } + h +} + +/// Evaluates a scoped JS script (`{ ... }`) on a warm realm, caching its compiled `boa_engine::Script` +/// (`Gc`) so subsequent warm invocations skip lexing, parsing, scope analysis, and byte compilation. +pub(crate) fn eval_or_reuse_cached_script( + realm: &mut WarmBoaRealm, + scoped_js: &str, +) -> boa_engine::JsResult { + let key = fnv1a_script_key(scoped_js.as_bytes()); + if let Some(cached) = realm.compiled_scripts.get(&key).cloned() { + return cached.evaluate(&mut realm.ctx); + } + let script = boa_engine::Script::parse( + boa_engine::Source::from_bytes(scoped_js.as_bytes()), + None, + &mut realm.ctx, + )?; + let reusable = script.can_reuse_across_runs(&mut realm.ctx); + let res = script.evaluate(&mut realm.ctx); + if reusable + && res.is_ok() + && BOA_VIOLATION.with(|v| v.borrow().is_none()) + && realm.compiled_scripts.len() < 32 + { + realm.compiled_scripts.insert(key, script); + } + res } /// Creates a warm `boa_engine::Context` initialized with Slice's native host functions, @@ -522,9 +654,7 @@ pub(crate) fn ensure_realm_shards( return; } let lazy_getters_active = (realm.loaded_shards_mask & 1) != 0; - for shard_id in [ - 2u32, 13, 1, 11, 12, 10, 3, 14, 15, 4, 16, 5, 17, 6, 7, 8, 9, 18, - ] { + for shard_id in crate::js_preludes::SHARD_LOAD_ORDER { let bit = 1u32 << shard_id; if (missing & bit) != 0 { if lazy_getters_active { @@ -583,6 +713,8 @@ pub(crate) struct SavedIsolateContextGuard { pub(crate) saved_http_res: Option, pub(crate) saved_wait_until_count: usize, pub(crate) saved_dirty_subsystems: u8, + pub(crate) saved_exec_dirty: u8, + pub(crate) saved_custom_argv: Option>, pub(crate) saved_process_exit: Option, pub(crate) saved_last_exit_code: Option, pub(crate) saved_unhandled_rejections: Vec, @@ -592,6 +724,7 @@ pub(crate) struct SavedIsolateContextGuard { impl SavedIsolateContextGuard { pub(crate) fn enter() -> Self { + let saved_exec_dirty = BOA_EXEC_DIRTY.with(|c| c.replace(0)); let saved_stdout = BOA_STDOUT.with(|out| std::mem::take(&mut *out.borrow_mut())); let saved_violation = BOA_VIOLATION.with(|v| v.borrow_mut().take()); let saved_tenant = BOA_ACTIVE_TENANT.with(|t| std::mem::take(&mut *t.borrow_mut())); @@ -601,7 +734,11 @@ impl SavedIsolateContextGuard { BOA_EGRESS_SECRETS.with(|s| std::mem::take(&mut *s.borrow_mut())); let saved_env_map = BOA_ENV_MAP.with(|m| std::mem::take(&mut *m.borrow_mut())); let saved_exec_bins = BOA_EXEC_BINS.with(|b| std::mem::take(&mut *b.borrow_mut())); - let saved_last_cp_violation = BOA_LAST_CHILD_PROC_VIOLATION.with(|v| v.borrow_mut().take()); + let saved_last_cp_violation = if (saved_exec_dirty & EXEC_DIRTY_CHILD_PROC) != 0 { + BOA_LAST_CHILD_PROC_VIOLATION.with(|v| v.borrow_mut().take()) + } else { + None + }; let saved_fetch_mocks = BOA_FETCH_MOCKS.with(|m| { let b = m.borrow(); if b.is_empty() { @@ -648,11 +785,30 @@ impl SavedIsolateContextGuard { let saved_http_res = BOA_HTTP_RES.with(|res| res.borrow_mut().take()); let saved_wait_until_count = BOA_WAIT_UNTIL_COUNT.with(|c| c.replace(0)); let saved_dirty_subsystems = BOA_DIRTY_SUBSYSTEMS.with(|d| d.replace(0)); - let saved_process_exit = BOA_PROCESS_EXIT.with(|e| e.replace(None)); - let saved_last_exit_code = BOA_LAST_EXIT_CODE.with(|e| e.replace(None)); - let saved_unhandled_rejections = - BOA_UNHANDLED_REJECTIONS.with(|u| std::mem::take(&mut *u.borrow_mut())); - let saved_uncaught_error = BOA_UNCAUGHT_ERROR.with(|e| e.borrow_mut().take()); + let saved_custom_argv = if (saved_exec_dirty & EXEC_DIRTY_ARGV) != 0 { + BOA_CUSTOM_ARGV.with(|a| a.borrow_mut().take()) + } else { + None + }; + let (saved_process_exit, saved_last_exit_code) = + if (saved_exec_dirty & EXEC_DIRTY_EXIT) != 0 { + ( + BOA_PROCESS_EXIT.with(|e| e.replace(None)), + BOA_LAST_EXIT_CODE.with(|e| e.replace(None)), + ) + } else { + (None, None) + }; + let saved_unhandled_rejections = if (saved_exec_dirty & EXEC_DIRTY_REJECTIONS) != 0 { + BOA_UNHANDLED_REJECTIONS.with(|u| std::mem::take(&mut *u.borrow_mut())) + } else { + Vec::new() + }; + let saved_uncaught_error = if (saved_exec_dirty & EXEC_DIRTY_UNCAUGHT) != 0 { + BOA_UNCAUGHT_ERROR.with(|e| e.borrow_mut().take()) + } else { + None + }; let saved_ev_loop = crate::event_loop::save_and_reset_event_loop_state(); Self { @@ -679,6 +835,8 @@ impl SavedIsolateContextGuard { saved_http_res, saved_wait_until_count, saved_dirty_subsystems, + saved_exec_dirty, + saved_custom_argv, saved_process_exit, saved_last_exit_code, saved_unhandled_rejections, @@ -694,12 +852,24 @@ impl Drop for SavedIsolateContextGuard { crate::event_loop::restore_event_loop_state(ev); } let child_dirty = BOA_DIRTY_SUBSYSTEMS.with(|d| d.get()); + let child_exec_dirty = BOA_EXEC_DIRTY.with(|c| c.get()); + let union_exec_dirty = self.saved_exec_dirty | child_exec_dirty; BOA_DIRTY_SUBSYSTEMS.with(|d| d.set(self.saved_dirty_subsystems)); - BOA_PROCESS_EXIT.with(|e| e.set(self.saved_process_exit)); - BOA_LAST_EXIT_CODE.with(|e| e.set(self.saved_last_exit_code)); - BOA_UNHANDLED_REJECTIONS - .with(|u| *u.borrow_mut() = std::mem::take(&mut self.saved_unhandled_rejections)); - BOA_UNCAUGHT_ERROR.with(|e| *e.borrow_mut() = self.saved_uncaught_error.take()); + BOA_EXEC_DIRTY.with(|c| c.set(self.saved_exec_dirty)); + if (union_exec_dirty & EXEC_DIRTY_EXIT) != 0 { + BOA_PROCESS_EXIT.with(|e| e.set(self.saved_process_exit)); + BOA_LAST_EXIT_CODE.with(|e| e.set(self.saved_last_exit_code)); + } + if (union_exec_dirty & EXEC_DIRTY_REJECTIONS) != 0 { + BOA_UNHANDLED_REJECTIONS + .with(|u| *u.borrow_mut() = std::mem::take(&mut self.saved_unhandled_rejections)); + } + if (union_exec_dirty & EXEC_DIRTY_UNCAUGHT) != 0 { + BOA_UNCAUGHT_ERROR.with(|e| *e.borrow_mut() = self.saved_uncaught_error.take()); + } + if (union_exec_dirty & EXEC_DIRTY_ARGV) != 0 { + BOA_CUSTOM_ARGV.with(|a| *a.borrow_mut() = self.saved_custom_argv.take()); + } BOA_STDOUT.with(|out| *out.borrow_mut() = std::mem::take(&mut self.saved_stdout)); BOA_VIOLATION.with(|v| *v.borrow_mut() = self.saved_violation.take()); BOA_ACTIVE_TENANT.with(|t| *t.borrow_mut() = std::mem::take(&mut self.saved_tenant)); @@ -709,8 +879,10 @@ impl Drop for SavedIsolateContextGuard { .with(|s| *s.borrow_mut() = std::mem::take(&mut self.saved_egress_secrets)); BOA_ENV_MAP.with(|m| *m.borrow_mut() = std::mem::take(&mut self.saved_env_map)); BOA_EXEC_BINS.with(|b| *b.borrow_mut() = std::mem::take(&mut self.saved_exec_bins)); - BOA_LAST_CHILD_PROC_VIOLATION - .with(|v| *v.borrow_mut() = self.saved_last_cp_violation.take()); + if (union_exec_dirty & EXEC_DIRTY_CHILD_PROC) != 0 { + BOA_LAST_CHILD_PROC_VIOLATION + .with(|v| *v.borrow_mut() = self.saved_last_cp_violation.take()); + } if let Some(fm) = self.saved_fetch_mocks.take() { BOA_FETCH_MOCKS.with(|m| *m.borrow_mut() = fm); } else if (child_dirty & DIRTY_FETCH_MOCK) != 0 { diff --git a/crates/slice-engine/src/runtime/event_loop.rs b/crates/slice-engine/src/runtime/event_loop.rs index 0e5f722..2978281 100644 --- a/crates/slice-engine/src/runtime/event_loop.rs +++ b/crates/slice-engine/src/runtime/event_loop.rs @@ -3,10 +3,11 @@ //! Outbound `fetch()` Multiplexer (`Promise.all([fetch(...), ...])`). use crate::boa_realm::{ - mark_subsystem_dirty, BOA_ACTIVE_TENANT, BOA_ALS_ACTIVE, BOA_ALS_SNAP, BOA_DET_STATE, - BOA_DIRTY_SUBSYSTEMS, BOA_EGRESS_SECRETS, BOA_KV_MEM_BUDGET, BOA_LAST_EXIT_CODE, BOA_NET_HOSTS, - BOA_PROCESS_EXIT, BOA_UNCAUGHT_ERROR, BOA_UNHANDLED_REJECTIONS, BOA_VIOLATION, DIRTY_ALS, - DIRTY_EVENT_LOOP, DIRTY_SOCKETS, DIRTY_WORKERS, + has_process_exit, has_uncaught_error, mark_subsystem_dirty, set_last_exit_code, + set_uncaught_error, BOA_ACTIVE_TENANT, BOA_ALS_ACTIVE, BOA_ALS_SNAP, BOA_DET_STATE, + BOA_DIRTY_SUBSYSTEMS, BOA_EGRESS_SECRETS, BOA_EXEC_DIRTY, BOA_KV_MEM_BUDGET, + BOA_LAST_EXIT_CODE, BOA_NET_HOSTS, BOA_PROCESS_EXIT, BOA_UNHANDLED_REJECTIONS, BOA_VIOLATION, + DIRTY_ALS, DIRTY_EVENT_LOOP, DIRTY_SOCKETS, DIRTY_WORKERS, EXEC_DIRTY_REJECTIONS, }; use crate::outbound_http::{ execute_outbound_fetch_with_redirects, outbound_pool_reuse_count, record_outbound_pool_reuses, @@ -603,7 +604,7 @@ pub(crate) fn format_uncaught_js_error(err: &boa_engine::JsError, ctx: &mut Cont } pub(crate) fn handle_uncaught_js_error(err: boa_engine::JsError, ctx: &mut Context) -> bool { - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { return true; } let msg = err.to_string(); @@ -668,7 +669,7 @@ pub(crate) fn handle_uncaught_js_error(err: boa_engine::JsError, ctx: &mut Conte ], ctx, ); - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { return true; } match emit_fn.call( @@ -682,16 +683,16 @@ pub(crate) fn handle_uncaught_js_error(err: boa_engine::JsError, ctx: &mut Conte ) { Ok(v) if v.to_boolean() => { let _ = run_jobs_and_check_rejections(ctx); - return BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_none()) + return !has_uncaught_error() && BOA_VIOLATION.with(|v| v.borrow().is_none()); } Err(handler_err) => { - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { return true; } let h_formatted = format_uncaught_js_error(&handler_err, ctx); - BOA_UNCAUGHT_ERROR.with(|e| *e.borrow_mut() = Some(h_formatted)); - BOA_LAST_EXIT_CODE.with(|c| c.set(Some(1))); + set_uncaught_error(h_formatted); + set_last_exit_code(1); return false; } Ok(_) => {} @@ -701,15 +702,18 @@ pub(crate) fn handle_uncaught_js_error(err: boa_engine::JsError, ctx: &mut Conte } } - BOA_UNCAUGHT_ERROR.with(|e| *e.borrow_mut() = Some(formatted)); - BOA_LAST_EXIT_CODE.with(|c| c.set(Some(1))); + set_uncaught_error(formatted); + set_last_exit_code(1); false } pub(crate) fn drain_unhandled_rejections(ctx: &mut Context) -> bool { + if (BOA_EXEC_DIRTY.with(|c| c.get()) & EXEC_DIRTY_REJECTIONS) == 0 { + return true; + } while BOA_UNHANDLED_REJECTIONS.with(|u| !u.borrow().is_empty()) { - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) - || BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_some()) + if has_process_exit() + || has_uncaught_error() || BOA_VIOLATION.with(|v| v.borrow().is_some()) { BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); @@ -780,7 +784,7 @@ pub(crate) fn drain_unhandled_rejections(ctx: &mut Context) -> bool { return false; } } - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { return false; } continue; @@ -789,7 +793,7 @@ pub(crate) fn drain_unhandled_rejections(ctx: &mut Context) -> bool { if !handle_uncaught_js_error(handler_err, ctx) { return false; } - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { return false; } continue; @@ -804,9 +808,8 @@ pub(crate) fn drain_unhandled_rejections(ctx: &mut Context) -> bool { .to_string(ctx) .map(|s| s.to_std_string_escaped()) .unwrap_or_else(|_| reason.display().to_string()); - BOA_UNCAUGHT_ERROR - .with(|e| *e.borrow_mut() = Some(format!("Uncaught (in promise) {}", reason_str))); - BOA_LAST_EXIT_CODE.with(|c| c.set(Some(1))); + set_uncaught_error(format!("Uncaught (in promise) {}", reason_str)); + set_last_exit_code(1); BOA_UNHANDLED_REJECTIONS.with(|u| u.borrow_mut().clear()); return false; } @@ -821,7 +824,7 @@ pub(crate) fn run_jobs_and_check_rejections(ctx: &mut Context) -> bool { return false; } } - if BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if has_process_exit() { return false; } drain_unhandled_rejections(ctx) @@ -830,8 +833,8 @@ pub(crate) fn run_jobs_and_check_rejections(ctx: &mut Context) -> bool { fn try_emit_before_exit(ctx: &mut Context, before_exit_count: &mut usize) -> bool { if (BOA_DIRTY_SUBSYSTEMS.with(|d| d.get()) & crate::boa_realm::DIRTY_PROCESS) == 0 || *before_exit_count >= 64 - || BOA_PROCESS_EXIT.with(|e| e.get().is_some()) - || BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_some()) + || has_process_exit() + || has_uncaught_error() || BOA_VIOLATION.with(|v| v.borrow().is_some()) { return false; @@ -936,7 +939,7 @@ pub(crate) fn finalize_and_reset_process_state(ctx: &mut Context) { } } if code != 0 || BOA_LAST_EXIT_CODE.with(|e| e.get().is_some()) { - BOA_LAST_EXIT_CODE.with(|e| e.set(Some(code))); + set_last_exit_code(code); } if crate::workers::is_worker_thread() && code != 0 { crate::workers::worker_self_set_listening(false, Some(code)); @@ -982,8 +985,8 @@ pub(crate) fn drive_event_loop_to_completion(ctx: &mut Context) { loop { if BOA_VIOLATION.with(|v| v.borrow().is_some()) - || BOA_PROCESS_EXIT.with(|e| e.get().is_some()) - || BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_some()) + || has_process_exit() + || has_uncaught_error() || crate::workers::is_current_worker_terminated() { clear_event_loop_state(); @@ -1000,8 +1003,8 @@ pub(crate) fn drive_event_loop_to_completion(ctx: &mut Context) { if did_parent_w || did_self_w { idle_worker_polls = 0; if BOA_VIOLATION.with(|v| v.borrow().is_some()) - || BOA_PROCESS_EXIT.with(|e| e.get().is_some()) - || BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_some()) + || has_process_exit() + || has_uncaught_error() || crate::workers::is_current_worker_terminated() { clear_event_loop_state(); @@ -1023,15 +1026,22 @@ pub(crate) fn drive_event_loop_to_completion(ctx: &mut Context) { i += 1; } } - let in_flight_ids: Vec = loop_st.in_flight_fetches.keys().copied().collect(); - for fid in in_flight_ids { - let abort_opt = loop_st + if !loop_st.in_flight_fetches.is_empty() + && loop_st .in_flight_fetches - .get(&fid) - .and_then(|h| is_signal_aborted(&h.signal_obj, ctx)); - if let Some(reason) = abort_opt { - if let Some(removed) = loop_st.in_flight_fetches.remove(&fid) { - aborted_callbacks.push((removed.reject_fn, reason)); + .values() + .any(|h| h.signal_obj.is_some()) + { + let in_flight_ids: Vec = loop_st.in_flight_fetches.keys().copied().collect(); + for fid in in_flight_ids { + let abort_opt = loop_st + .in_flight_fetches + .get(&fid) + .and_then(|h| is_signal_aborted(&h.signal_obj, ctx)); + if let Some(reason) = abort_opt { + if let Some(removed) = loop_st.in_flight_fetches.remove(&fid) { + aborted_callbacks.push((removed.reject_fn, reason)); + } } } } @@ -1234,8 +1244,8 @@ pub(crate) fn drive_event_loop_to_completion(ctx: &mut Context) { return; } if BOA_VIOLATION.with(|v| v.borrow().is_some()) - || BOA_PROCESS_EXIT.with(|e| e.get().is_some()) - || BOA_UNCAUGHT_ERROR.with(|e| e.borrow().is_some()) + || has_process_exit() + || has_uncaught_error() { clear_event_loop_state(); return; diff --git a/crates/slice-engine/src/runtime/workers.rs b/crates/slice-engine/src/runtime/workers.rs index cb98476..1fb6bb6 100644 --- a/crates/slice-engine/src/runtime/workers.rs +++ b/crates/slice-engine/src/runtime/workers.rs @@ -1031,7 +1031,7 @@ pub(crate) fn poll_worker_self_inbox_and_dispatch( let arg = JsValue::from(boa_engine::js_string!(msg_json)); let call_res = dispatch_fn.call(&JsValue::undefined(), &[arg], ctx); let _ = ctx.run_jobs(); - if crate::boa_realm::BOA_PROCESS_EXIT.with(|e| e.get().is_some()) { + if crate::boa_realm::has_process_exit() { return true; } if let Err(err) = call_res { diff --git a/crates/slice-engine/src/vm/boacas.rs b/crates/slice-engine/src/vm/boacas.rs index a34bac0..bf3e585 100644 --- a/crates/slice-engine/src/vm/boacas.rs +++ b/crates/slice-engine/src/vm/boacas.rs @@ -272,18 +272,7 @@ pub fn pack_boacas_container(compacted_js: &str) -> Vec { has_next_tick, ); - let mut compiler_ctx = boa_engine::Context::default(); - let precompiled = if let Ok(script) = boa_engine::Script::parse( - boa_engine::Source::from_bytes(&fused_bytes), - None, - &mut compiler_ctx, - ) { - script - .compile_to_slicebc(&mut compiler_ctx) - .unwrap_or_default() - } else { - Vec::new() - }; + let precompiled = crate::js_preludes::compile_static_js_to_slicebc(&fused_bytes); let header = BoaCasHeader { approach_kind: 3, @@ -377,9 +366,7 @@ pub(crate) fn eval_boacas_on_realm( return (res, true); } // Fallback if CodeBlock deserialization fails - let _ = realm.ctx.eval(boa_engine::Source::from_bytes( - crate::js_preludes::ULTRA_CORE_PRELUDE, - )); + let _ = crate::js_preludes::eval_ultra_core_prelude(&mut realm.ctx); crate::boa_realm::populate_realm_cached_handles(realm); } @@ -420,14 +407,10 @@ pub(crate) fn eval_boacas_on_realm( } else { ensure_realm_shards(realm, effective_shards, init_lazy); let res = if (header.feature_flags & BOACAS_FLAG_STARTS_WITH_BRACE) != 0 { - realm - .ctx - .eval(boa_engine::Source::from_bytes(fallback_js.as_bytes())) + crate::boa_realm::eval_or_reuse_cached_script(realm, fallback_js) } else { let scoped = format!("{{\n{}\n}}", fallback_js); - realm - .ctx - .eval(boa_engine::Source::from_bytes(scoped.as_bytes())) + crate::boa_realm::eval_or_reuse_cached_script(realm, &scoped) }; (res, true) } diff --git a/crates/slice-engine/src/vm/parser_and_compiler.rs b/crates/slice-engine/src/vm/parser_and_compiler.rs index bfb3e64..640caaa 100644 --- a/crates/slice-engine/src/vm/parser_and_compiler.rs +++ b/crates/slice-engine/src/vm/parser_and_compiler.rs @@ -2105,6 +2105,11 @@ fn compile_source_to_bytecode_inner(raw_source: &str, allow_boacas_aot: bool) -> bytes } +thread_local! { + static SNP_LAST_HIT: std::cell::RefCell<(usize, usize, Option>)> = + const { std::cell::RefCell::new((0, 0, None)) }; +} + #[inline] pub(crate) fn decode_slicesnp_cached(bytecode: &[u8]) -> std::sync::Arc { if bytecode.len() < 8 || &bytecode[0..8] != SNAPSHOT_MAGIC { @@ -2113,11 +2118,23 @@ pub(crate) fn decode_slicesnp_cached(bytecode: &[u8]) -> std::sync::Arc std::sync::Arc ({ + id: i, + label: "row-" + i, + nested: { x: i * 2, active: (i & 1) === 0 } + })) + ); + const batch = JSON.parse(batchText); + let sum = 0; + for (let i = 0; i < batch.length; i++) { + sum += batch[i].id + batch[i].nested.x; + } + + // Heterogeneous keys, duplicate keys, numeric index keys, and __proto__ own property + const hetero = JSON.parse('[{"a":1,"b":2},{"b":20,"a":10,"c":30},{"0":"zero","10":"ten","dup":1,"dup":2,"__proto__":{"admin":true}}]'); + const protoNotPolluted = ({}).admin === undefined; + const ownProtoDesc = Object.getOwnPropertyDescriptor(hetero[2], "__proto__"); + + // Reviver with `context.source` + const sources = []; + const revived = JSON.parse('{"big":9007199254740993,"flag":true}', (k, v, ctx) => { + if (k) sources.push(k + "=" + ctx.source); + return k === "big" ? ctx.source : v; + }); + + console.log(JSON.stringify({ + asciiEq: strParsed.ascii === longAscii, + utf16Eq: strParsed.utf16 === longUtf16, + loneOk: strParsed.loneHigh.charCodeAt(0) === 0xd800 && strParsed.loneLow.charCodeAt(4) === 0xdc00, + negZeroOk, + maxSafe: nums[5] === 9007199254740991, + minSafe: nums[6] === -9007199254740991, + infOk: nums[9] === Infinity, + sum, + heteroCheck: hetero[0].a === 1 && hetero[1].c === 30 && hetero[2]["0"] === "zero" && hetero[2]["10"] === "ten" && hetero[2].dup === 2, + protoNotPolluted, + ownProtoAdmin: Boolean(ownProtoDesc && ownProtoDesc.enumerable && ownProtoDesc.value.admin === true), + revivedBig: revived.big, + sources + })); + "#; + + let m = run_source_isolated( + "json-shape-tenant", + js, + CapabilityToken::pure_compute(), + 2_000_000, + 8 * 1024 * 1024, + ) + .unwrap(); + assert_eq!( + m.stdout[0], + r#"{"asciiEq":true,"utf16Eq":true,"loneOk":true,"negZeroOk":true,"maxSafe":true,"minSafe":true,"infOk":true,"sum":1488,"heteroCheck":true,"protoNotPolluted":true,"ownProtoAdmin":true,"revivedBig":"9007199254740993","sources":["big=9007199254740993","flag=true"]}"# + ); +} + +#[test] +fn test_fs_host_reads_directory_errors_symlinks_watch_and_lazy_promises() { + use crate::run_source_isolated; + use slice_sandbox::CapabilityToken; + + let tmp_dir = std::env::temp_dir().join(format!("slice_fs_host_test_{}", std::process::id())); + let sub_dir = tmp_dir.join("nested_dir"); + let _ = std::fs::remove_dir_all(&tmp_dir); + std::fs::create_dir_all(&sub_dir).unwrap(); + + let ascii_file = tmp_dir.join("ascii.txt"); + let utf8_file = tmp_dir.join("utf8.txt"); + std::fs::write(&ascii_file, b"hello-host-ascii-payload").unwrap(); + std::fs::write( + &utf8_file, + "Cafe \u{20ac}100 \u{65e5}\u{672c}\u{8a9e}".as_bytes(), + ) + .unwrap(); + + let tmp_norm = tmp_dir.to_string_lossy().replace('\\', "/"); + let sub_norm = sub_dir.to_string_lossy().replace('\\', "/"); + let ascii_norm = ascii_file.to_string_lossy().replace('\\', "/"); + let utf8_norm = utf8_file.to_string_lossy().replace('\\', "/"); + + let js = format!( + r#" + const fs = require("node:fs"); + const asciiTxt = fs.readFileSync({:?}, "utf8"); + const utf8Txt = fs.readFileSync({:?}, "utf8"); + const rawBytes = fs.readFileSync({:?}); + + let hostDirCode = ""; + try {{ fs.readFileSync({:?}, "utf8"); }} catch (e) {{ hostDirCode = e.code; }} + + fs.mkdirSync("/tmp/vfs-dir-check", {{ recursive: true }}); + let vfsDirCode = ""; + try {{ fs.readFileSync("/tmp/vfs-dir-check", "utf8"); }} catch (e) {{ vfsDirCode = e.code; }} + + fs.writeFileSync("/tmp/vfs-dir-check/target.txt", "symlink-body"); + fs.symlinkSync("/tmp/vfs-dir-check/target.txt", "/tmp/vfs-dir-check/link.txt"); + const linkTxt = fs.readFileSync("/tmp/vfs-dir-check/link.txt", "utf8"); + const isSym = fs.lstatSync("/tmp/vfs-dir-check/link.txt").isSymbolicLink(); + + const events = []; + const watcher = fs.watch("/tmp/vfs-dir-check", (ev, name) => events.push(ev + ":" + name)); + fs.writeFileSync("/tmp/vfs-dir-check/watched.txt", "ok"); + watcher.close(); + + const fsp = require("node:fs/promises"); + const samePromisesRef = (fs.promises === fsp); + fsp.readFile({:?}, "utf8").then((asyncTxt) => {{ + console.log(JSON.stringify({{ + asciiTxt, + utf8Len: utf8Txt.length, + rawLen: rawBytes.length, + hostDirCode, + vfsDirCode, + linkTxt, + isSym, + watchEvents: events.length, + samePromisesRef, + asyncMatch: asyncTxt === asciiTxt + }})); + }}); + "#, + ascii_norm, utf8_norm, ascii_norm, sub_norm, ascii_norm + ); + + let caps = CapabilityToken::pure_compute() + .with_read_prefix(&tmp_norm) + .with_read_prefix("/tmp") + .with_write_prefix("/tmp"); + let m = run_source_isolated("fs-host-tenant", &js, caps, 2_000_000, 8 * 1024 * 1024).unwrap(); + let _ = std::fs::remove_dir_all(&tmp_dir); + + assert_eq!( + m.stdout[0], + r#"{"asciiTxt":"hello-host-ascii-payload","utf8Len":13,"rawLen":24,"hostDirCode":"EISDIR","vfsDirCode":"EISDIR","linkTxt":"symlink-body","isSym":true,"watchEvents":1,"samePromisesRef":true,"asyncMatch":true}"# + ); +} + +#[test] +fn test_buffer_byte_length_encodings_and_array_buffer_views() { + use crate::run_source_isolated; + use slice_sandbox::CapabilityToken; + + let js = r#" + const asciiLen = Buffer.byteLength("hello-world", "utf8"); + const latin1HighUtf8 = Buffer.byteLength("\u00e9\u00ffA", "utf8"); + const latin1Raw = Buffer.byteLength("\u00e9\u00ffA", "latin1"); + const bmpAndAstralUtf8 = Buffer.byteLength("\u20ac\ud83d\ude80", "utf8"); + const loneSurrogateUtf8 = Buffer.byteLength("\ud800", "utf8"); + const utf16leLen = Buffer.byteLength("abcd", "utf16le"); + const hexLen = Buffer.byteLength("deadbeef01", "hex"); + const b64Padded = Buffer.byteLength("aGVsbG8=", "base64"); + const b64UrlUnpadded = Buffer.byteLength("aGVsbG8", "base64url"); + + const ab = new ArrayBuffer(32); + const sub = new Uint8Array(ab, 8, 12); + const dv = new DataView(ab, 4, 10); + const buf = Buffer.from("slice"); + + const { Writable } = require("node:stream"); + const w = new Writable({ highWaterMark: 16, write(_c, _e, cb) { cb(null); } }); + w.write("\u20ac\u20ac"); // 6 UTF-8 bytes without needing explicit Buffer import + + console.log(JSON.stringify({ + asciiLen, + latin1HighUtf8, + latin1Raw, + bmpAndAstralUtf8, + loneSurrogateUtf8, + utf16leLen, + hexLen, + b64Padded, + b64UrlUnpadded, + abLen: Buffer.byteLength(ab), + subLen: Buffer.byteLength(sub), + dvLen: Buffer.byteLength(dv), + bufLen: Buffer.byteLength(buf) + })); + "#; + + let m = run_source_isolated( + "buf-bytelen-tenant", + js, + CapabilityToken::pure_compute(), + 1_000_000, + 4 * 1024 * 1024, + ) + .unwrap(); + assert_eq!( + m.stdout[0], + r#"{"asciiLen":11,"latin1HighUtf8":5,"latin1Raw":3,"bmpAndAstralUtf8":7,"loneSurrogateUtf8":3,"utf16leLen":8,"hexLen":5,"b64Padded":5,"b64UrlUnpadded":5,"abLen":32,"subLen":12,"dvLen":10,"bufLen":5}"# + ); +} + +#[test] +fn test_shard_isolation_for_node_crypto_process_cli_intl_dom_exception_and_streams() { + use crate::boacas::compute_boacas_metadata; + use crate::run_source_isolated; + use slice_sandbox::CapabilityToken; + + // 1. `node:crypto` (`crypto.createHash`) must NOT pull in Shard 4 (`WebCrypto`, bit 4) + let (_, node_crypto_mask, _) = compute_boacas_metadata( + r#"const crypto = require("node:crypto"); const h = crypto.createHash("sha256").update("x").digest("hex");"#, + ); + assert_ne!(node_crypto_mask & (1u32 << 19), 0); + assert_eq!(node_crypto_mask & (1u32 << 4), 0); + + // WebCrypto (`crypto.randomUUID`, `crypto.subtle`, `globalThis.crypto`) MUST pull in Shard 4 + let (_, web_crypto_mask, _) = compute_boacas_metadata(r#"const id = crypto.randomUUID();"#); + assert_ne!(web_crypto_mask & (1u32 << 4), 0); + + // 2. `AbortController` must NOT pull in Shard 6 (`06_console_ext.js`) + let (_, abort_mask, _) = compute_boacas_metadata(r#"const ac = new AbortController();"#); + assert_ne!(abort_mask & (1u32 << 10), 0); + assert_ne!(abort_mask & (1u32 << 13), 0); + assert_eq!(abort_mask & (1u32 << 6), 0); + + // 3. `process.stdout` / `hrtime` / `node:process` must load Shard 29 (`19_process_cli.js`) without Shard 18 (`18_intl.js`) + let (_, proc_cli_mask, _) = compute_boacas_metadata( + r#"const p = require("node:process"); const t = process.hrtime.bigint(); process.stdout.write(String(t));"#, + ); + assert_ne!(proc_cli_mask & (1u32 << 29), 0); + assert_eq!(proc_cli_mask & (1u32 << 18), 0); + + let (_, intl_mask, _) = + compute_boacas_metadata(r#"const nf = new Intl.NumberFormat("en-US");"#); + assert_ne!(intl_mask & (1u32 << 18), 0); + + // 4. Runtime execution of `process` CLI, `Intl`, `DOMException` lazy stack, and `ReadableStream` + let runtime_js = r#" + let evFired = false; + process.on("customCliEvent", (v) => { evFired = (v === 99); }); + process.emit("customCliEvent", 99); + const hr = process.hrtime(); + const formatted = new Intl.NumberFormat("en-US").format(12345); + + const domErr = new DOMException("timed out", "TimeoutError"); + const stackBefore = domErr.stack; + domErr.stack = "custom-stack"; + + const rs = new ReadableStream({ + start(ctrl) { + ctrl.enqueue("chunk-1"); + }, + pull(ctrl) { + ctrl.enqueue("chunk-2"); + ctrl.close(); + } + }); + const reader = rs.getReader(); + Promise.all([reader.read(), reader.read(), reader.read()]).then((steps) => { + console.log(JSON.stringify({ + evFired, + hrPair: Array.isArray(hr) && hr.length === 2, + formatted, + domCode: domErr.code, + domConst: DOMException.TIMEOUT_ERR, + stackHasName: stackBefore.indexOf("TimeoutError: timed out") === 0, + stackOverridden: domErr.stack === "custom-stack", + chunks: [steps[0].value, steps[1].value, steps[2].done] + })); + }); + "#; + let m = run_source_isolated( + "shard-runtime-tenant", + runtime_js, + CapabilityToken::pure_compute(), + 2_000_000, + 8 * 1024 * 1024, + ) + .unwrap(); + assert_eq!( + m.stdout[0], + r#"{"evFired":true,"hrPair":true,"formatted":"12,345","domCode":23,"domConst":23,"stackHasName":true,"stackOverridden":true,"chunks":["chunk-1","chunk-2",true]}"# + ); +} + +#[test] +fn test_http_fast_outcome_and_server_websocket_dispatch() { + use crate::{compile_source_to_bytecode, HttpRequestContext, ServerWsOutFrame, SliceIsolate}; + use slice_sandbox::CapabilityToken; + + // 1. Tier-0 SLICESNP fast HTTP dispatch + pointer-cached `decode_slicesnp_cached` + let tier0_bc = compile_source_to_bytecode("const a = 200; const b = 56; return a + b;"); + let mut iso = SliceIsolate::spawn( + "http-fast-tenant", + 1, + CapabilityToken::pure_compute(), + 5_000_000, + 4 * 1024 * 1024, + ); + let req = HttpRequestContext { + method: "GET", + path: "/calc", + query: "x=1", + tenant_id: "http-fast-tenant", + body: "", + headers: &[("host", "localhost")], + }; + for slot in 1..=3 { + iso.reset_for_request("http-fast-tenant", slot, 5_000_000, 4 * 1024 * 1024); + let out = iso + .execute_http_request_fast(&tier0_bc, None, &req) + .unwrap(); + assert_eq!(out.status_code, 200); + assert_eq!(out.content_type, "application/json"); + assert_eq!(out.response_body, "256"); + } + + // 2. Tier-1 SLICEBC custom `Slice.respond` + `Slice.waitUntil` + Egress DLP guard + let wintertc_bc = compile_source_to_bytecode( + r#" + const r = Slice.request(); + Slice.waitUntil(() => { Slice.kv.set("wu_path", r.path, 0); }); + Slice.respond(201, JSON.stringify({ created: r.path }), "application/json", [["x-edge", "ok"]]); + "#, + ); + iso.reset_for_request("http-fast-tenant", 10, 5_000_000, 4 * 1024 * 1024); + let out_w = iso + .execute_http_request_fast(&wintertc_bc, None, &req) + .unwrap(); + assert_eq!(out_w.status_code, 201); + assert_eq!(out_w.response_body, r#"{"created":"/calc"}"#); + assert_eq!(out_w.wait_until_count, 1); + assert_eq!(iso.drain_wait_until_tasks().unwrap(), 1); + assert_eq!(iso.kv_get("wu_path").as_deref(), Some("/calc")); + + // Egress DLP must also block secret exfiltration on `execute_http_request_fast` + iso.add_egress_audit_secret("sk_live_topsecret999"); + let leak_bc = + compile_source_to_bytecode(r#"Slice.respond(200, "token=sk_live_topsecret999");"#); + iso.reset_for_request("http-fast-tenant", 11, 5_000_000, 4 * 1024 * 1024); + assert!(iso.execute_http_request_fast(&leak_bc, None, &req).is_err()); + + // 3. Direct callable server WebSocket frame dispatch (`execute_websocket_event`) + let mut ws_iso = SliceIsolate::spawn( + "ws-fast-tenant", + 20, + CapabilityToken::pure_compute(), + 5_000_000, + 4 * 1024 * 1024, + ); + let ws_setup_bc = compile_source_to_bytecode( + r#" + Slice.onWebSocket({ + message(ws, data) { + ws.send("ack:" + String(data)); + } + }); + "#, + ); + ws_iso.execute_bytecode(&ws_setup_bc, None).unwrap(); + let frames = ws_iso + .execute_websocket_event("message", false, b"ping-payload", 0, "") + .unwrap(); + assert_eq!(frames.len(), 1); + match &frames[0] { + ServerWsOutFrame::Text(t) => assert_eq!(t, "ack:ping-payload"), + other => panic!("expected text frame, got {:?}", other), + } +} diff --git a/docs/general/00_index.md b/docs/general/00_index.md index e2430d0..dc1f428 100644 --- a/docs/general/00_index.md +++ b/docs/general/00_index.md @@ -1,6 +1,6 @@ -# The Slice (Nexus-JS) Developer Handbook (`v0.10.11`) +# The Slice (Nexus-JS) Developer Handbook (`v0.10.12`) -Welcome to the complete developer handbook for **Slice (Nexus-JS)** (`v0.10.11`) — a microVM-grade JavaScript and TypeScript runtime, compiler, HTTP server, and AI sandbox engineered in Rust. +Welcome to the complete developer handbook for **Slice (Nexus-JS)** (`v0.10.12`) — a microVM-grade JavaScript and TypeScript runtime, compiler, HTTP server, and AI sandbox engineered in Rust. Whether you are building a high-throughput full-stack web service, packaging a CLI tool into a single zero-dependency executable, running 1,000 untrusted customer plugins on a single machine, or executing LLM-generated TypeScript inside an AI coding agent, this handbook walks you through every feature, CLI command, API, security capability, and migration pattern from the perspective of an application developer. diff --git a/docs/general/01_getting_started_and_cli.md b/docs/general/01_getting_started_and_cli.md index 6fdc054..54a003d 100644 --- a/docs/general/01_getting_started_and_cli.md +++ b/docs/general/01_getting_started_and_cli.md @@ -1,6 +1,6 @@ # Chapter 01: Installation, Upgrading, Quickstart, `slice.toml` & Complete CLI Reference -This chapter is your complete day-one guide to installing, upgrading, configuring, and operating **Slice (Nexus-JS)** (`v0.10.11`). By the end of this chapter, you will know how to install and update Slice on any operating system, scaffold a new TypeScript project, configure your `slice.toml` manifest and `.env` vault, run live development with `< 3 ms` `--watch` reloads, use the interactive `slice repl` shell, and master all 13 CLI commands. +This chapter is your complete day-one guide to installing, upgrading, configuring, and operating **Slice (Nexus-JS)** (`v0.10.12`). By the end of this chapter, you will know how to install and update Slice on any operating system, scaffold a new TypeScript project, configure your `slice.toml` manifest and `.env` vault, run live development with `< 3 ms` `--watch` reloads, use the interactive `slice repl` shell, and master all 13 CLI commands. --- @@ -545,7 +545,7 @@ Launches an interactive **SES-Locked TypeScript/JavaScript Compartment Shell** w **Example REPL Session:** ```text $ slice repl -Slice (Nexus-JS) v0.10.11 Interactive SES-Locked Compartment Shell +Slice (Nexus-JS) v0.10.12 Interactive SES-Locked Compartment Shell Commands: :help, :metrics, :caps, :vars, :reset, :quit slice(ses)> const price: number = 250 * 4; => 1000 diff --git a/docs/general/09_benchmarks_testing_and_docker_suite.md b/docs/general/09_benchmarks_testing_and_docker_suite.md index 4b4aa34..bcfaf4c 100644 --- a/docs/general/09_benchmarks_testing_and_docker_suite.md +++ b/docs/general/09_benchmarks_testing_and_docker_suite.md @@ -147,45 +147,45 @@ Slice includes a comprehensive Linux `x86_64` Docker benchmark suite ([`tests/`] ### 4.1 Verified Results Across All 33 Production Applications, Frameworks & Case Studies ([`tests/reports/latest.md`](../../tests/reports/latest.md)) -> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](../../tests/reports/latest.md)** (Archive: [`bench_v0.10.11_20261111_055407Z_898e90b.md`](../../tests/reports/bench_v0.10.11_20261111_055407Z_898e90b.md)) -> **Provenance:** Slice `v0.10.11` (`898e90b`) · Generated `2026-11-11T05:54:07Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` -> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **28/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. +> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](../../tests/reports/latest.md)** (Archive: [`bench_v0.10.12_20261111_175836Z_dc31f74.md`](../../tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md)) +> **Provenance:** Slice `v0.10.12` (`dc31f74`) · Generated `2026-11-11T17:58:36Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **29/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. #### 1. Core Architecture, HTTP Throughput & 1,000-Tenant MicroVM Density -| Metric | Slice (`v0.10.11` `SLICEBC\x01`) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Advantage | +| Metric | Slice (`v0.10.12` `SLICEBC\x01`) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Advantage | | :--- | :---: | :---: | :---: | :---: | :--- | -| **In-Process Isolate Cold Start (`P50` / `P99`)** | **`1.23 us` / `2.03 us`** | N/A (Process/VM) | N/A (Process/VM) | N/A (Process/VM) | **~120,000x faster than 125ms Firecracker VM** | -| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.47 ms` (`9.70 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | +| **In-Process Isolate Cold Start (`P50` / `P99`)** | **`1.02 us` / `4.27 us`** | N/A (Process/VM) | N/A (Process/VM) | N/A (Process/VM) | **~120,000x faster than 125ms Firecracker VM** | +| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.74 ms` (`9.82 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | | **500-Module Monorepo Cold Boot (`stat()` Calls)** | **`3.41 ms` (`0 stat()`)** | `12.72 ms` (`500+ stat`) | `41.80 ms` (`500+ stat`) | `70.38 ms` (`1,500+ stat`) | **`3.7x` faster than Bun / `20.6x` Node.js** | -| **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`153,174 req/s`** (Tier-0)
**`145,192 req/s`** (Tier-1) | `101,093 req/s` | `99,307 req/s` | `54,637 req/s` | **`1.52x` (`Tier-0`) / `1.44x` (`Tier-1`) vs `Bun.serve`** | -| **Peak Process Memory (`Max RSS` Across Suite)** | **`14.25 – 21.88 MB`** | `26.13 – 41.13 MB` | `45.53 – 61.75 MB` | `69.91 – 93.12 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | +| **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`154,794 req/s`** (Tier-0)
**`147,564 req/s`** (Tier-1) | `100,562 req/s` | `99,082 req/s` | `56,447 req/s` | **`1.54x` (`Tier-0`) / `1.47x` (`Tier-1`) vs `Bun.serve`** | +| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.45 – 21.63 MB`** | `26.13 – 40.25 MB` | `45.69 – 62.38 MB` | `70.15 – 93.00 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | | **Multi-Tenant Security Containment** | **`5 / 5 PASS`** (OCap+SES+Fuel+DLP) | `0 / 5` (Ambient) | `2 / 5` (Coarse CLI) | `0 / 5` (Ambient) | **Hardware & Language Zero-Trust Isolation** | #### 2. Real-Life Workload Summary by Domain (All 33 Workloads Aggregated) | Workload Domain & Stack Coverage | Suites | Slice Cold `.cas` Avg (Range) | Slice Warm (`--warm`) Avg | Bun `v1.4.4` Avg | Deno `v2.9.8` Avg | Node.js `v27.0.0-alpha.0.0.0` Avg | Category Speedup vs Bun / Node.js | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- | -| **Core Edge, Auth & Crypto (`Apps 01, 04, 05, 16`)**
Multi-file TS, SHA-256/HMAC, JWT/OAuth2, `.env` Auto-DLP | `4` | **`8.21 ms`** (`6.70–10.51 ms`) | **`3.72 ms`** | `14.26 ms` | `41.57 ms` | `62.14 ms` | **`1.74x Bun` (`3.83x` Warm) / `7.57x Node`** | -| **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`11.43 ms`** (`7.62–14.79 ms`) | **`4.37 ms`** | `17.40 ms` | `48.13 ms` | `66.84 ms` | **`1.52x Bun` (`3.98x` Warm) / `5.85x Node`** | -| **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`16.13 ms`** (`8.52–30.84 ms`) | **`8.10 ms`** | `18.60 ms` | `52.66 ms` | `95.09 ms` | **`1.15x Bun` (`2.29x` Warm) / `5.90x Node`** | -| **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.24 ms`** (`8.74–20.16 ms`) | **`2.93 ms`** | `28.64 ms` | `63.70 ms` | `86.48 ms` | **`2.01x Bun` (`9.77x` Warm) / `6.07x Node`** | -| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`20.59 ms`** (`15.22–32.08 ms`) | **`8.39 ms`** | `29.73 ms` | `56.05 ms` | `94.07 ms` | **`1.44x Bun` (`3.54x` Warm) / `4.57x Node`** | -| **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`20.58 ms`** (`13.69–32.18 ms`) | **`6.77 ms`** | `20.18 ms` | `54.28 ms` | `79.15 ms` | **`0.98x Bun` (`2.98x` Warm) / `3.85x Node`** | +| **Core Edge, Auth & Crypto (`Apps 01, 04, 05, 16`)**
Multi-file TS, SHA-256/HMAC, JWT/OAuth2, `.env` Auto-DLP | `4` | **`7.84 ms`** (`6.28–10.07 ms`) | **`2.17 ms`** | `14.52 ms` | `42.60 ms` | `62.07 ms` | **`1.85x Bun` (`6.69x` Warm) / `7.92x Node`** | +| **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`10.94 ms`** (`7.25–14.23 ms`) | **`3.16 ms`** | `17.64 ms` | `48.12 ms` | `65.89 ms` | **`1.61x Bun` (`5.59x` Warm) / `6.02x Node`** | +| **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`15.45 ms`** (`8.12–29.33 ms`) | **`7.31 ms`** | `18.48 ms` | `52.47 ms` | `93.96 ms` | **`1.20x Bun` (`2.53x` Warm) / `6.08x Node`** | +| **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.25 ms`** (`8.72–20.99 ms`) | **`2.48 ms`** | `28.68 ms` | `62.87 ms` | `86.44 ms` | **`2.01x Bun` (`11.57x` Warm) / `6.07x Node`** | +| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`20.74 ms`** (`14.65–34.19 ms`) | **`7.47 ms`** | `29.22 ms` | `54.14 ms` | `93.40 ms` | **`1.41x Bun` (`3.91x` Warm) / `4.50x Node`** | +| **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`21.17 ms`** (`13.17–34.84 ms`) | **`6.27 ms`** | `20.96 ms` | `56.54 ms` | `80.98 ms` | **`0.99x Bun` (`3.34x` Warm) / `3.82x Node`** | #### 3. Flagship Real-World Representative Workloads (9 of 33 Highlights) | # | Flagship Workload | Slice Cold `.cas` | Slice Warm (`--warm`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :--- | -| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.70 ms`** | **`1.68 ms`** | `13.45 ms` | `35.70 ms` | `59.15 ms` | **`2.01x Bun` (`8.01x` Warm) / `8.83x Node`** | -| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.62 ms`** | **`1.72 ms`** | `13.79 ms` | `45.41 ms` | `61.73 ms` | **`1.81x Bun` (`8.00x` Warm) / `8.10x Node`** | -| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`16.69 ms`** | **`7.97 ms`** | `21.63 ms` | `53.17 ms` | `112.88 ms` | **`1.30x Bun` (`2.71x` Warm) / `6.76x Node`** | -| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.30 ms`** | **`0.61 ms`** | `22.40 ms` | `55.00 ms` | `76.30 ms` | **`1.98x Bun` (`36.60x` Warm) / `6.75x Node`** | -| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.16 ms`** | **`2.23 ms`** | `55.92 ms` | `112.63 ms` | `101.84 ms` | **`2.77x Bun` (`25.10x` Warm) / `5.05x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.22 ms`** | **`5.63 ms`** | `19.63 ms` | `52.60 ms` | `94.61 ms` | **`1.29x Bun` (`3.49x` Warm) / `6.22x Node`** | -| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`32.08 ms`** | **`16.95 ms`** | `43.52 ms` | `74.25 ms` | `112.27 ms` | **`1.36x Bun` (`2.57x` Warm) / `3.50x Node`** | -| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.71 ms`** | **`13.02 ms`** | `28.39 ms` | `72.12 ms` | `88.96 ms` | **`0.88x Bun` (`2.18x` Warm) / `2.76x Node`** | -| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.21 ms`** | **`7.92 ms`** | `20.31 ms` | `62.71 ms` | `84.14 ms` | **`1.11x Bun` (`2.56x` Warm) / `4.62x Node`** | +| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.28 ms`** | **`1.05 ms`** | `13.38 ms` | `35.22 ms` | `58.45 ms` | **`2.13x Bun` (`12.74x` Warm) / `9.31x Node`** | +| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.25 ms`** | **`1.29 ms`** | `14.08 ms` | `43.23 ms` | `61.79 ms` | **`1.94x Bun` (`10.92x` Warm) / `8.52x Node`** | +| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.83 ms`** | **`6.70 ms`** | `21.20 ms` | `56.40 ms` | `108.62 ms` | **`1.34x Bun` (`3.17x` Warm) / `6.86x Node`** | +| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.26 ms`** | **`0.50 ms`** | `25.08 ms` | `55.78 ms` | `73.35 ms` | **`2.23x Bun` (`50.56x` Warm) / `6.51x Node`** | +| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.99 ms`** | **`1.74 ms`** | `57.15 ms` | `114.02 ms` | `101.72 ms` | **`2.72x Bun` (`32.86x` Warm) / `4.85x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`14.65 ms`** | **`5.59 ms`** | `19.86 ms` | `51.15 ms` | `94.15 ms` | **`1.36x Bun` (`3.55x` Warm) / `6.43x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`34.37 ms`** | **`14.26 ms`** | `43.71 ms` | `68.04 ms` | `108.54 ms` | **`1.28x Bun` (`3.07x` Warm) / `3.17x Node`** | +| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.84 ms`** | **`12.99 ms`** | `28.86 ms` | `73.55 ms` | `91.05 ms` | **`0.83x Bun` (`2.22x` Warm) / `2.61x Node`** | +| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.14 ms`** | **`8.32 ms`** | `21.10 ms` | `65.54 ms` | `86.65 ms` | **`1.16x Bun` (`2.54x` Warm) / `4.78x Node`** | *Full 33-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](../../tests/reports/latest.md)**.* diff --git a/docs/general/COMPATIBILITY.md b/docs/general/COMPATIBILITY.md index 9f26853..8ccad1f 100644 --- a/docs/general/COMPATIBILITY.md +++ b/docs/general/COMPATIBILITY.md @@ -8,7 +8,7 @@ Instead of embedding a heavyweight OS process runtime like libuv/V8, Slice targe ## 1. WinterTC Minimum Common Web API (100% Supported) -All WinterTC globals are available in every isolate out of the box. Under the hood, Slice maintains human-readable JavaScript prelude sources in `crates/slice-engine/src/preludes/*.js`, compiles and minifies them deterministically at Rust build time (`crates/slice-engine/build.rs`), and evaluates only a ~6 KB ultra-core bootstrap (`00_ultra_core.js`) when creating a realm. All 18 feature shards (`URL`, `TextEncoder`, `ReadableStream`, `WebCrypto`, `Buffer`, `console.*` extensions, `WebSocket`, `Worker`/Sockets, `WebAssembly`, `fetch`/SSE, `Headers`/`Request`/`Response`, `URLPattern`, `Event`/`EventTarget`, `TransformStream`/`CompressionStream`, `Blob`/`File`/`FormData`, `structuredClone`, `Buffer` binary R/W, and `Intl`/`navigator`/`location`/`process` CLI extensions) are loaded on demand via pre-fused `SLICEBC\x01` bitmasks or self-replacing lazy property getters on `globalThis` so scripts that do not touch a subsystem pay `0 bytes` of parse or evaluation cost: +All WinterTC globals are available in every isolate out of the box. Under the hood, Slice maintains human-readable JavaScript prelude sources in `crates/slice-engine/src/preludes/*.js`, compiles and minifies them deterministically at Rust build time (`crates/slice-engine/build.rs`), and evaluates only a ~6 KB ultra-core bootstrap (`00_ultra_core.js`) when creating a realm. All 19 feature shards (`URL`, `TextEncoder`, `ReadableStream`, `WebCrypto`, `Buffer`, `console.*` extensions, `WebSocket`, `Worker`/Sockets, `WebAssembly`, `fetch`/SSE, `Headers`/`Request`/`Response`, `URLPattern`, `Event`/`EventTarget`, `TransformStream`/`CompressionStream`, `Blob`/`File`/`FormData`, `structuredClone`, `Buffer` binary R/W, `Intl`, and `navigator`/`location`/`process` CLI extensions) are loaded on demand via pre-fused `SLICEBC\x01` bitmasks or self-replacing lazy property getters on `globalThis` so scripts that do not touch a subsystem pay `0 bytes` of parse or evaluation cost: | Category | Global / API | Support Status | Implementation Notes | | :--- | :--- | :--- | :--- | @@ -26,7 +26,7 @@ All WinterTC globals are available in every isolate out of the box. Under the ho | **Events & Signals** | `Event`, `CustomEvent`, `EventTarget`, `AbortController`, `AbortSignal` | **100% Supported** | Listener registration (`once`, `passive`, `signal`), `AbortSignal.abort()`, `AbortSignal.timeout(ms)`, `AbortSignal.any(signals)`, and `DOMException`. | | **Timers & Microtasks** | `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval`, `setImmediate`, `clearImmediate`, `queueMicrotask`, `process.nextTick` | **100% Supported** | $O(1)$ Slab-Allocated Hierarchical Timer Wheel with strict priority ordering (`sync -> process.nextTick -> Promise.then / queueMicrotask -> setImmediate -> setTimeout(0)`), deterministic virtual time-warp (`0 ns` wall-clock wait during cassette tests), and real non-blocking concurrency on live sockets. | | **Cloning & Diagnostics** | `structuredClone`, `performance.now()`, `console.*` (`log`, `info`, `warn`, `error`, `debug`, `table`, `time`, `timeLog`, `timeEnd`, `group`, `groupCollapsed`, `groupEnd`, `dir`, `dirxml`, `count`, `countReset`, `assert`, `trace`, `clear`) | **100% Supported** | Graph-preserving cyclic `structuredClone` (`Map`, `Set`, `Date`, `RegExp`, `ArrayBuffer`, `Uint8Array`, `Error`, `transfer` list) and full WHATWG `console.*` specification routed through the Outbound Egress Secret DLP Firewall (with deterministic elapsed timing under `--deterministic`). | -| **Internationalization & WinterTC Globals** | `Intl` (`DateTimeFormat`, `NumberFormat`, `Collator`, `PluralRules`, `Segmenter`, `getCanonicalLocales`, `supportedValuesOf`), `navigator`, `location` | **100% Supported** | Zero-ICU-bloat deterministic `Intl` fast-path shard (`18_intl.js`) supporting `Date.prototype.toLocale*`, `Number.prototype.toLocaleString` (`decimal`, `currency`, `percent`, `unit`, `formatToParts`), `String.prototype.localeCompare`, `PluralRules` (`cardinal`, `ordinal`), `Segmenter` (`grapheme`, `word`, `sentence`), plus WinterTC `navigator` (`userAgent: "Slice-NexusJS/0.10.11"`, `hardwareConcurrency`, `language`, `languages`) and `location`. | +| **Internationalization & WinterTC Globals** | `Intl` (`DateTimeFormat`, `NumberFormat`, `Collator`, `PluralRules`, `Segmenter`, `getCanonicalLocales`, `supportedValuesOf`), `navigator`, `location` | **100% Supported** | Zero-ICU-bloat deterministic `Intl` fast-path shard (`18_intl.js`) supporting `Date.prototype.toLocale*`, `Number.prototype.toLocaleString` (`decimal`, `currency`, `percent`, `unit`, `formatToParts`), `String.prototype.localeCompare`, `PluralRules` (`cardinal`, `ordinal`), and `Segmenter` (`grapheme`, `word`, `sentence`), decoupled from the lightweight `19_process_cli.js` shard providing WinterTC `navigator`, `location`, and the complete `process` CLI surface (`stdout`, `stderr`, `stdin`, `hrtime`, `memoryUsage`, `on`/`emit`). | | **JSX / TSX & Edge SSR** | Native `.tsx` / `.jsx` compilation + `slice:jsx` (`react/jsx-runtime`, `preact/jsx-runtime`, `hono/jsx`) | **100% Supported** | Native Rust Oxc JSX/TSX compiler (`runtime: automatic`) paired with a built-in zero-dependency SSR engine (`renderToString`, `jsx`, `jsxs`, `jsxDEV`, `Fragment`, `createElement`/`h`, `raw`) featuring automatic HTML & attribute XSS escaping, void tag handling, and camelCase `style` object serialization. | --- diff --git a/docs/guides/README.md b/docs/guides/README.md index 0d07331..eab7deb 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -1,6 +1,6 @@ # Slice (Nexus-JS) — Developer How-To Guides (`docs/guides/`) -This directory contains practical step-by-step developer guides, production deployment how-tos, and ecosystem integration recipes for Slice (`v0.10.11`): +This directory contains practical step-by-step developer guides, production deployment how-tos, and ecosystem integration recipes for Slice (`v0.10.12`): ## Available Guides diff --git a/docs/system/00_index.md b/docs/system/00_index.md index 7cdf824..c440635 100644 --- a/docs/system/00_index.md +++ b/docs/system/00_index.md @@ -1,4 +1,4 @@ -# Slice (Nexus-JS): System Architecture & Internal Specification Index (`v0.10.11`) +# Slice (Nexus-JS): System Architecture & Internal Specification Index (`v0.10.12`) Welcome to the **Slice (Nexus-JS)** System Architecture and Internal Specification (`docs/system/`). Engineered in pure Rust (`edition = 2021`, `opt-level = 3`, `lto = "fat"`, `codegen-units = 1`, `panic = "abort"`), Slice replaces the legacy POSIX + monolithic V8/JSC assumptions of Node.js, Deno, and Bun with four orthogonal, tightly integrated Rust crates: @@ -21,7 +21,7 @@ Welcome to the **Slice (Nexus-JS)** System Architecture and Internal Specificati | **[`05_wasm_workers_and_kernel_io.md`](./05_wasm_workers_and_kernel_io.md)** | Pure-Rust WebAssembly (`wasmi` `v2.0.0`, `GLOBAL_WASM_MODULE_CACHE`, 5-Ring WASM Cage), Capability-Attenuated MicroVM Web Workers & `node:worker_threads` (`IDLE_WORKER_POOL`), Direct Kernel Completion Rings (`io_uring` & `IOCP`), & OS-Native `notify` File Watcher | `crates/slice-engine/src/{wasm,workers}.rs`, `crates/slice-io/src/lib.rs`, `crates/slice-cli/src/config_and_watch.rs` | | **[`06_edge_kv_ai_sandbox_and_mcp.md`](./06_edge_kv_ai_sandbox_and_mcp.md)** | 16-Way Sharded `Slice.kv` (`EDGE_KV_SLAB`), Multi-Tenant `--tenant-dir` Atomic Hot-Swap, SplitMix64 `--deterministic` Replay, AI Agent "Code Mode" (`Slice.evalSandbox`, `< 5 us` `Slice.checkpoint`/`restore`), Time-Travel `slice test`, & Built-In MCP Server (`slice mcp`) | `crates/slice-engine/src/state_and_kv.rs`, `crates/slice-cli/src/{test_runner,mcp_and_repl}.rs` | | **[`07_production_tooling_guide.md`](./07_production_tooling_guide.md)** | Production CLI Reference, Unified 4-Layer Configuration System (`slice.toml`, Inline `// @slice-...`, `SLICE_*` Env Vars, CLI Flags), Docker & Kubernetes Deployment Patterns, and Multi-Tenant Operations | `crates/slice-cli/src/{main,config_and_watch}.rs`, `crates/slice-sandbox/src/lib.rs` | -| **[`08_benchmarks_and_comparisons.md`](./08_benchmarks_and_comparisons.md)** | Complete 4-Runtime Empirical Benchmark Suite (Slice `v0.10.11` vs Node.js `v25.8.1`, Deno `v2.7.5`, and Bun `v1.3.10`) Across All 31 Applications, Framework Suites & Case Studies | `benches/`, `tests/apps/`, `tests/frameworks/`, `tests/case_studies/` | +| **[`08_benchmarks_and_comparisons.md`](./08_benchmarks_and_comparisons.md)** | Complete 4-Runtime Empirical Benchmark Suite (Slice `v0.10.12` vs Node.js `v25.8.1`, Deno `v2.7.5`, and Bun `v1.3.10`) Across All 31 Applications, Framework Suites & Case Studies | `benches/`, `tests/apps/`, `tests/frameworks/`, `tests/case_studies/` | | **[`09_research_deep_dive.md`](./09_research_deep_dive.md)** | Foundational Systems Research Paper: Breaking the JS/TS Cold-Start, Memory Density, and Multi-Tenant Security Wall | Architectural Research Blueprint | | **[`vendor/boa_engine/SLICE_PATCH.md`](../../vendor/boa_engine/SLICE_PATCH.md)** | `SLICEBC1` Precompiled `CodeBlock` Binary Serializer/Deserializer & Deferred Function Span Architecture | `vendor/boa_engine/src/{slice_precompile.rs,lib.rs,vm/opcode/call/mod.rs}` | @@ -31,7 +31,7 @@ Welcome to the **Slice (Nexus-JS)** System Architecture and Internal Specificati ``` +---------------------------------------------------------------------------------------------------+ -| Slice (Nexus-JS) v0.10.11 Host | +| Slice (Nexus-JS) v0.10.12 Host | | | | +---------------------------------------------------------------------------------------------+ | | | slice-sandbox: Zero-Trust OCap, SES & Hardware Boundary | | diff --git a/docs/system/07_production_tooling_guide.md b/docs/system/07_production_tooling_guide.md index e53d5d3..76babe5 100644 --- a/docs/system/07_production_tooling_guide.md +++ b/docs/system/07_production_tooling_guide.md @@ -2,7 +2,7 @@ ## 1. Overview of the Production Toolchain -Slice `v0.10.11` provides a complete developer and production deployment workflow packaged inside a single self-contained native Rust executable (`slice`, embedding the **Oxc** TypeScript compiler, transitive `node_modules` bundler, **Boa** ES2024+ VM, and **Slice** Zero-Stat CAS + Tier-0/Tier-2 engine): +Slice `v0.10.12` provides a complete developer and production deployment workflow packaged inside a single self-contained native Rust executable (`slice`, embedding the **Oxc** TypeScript compiler, transitive `node_modules` bundler, **Boa** ES2024+ VM, and **Slice** Zero-Stat CAS + Tier-0/Tier-2 engine): 1. **Project Initialization & Policy Configuration (`slice init` & `slice.toml`)** 2. **Zero-Stat Content-Addressed Packaging (`slice pack` for single files or full `package.json` + `node_modules` folders)** diff --git a/docs/system/08_benchmarks_and_comparisons.md b/docs/system/08_benchmarks_and_comparisons.md index 60af6c9..54389ba 100644 --- a/docs/system/08_benchmarks_and_comparisons.md +++ b/docs/system/08_benchmarks_and_comparisons.md @@ -266,7 +266,7 @@ All compute, array pipeline, and security containment benchmarks execute through | **Deterministic Time-Travel Event Loop ([`event_loop.rs`](../../crates/slice-engine/src/runtime/event_loop.rs)), Slab Timer Wheel, `AbortSignal`, & Concurrent `Promise.all` Fetch Multiplexer** | Zero-cost synchronous bypass (`ACTIVE_ASYNC_ITEMS`), deterministic `(deadline_ms, id)` timer wheel (`setTimeout`, `clearTimeout`, `setInterval`, `clearInterval`, `queueMicrotask`), `0 ns` Virtual Time-Warp (`BOA_DET_STATE`), `AbortController` / `AbortSignal.timeout(ms)`, and parallel `Promise.all([fetch(...)])` worker fan-out | **`66,000 ms` deterministic retry timer suite executes in `< 50 ms` of wall time; 4x60ms parallel `Promise.all` fan-out + 35ms `AbortSignal.timeout` completes in `< 150 ms`; 100% Node.js parity on App 18 (`18-async-event-loop-fanout-scheduler`, `auditDigest: 0b76cd366dc934f2`)** | | **Complete WinterTC Minimum Common Web Platform API ([`boa_realm.rs`](../../crates/slice-engine/src/runtime/boa_realm.rs), [`intrinsics.rs`](../../crates/slice-engine/src/intrinsics/mod.rs))** | Direct `JsArrayBuffer`/`JsUint8Array` Rust host bridge, `TextEncoder` (`encode`, `encodeInto`) & `TextDecoder` (`fatal`), WhatWG `btoa`/`atob`, deterministic `crypto.randomUUID()` & `crypto.getRandomValues()`, `crypto.subtle` (`digest` SHA-1/256/384/512, `importKey`/`exportKey` raw & JWK, `sign`/`verify` HMAC, `timingSafeEqual`), `EventTarget`, `CustomEvent`, `AbortSignal.any`, `Blob`/`File`/`FormData`, cyclic `structuredClone`, and `ReadableStream`/`WritableStream`/`TransformStream`/`TextEncoderStream`/`TextDecoderStream` | **Pre-baked in `WarmBoaRealm` (`0.00 ns` per-request overhead, `1.20 us` min isolate cold-start preserved); 100% deterministic WebCrypto replay across isolates; 100% NIST FIPS-180-4 SHA-1/256/384/512 & Node.js parity on App 19 (`19-wintertc-webcrypto-streams-edge`, `auditDigest: 7319225b3dc10146`)** | | **Real `Uint8Array`-Backed `Buffer`, Node Core Tier-1 Modules, & Oxc AST Module Bundler ([`boa_realm.rs`](../../crates/slice-engine/src/runtime/boa_realm.rs), [`slice-cas/src/lib.rs`](../../crates/slice-cas/src/lib.rs))** | Real `Uint8Array` subclass `Buffer` (`Buffer.isBuffer`, `readUInt32BE/LE`, `writeBigUInt64BE/LE`, `hex`/`base64url` native codecs), lazy IIFE-isolated `node:events`, `node:path`, `node:crypto` (streaming `createHash`/`createHmac`, `randomBytes`), `node:fs`/`node:fs/promises`, `node:util`, `node:assert`, plus Oxc AST ESM->CJS module transformer & `package.json` `"exports"` subpath resolver | **Zero per-tenant memory regression (`4.0 KB` isolate footprint, `0.97 us` min cold-start); full multi-line ESM & subpath `"exports"` bundling; 100% byte-for-byte parity with Node.js on App 20 (`20-node-compat-and-edge-router`, `hmacSha256Hex: fda684d490d2bd86c7023653983dab877506c69edf9bb254675a7305e9d91c6c`)** | -| **17-Shard Surgical Prelude Architecture & Native Rust Web Primitives ([`web_primitives.rs`](../../crates/slice-engine/src/intrinsics/url_and_usp.rs), [`js_preludes.rs`](../../crates/slice-engine/src/preludes/js_preludes.rs))** | Splits WinterTC and Node.js globals across 17 orthogonal on-demand sub-shards (`loaded_shards_mask: u32`) so cold isolates only parse and compile referenced primitives (`URL`/`URLSearchParams` isolated from `Headers`/`Request`/`Response` and `URLPattern`; `TextEncoder` isolated from `EventTarget`; `ReadableStream` isolated from `TransformStream`/`FormData`; `Buffer` core isolated from `DataView` integer readers/writers), backed by native Rust `parse_whatwg_url`, `can_parse_whatwg_url`, `usp_encode_component`, and `usp_decode_component` | **Reduces cold isolate execution latency across all 31 workloads while maintaining `12.38 MB - 17.88 MB` Max RSS (2.5x-3.5x lower than Bun, 3.8x-5.0x lower than Node.js) and 100% byte-for-byte compatibility** | +| **19-Shard Surgical Prelude Architecture & Native Rust Web Primitives ([`web_primitives.rs`](../../crates/slice-engine/src/intrinsics/url_and_usp.rs), [`js_preludes.rs`](../../crates/slice-engine/src/preludes/js_preludes.rs))** | Splits WinterTC and Node.js globals across 19 orthogonal on-demand sub-shards (`loaded_shards_mask: u32`) so cold isolates only parse and compile referenced primitives (`URL`/`URLSearchParams` isolated from `Headers`/`Request`/`Response` and `URLPattern`; `TextEncoder` isolated from `EventTarget`; `ReadableStream` isolated from `TransformStream`/`FormData`; `Buffer` core isolated from `DataView` integer readers/writers; `Intl` isolated from `process` CLI/`navigator`/`location`), backed by native Rust `parse_whatwg_url`, `can_parse_whatwg_url`, `usp_encode_component`, and `usp_decode_component` | **Reduces cold isolate execution latency across all workloads while maintaining `12.38 MB - 17.88 MB` Max RSS (2.5x-3.5x lower than Bun, 3.8x-5.0x lower than Node.js) and 100% byte-for-byte compatibility** | | **Default `SLICEBC\x01` Precompiled Boa `CodeBlock` CAS + Oxc AST Deferred Module Spans + `node:*` Built-In Pre-Fusion ([`boacas.rs`](../../crates/slice-engine/src/vm/boacas.rs), [`vendor/boa_engine/src/slice_precompile.rs`](../../vendor/boa_engine/src/slice_precompile.rs))** | Ahead-of-time compiles bundled JavaScript (`ULTRA_CORE_PRELUDE` + needed shards + `node:*` built-ins + user script) into a 32-byte `BoaCasHeader` + `SLICEBC1` recursive `CodeBlock` binary image with Oxc AST deferred function module spans (`0x11` tag) | **Eliminates 100% of runtime JS lexing, AST parsing, scope analysis, and bytecode compilation on cold start; beats Bun (`v1.3.10`) on 30 out of 31 workloads cold and 31 out of 31 warm (`5.11 ms` App 01, `13.11 ms` Hono v4, `15.52 ms` itty+UnJS)** | diff --git a/scripts/install.ps1 b/scripts/install.ps1 index b11a652..2b25dbb 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -16,6 +16,6 @@ if (-not (Test-Path $ReleaseExe)) { $DestExe = Join-Path $InstallDir "slice.exe" Copy-Item -Force $ReleaseExe $DestExe -Write-Host "Installed Slice v0.10.11 to $DestExe" +Write-Host "Installed Slice v0.10.12 to $DestExe" & $DestExe info diff --git a/scripts/install.sh b/scripts/install.sh index a40390e..678ebd9 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -9,13 +9,13 @@ INSTALL_DIR="${HOME}/.slice/bin" mkdir -p "$INSTALL_DIR" if [ ! -f "$ROOT_DIR/target/release/slice" ]; then - echo "Compiling Slice v0.10.11 release binary..." + echo "Compiling Slice v0.10.12 release binary..." cargo build --release fi cp -f "$ROOT_DIR/target/release/slice" "$INSTALL_DIR/slice" chmod +x "$INSTALL_DIR/slice" -echo "Installed Slice v0.10.11 to $INSTALL_DIR/slice" +echo "Installed Slice v0.10.12 to $INSTALL_DIR/slice" "$INSTALL_DIR/slice" info diff --git a/scripts/package_release.ps1 b/scripts/package_release.ps1 index a6255a3..795f84f 100644 --- a/scripts/package_release.ps1 +++ b/scripts/package_release.ps1 @@ -6,7 +6,7 @@ $ErrorActionPreference = "Stop" $RootDir = Split-Path -Parent $PSScriptRoot Set-Location $RootDir -Write-Host "[1/4] Building Slice v0.10.11 Release Binary (LTO=fat, opt-level=3)..." +Write-Host "[1/4] Building Slice v0.10.12 Release Binary (LTO=fat, opt-level=3)..." cargo build --release $DistDir = Join-Path $RootDir "dist" diff --git a/scripts/run_benchmarks.ps1 b/scripts/run_benchmarks.ps1 index 2b92c61..e176032 100644 --- a/scripts/run_benchmarks.ps1 +++ b/scripts/run_benchmarks.ps1 @@ -15,7 +15,7 @@ $CargoToml = Get-Content (Join-Path $RootDir "Cargo.toml") -Raw if ($CargoToml -match '(?m)^\[workspace\.package\]\s*\r?\nversion\s*=\s*"([^"]+)"') { $Version = $Matches[1] } else { - $Version = "0.10.11" + $Version = "0.10.12" } try { diff --git a/tests/README.md b/tests/README.md index 8e1916b..15e5eca 100644 --- a/tests/README.md +++ b/tests/README.md @@ -6,7 +6,7 @@ This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmar ## Latest Runtimes Installed in Docker ([`tests/Dockerfile`](./Dockerfile)) -- **Slice (`v0.10.11` — `SLICEBC\x01` Precompiled `CodeBlock` CAS Default):** Hybrid architecture combining **Oxc** (`v0.154.0` production Rust TypeScript compiler + AST ESM-to-CJS module bundler with deferred function module spans (`0x11` tag) + `.wasm` zero-stat module bundler + full `package.json` `"exports"` resolver + static barrel tree-shaker), **Boa (`boa_engine` v0.22 + [`vendor/boa_engine/SLICE_PATCH.md`](../vendor/boa_engine/SLICE_PATCH.md))** full ECMAScript VM with default `SLICEBC\x01` precompiled `Gc` + global `Scope` binary payloads (zero runtime `boa_parser` / `ByteCompiler` overhead) and pre-fused `node:*` built-in shards, thread-local pre-warmed context pool (`BOA_CONTEXT_POOL`), pure-Rust **WebAssembly (`wasmi` v2.0.0)** engine with `GLOBAL_WASM_MODULE_CACHE` and 5-Ring CPU fuel & linear memory cages, native Rust fast-path intrinsics (`SemVer`, `SHA-256`/`SHA-384`/`SHA-512`, `HMAC-SHA256`/`HMAC-SHA512`, `Base64URL`, in-memory `VFS` slab cache, WinterTC `URL`/`URLPattern`/`URLSearchParams`/`Headers`/`Request`/`Response`/`ReadableStream`/`TransformStream`/`CompressionStream`/`DecompressionStream`/`TextEncoder`/`TextDecoder`/`crypto.subtle`/`Blob`/`File`/`FormData`/`structuredClone`/`EventTarget`/`AbortSignal`/`WebAssembly`, real `Uint8Array`-backed `Buffer`, `node:*` Core Tier-1 modules including `node:async_hooks` and `node:zlib`, `Slice.streamSSE` / `Response.sse`, OCap-guarded outbound HTTP/1.1 & HTTPS TLS 1.3 `fetch()` with Keep-Alive pooling, hop-by-hop redirect guard, Cloud Metadata SSRF Shield, and Egress DLP, built-in Time-Travel `slice test` runner, OS-native `notify` (`v8.2`) `< 5 ms` `--watch`, and Auto-DLP `.env`), and **Slice Zero-Stat CAS + `--static` BLAKE3 `ETag` Static Server + Tier-0/Tier-2 fast paths**. +- **Slice (`v0.10.12` — `SLICEBC\x01` Precompiled `CodeBlock` CAS Default):** Hybrid architecture combining **Oxc** (`v0.154.0` production Rust TypeScript compiler + AST ESM-to-CJS module bundler with deferred function module spans (`0x11` tag) + `.wasm` zero-stat module bundler + full `package.json` `"exports"` resolver + static barrel tree-shaker), **Boa (`boa_engine` v0.22 + [`vendor/boa_engine/SLICE_PATCH.md`](../vendor/boa_engine/SLICE_PATCH.md))** full ECMAScript VM with default `SLICEBC\x01` precompiled `Gc` + global `Scope` binary payloads (zero runtime `boa_parser` / `ByteCompiler` overhead) and pre-fused `node:*` built-in shards, thread-local pre-warmed context pool (`BOA_CONTEXT_POOL`), pure-Rust **WebAssembly (`wasmi` v2.0.0)** engine with `GLOBAL_WASM_MODULE_CACHE` and 5-Ring CPU fuel & linear memory cages, native Rust fast-path intrinsics (`SemVer`, `SHA-256`/`SHA-384`/`SHA-512`, `HMAC-SHA256`/`HMAC-SHA512`, `Base64URL`, in-memory `VFS` slab cache, WinterTC `URL`/`URLPattern`/`URLSearchParams`/`Headers`/`Request`/`Response`/`ReadableStream`/`TransformStream`/`CompressionStream`/`DecompressionStream`/`TextEncoder`/`TextDecoder`/`crypto.subtle`/`Blob`/`File`/`FormData`/`structuredClone`/`EventTarget`/`AbortSignal`/`WebAssembly`, real `Uint8Array`-backed `Buffer`, `node:*` Core Tier-1 modules including `node:async_hooks` and `node:zlib`, `Slice.streamSSE` / `Response.sse`, OCap-guarded outbound HTTP/1.1 & HTTPS TLS 1.3 `fetch()` with Keep-Alive pooling, hop-by-hop redirect guard, Cloud Metadata SSRF Shield, and Egress DLP, built-in Time-Travel `slice test` runner, OS-native `notify` (`v8.2`) `< 5 ms` `--watch`, and Auto-DLP `.env`), and **Slice Zero-Stat CAS + `--static` BLAKE3 `ETag` Static Server + Tier-0/Tier-2 fast paths**. - **Node.js (`v27.0.0-alpha` — Absolute Latest Release):** Dynamically resolved at container build time from `https://nodejs.org/dist/index.json` (`.[0].version`). - **Bun (`v1.4.4` — Absolute Latest Release):** Installed via official `https://bun.sh/install`. - **Deno (`v2.9.8` — Absolute Latest Release):** Installed via official `https://deno.land/install.sh`. @@ -212,45 +212,45 @@ This directory (`tests/`) contains a reproducible Linux `x86_64` Docker benchmar ## Verified Linux Docker (`x86_64`) Benchmark Results Across All 33 Workloads ([`reports/latest.md`](./reports/latest.md)) -> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./reports/latest.md)** (Archive: [`bench_v0.10.11_20261111_055407Z_898e90b.md`](./reports/bench_v0.10.11_20261111_055407Z_898e90b.md)) -> **Provenance:** Slice `v0.10.11` (`898e90b`) · Generated `2026-11-11T05:54:07Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` -> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **28/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. +> **Latest Verified Benchmark Report:** **[`tests/reports/latest.md`](./reports/latest.md)** (Archive: [`bench_v0.10.12_20261111_175836Z_dc31f74.md`](./reports/bench_v0.10.12_20261111_175836Z_dc31f74.md)) +> **Provenance:** Slice `v0.10.12` (`dc31f74`) · Generated `2026-11-11T17:58:36Z` · Environment: `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +> **Scorecard Across All 33 Production Workloads:** Beats **Deno (`v2.9.8`)** on **33/33**, **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33**, **Bun (`v1.4.4`)** on **29/33** cold one-shot, and **all 3 runtimes on 33/33 workloads in `--warm` pooled execution**. #### 1. Core Architecture, HTTP Throughput & 1,000-Tenant MicroVM Density -| Metric | Slice (`v0.10.11` `SLICEBC\x01`) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Advantage | +| Metric | Slice (`v0.10.12` `SLICEBC\x01`) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Advantage | | :--- | :---: | :---: | :---: | :---: | :--- | -| **In-Process Isolate Cold Start (`P50` / `P99`)** | **`1.23 us` / `2.03 us`** | N/A (Process/VM) | N/A (Process/VM) | N/A (Process/VM) | **~120,000x faster than 125ms Firecracker VM** | -| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.47 ms` (`9.70 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | +| **In-Process Isolate Cold Start (`P50` / `P99`)** | **`1.02 us` / `4.27 us`** | N/A (Process/VM) | N/A (Process/VM) | N/A (Process/VM) | **~120,000x faster than 125ms Firecracker VM** | +| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.74 ms` (`9.82 MB` RSS)** | > 5,000 ms | > 15,000 ms | > 30,000 ms | **> 3,900x faster / ~32,000x denser** | | **500-Module Monorepo Cold Boot (`stat()` Calls)** | **`3.41 ms` (`0 stat()`)** | `12.72 ms` (`500+ stat`) | `41.80 ms` (`500+ stat`) | `70.38 ms` (`1,500+ stat`) | **`3.7x` faster than Bun / `20.6x` Node.js** | -| **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`153,174 req/s`** (Tier-0)
**`145,192 req/s`** (Tier-1) | `101,093 req/s` | `99,307 req/s` | `54,637 req/s` | **`1.52x` (`Tier-0`) / `1.44x` (`Tier-1`) vs `Bun.serve`** | -| **Peak Process Memory (`Max RSS` Across Suite)** | **`14.25 – 21.88 MB`** | `26.13 – 41.13 MB` | `45.53 – 61.75 MB` | `69.91 – 93.12 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | +| **HTTP/1.1 Keep-Alive Throughput (`16k` Reqs)** | **`154,794 req/s`** (Tier-0)
**`147,564 req/s`** (Tier-1) | `100,562 req/s` | `99,082 req/s` | `56,447 req/s` | **`1.54x` (`Tier-0`) / `1.47x` (`Tier-1`) vs `Bun.serve`** | +| **Peak Process Memory (`Max RSS` Across Suite)** | **`13.45 – 21.63 MB`** | `26.13 – 40.25 MB` | `45.69 – 62.38 MB` | `70.15 – 93.00 MB` | **`2.0x–2.3x` less than Bun / `4.3x–6.8x` less than Node** | | **Multi-Tenant Security Containment** | **`5 / 5 PASS`** (OCap+SES+Fuel+DLP) | `0 / 5` (Ambient) | `2 / 5` (Coarse CLI) | `0 / 5` (Ambient) | **Hardware & Language Zero-Trust Isolation** | #### 2. Real-Life Workload Summary by Domain (All 33 Workloads Aggregated) | Workload Domain & Stack Coverage | Suites | Slice Cold `.cas` Avg (Range) | Slice Warm (`--warm`) Avg | Bun `v1.4.4` Avg | Deno `v2.9.8` Avg | Node.js `v27.0.0-alpha.0.0.0` Avg | Category Speedup vs Bun / Node.js | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :--- | -| **Core Edge, Auth & Crypto (`Apps 01, 04, 05, 16`)**
Multi-file TS, SHA-256/HMAC, JWT/OAuth2, `.env` Auto-DLP | `4` | **`8.21 ms`** (`6.70–10.51 ms`) | **`3.72 ms`** | `14.26 ms` | `41.57 ms` | `62.14 ms` | **`1.74x Bun` (`3.83x` Warm) / `7.57x Node`** | -| **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`11.43 ms`** (`7.62–14.79 ms`) | **`4.37 ms`** | `17.40 ms` | `48.13 ms` | `66.84 ms` | **`1.52x Bun` (`3.98x` Warm) / `5.85x Node`** | -| **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`16.13 ms`** (`8.52–30.84 ms`) | **`8.10 ms`** | `18.60 ms` | `52.66 ms` | `95.09 ms` | **`1.15x Bun` (`2.29x` Warm) / `5.90x Node`** | -| **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.24 ms`** (`8.74–20.16 ms`) | **`2.93 ms`** | `28.64 ms` | `63.70 ms` | `86.48 ms` | **`2.01x Bun` (`9.77x` Warm) / `6.07x Node`** | -| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`20.59 ms`** (`15.22–32.08 ms`) | **`8.39 ms`** | `29.73 ms` | `56.05 ms` | `94.07 ms` | **`1.44x Bun` (`3.54x` Warm) / `4.57x Node`** | -| **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`20.58 ms`** (`13.69–32.18 ms`) | **`6.77 ms`** | `20.18 ms` | `54.28 ms` | `79.15 ms` | **`0.98x Bun` (`2.98x` Warm) / `3.85x Node`** | +| **Core Edge, Auth & Crypto (`Apps 01, 04, 05, 16`)**
Multi-file TS, SHA-256/HMAC, JWT/OAuth2, `.env` Auto-DLP | `4` | **`7.84 ms`** (`6.28–10.07 ms`) | **`2.17 ms`** | `14.52 ms` | `42.60 ms` | `62.07 ms` | **`1.85x Bun` (`6.69x` Warm) / `7.92x Node`** | +| **NPM Ecosystem, AST & Disk I/O (`Apps 02, 03, 06, 07, 08, 20`)**
`semver`, `flatted`, `dlv`/`dset`, `mitt`, 10-Shard JSONL I/O, `Buffer` | `6` | **`10.94 ms`** (`7.25–14.23 ms`) | **`3.16 ms`** | `17.64 ms` | `48.12 ms` | `65.89 ms` | **`1.61x Bun` (`5.59x` Warm) / `6.02x Node`** | +| **WinterTC Web Standards, Fetch Mesh & DLP (`Apps 09–14, 17–19`)**
`Request`/`Response`, Static CDN `304`, SSE, Live `fetch`, WebCrypto | `9` | **`15.45 ms`** (`8.12–29.33 ms`) | **`7.31 ms`** | `18.48 ms` | `52.47 ms` | `93.96 ms` | **`1.20x Bun` (`2.53x` Warm) / `6.08x Node`** | +| **Realtime WebSockets, Workers & Wasm/TSX (`Apps 15, 21–24`)**
RFC 6455 WS, `worker_threads` + TCP/UDP, Pure-Rust `wasmi` Wasm, TSX SSR | `5` | **`14.25 ms`** (`8.72–20.99 ms`) | **`2.48 ms`** | `28.68 ms` | `62.87 ms` | `86.44 ms` | **`2.01x Bun` (`11.57x` Warm) / `6.07x Node`** | +| **Full-Stack Edge & Node Frameworks (`FW 01–04`)**
`Hono v4.6.20`, `itty-router + UnJS Nitro`, `Express/Polka node:http`, `SvelteKit 3.1.1 + Svelte 5.57.3` | `4` | **`20.74 ms`** (`14.65–34.19 ms`) | **`7.47 ms`** | `29.22 ms` | `54.14 ms` | `93.40 ms` | **`1.41x Bun` (`3.91x` Warm) / `4.50x Node`** | +| **AI Agent, Multi-Tenant SaaS & Chaos Case Studies (`CS 01–05`)**
Depth-4 ToT Agent, MCP Code Mode, 12-Tenant Mesh, Wasm CDR, 48 Payment Sagas | `5` | **`21.17 ms`** (`13.17–34.84 ms`) | **`6.27 ms`** | `20.96 ms` | `56.54 ms` | `80.98 ms` | **`0.99x Bun` (`3.34x` Warm) / `3.82x Node`** | #### 3. Flagship Real-World Representative Workloads (9 of 33 Highlights) | # | Flagship Workload | Slice Cold `.cas` | Slice Warm (`--warm`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :--- | -| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.70 ms`** | **`1.68 ms`** | `13.45 ms` | `35.70 ms` | `59.15 ms` | **`2.01x Bun` (`8.01x` Warm) / `8.83x Node`** | -| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.62 ms`** | **`1.72 ms`** | `13.79 ms` | `45.41 ms` | `61.73 ms` | **`1.81x Bun` (`8.00x` Warm) / `8.10x Node`** | -| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`16.69 ms`** | **`7.97 ms`** | `21.63 ms` | `53.17 ms` | `112.88 ms` | **`1.30x Bun` (`2.71x` Warm) / `6.76x Node`** | -| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.30 ms`** | **`0.61 ms`** | `22.40 ms` | `55.00 ms` | `76.30 ms` | **`1.98x Bun` (`36.60x` Warm) / `6.75x Node`** | -| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.16 ms`** | **`2.23 ms`** | `55.92 ms` | `112.63 ms` | `101.84 ms` | **`2.77x Bun` (`25.10x` Warm) / `5.05x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.22 ms`** | **`5.63 ms`** | `19.63 ms` | `52.60 ms` | `94.61 ms` | **`1.29x Bun` (`3.49x` Warm) / `6.22x Node`** | -| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`32.08 ms`** | **`16.95 ms`** | `43.52 ms` | `74.25 ms` | `112.27 ms` | **`1.36x Bun` (`2.57x` Warm) / `3.50x Node`** | -| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.71 ms`** | **`13.02 ms`** | `28.39 ms` | `72.12 ms` | `88.96 ms` | **`0.88x Bun` (`2.18x` Warm) / `2.76x Node`** | -| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.21 ms`** | **`7.92 ms`** | `20.31 ms` | `62.71 ms` | `84.14 ms` | **`1.11x Bun` (`2.56x` Warm) / `4.62x Node`** | +| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.28 ms`** | **`1.05 ms`** | `13.38 ms` | `35.22 ms` | `58.45 ms` | **`2.13x Bun` (`12.74x` Warm) / `9.31x Node`** | +| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.25 ms`** | **`1.29 ms`** | `14.08 ms` | `43.23 ms` | `61.79 ms` | **`1.94x Bun` (`10.92x` Warm) / `8.52x Node`** | +| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.83 ms`** | **`6.70 ms`** | `21.20 ms` | `56.40 ms` | `108.62 ms` | **`1.34x Bun` (`3.17x` Warm) / `6.86x Node`** | +| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.26 ms`** | **`0.50 ms`** | `25.08 ms` | `55.78 ms` | `73.35 ms` | **`2.23x Bun` (`50.56x` Warm) / `6.51x Node`** | +| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.99 ms`** | **`1.74 ms`** | `57.15 ms` | `114.02 ms` | `101.72 ms` | **`2.72x Bun` (`32.86x` Warm) / `4.85x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`14.65 ms`** | **`5.59 ms`** | `19.86 ms` | `51.15 ms` | `94.15 ms` | **`1.36x Bun` (`3.55x` Warm) / `6.43x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`34.37 ms`** | **`14.26 ms`** | `43.71 ms` | `68.04 ms` | `108.54 ms` | **`1.28x Bun` (`3.07x` Warm) / `3.17x Node`** | +| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.84 ms`** | **`12.99 ms`** | `28.86 ms` | `73.55 ms` | `91.05 ms` | **`0.83x Bun` (`2.22x` Warm) / `2.61x Node`** | +| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.14 ms`** | **`8.32 ms`** | `21.10 ms` | `65.54 ms` | `86.65 ms` | **`1.16x Bun` (`2.54x` Warm) / `4.78x Node`** | *Full 33-workload latency breakdown, standalone binary metrics, peak RSS per app, and historical reports: **[`tests/reports/latest.md`](./reports/latest.md)**.* diff --git a/tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.json b/tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.json new file mode 100644 index 0000000..e2f96cd --- /dev/null +++ b/tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.json @@ -0,0 +1,789 @@ +{ + "metadata": { + "version": "0.10.12", + "commit": "dc31f74", + "timestampUtc": "2026-11-11T17:58:36Z", + "environment": "Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)", + "runtimes": { + "slice": "v0.10.12", + "bun": "v1.4.4", + "deno": "v2.9.8", + "node": "v27.0.0-alpha.0.0.0" + }, + "archiveFile": "tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md", + "latestFile": "tests/reports/latest.md" + }, + "microvm": { + "linux": { + "coldMinUs": 0.94, + "coldP50Us": 1.02, + "coldP99Us": 4.27, + "swarm1000Ms": 1.74, + "swarm1000RssMb": 9.82, + "cas500ColdMs": 3.408, + "cas500MemUs": 467.08, + "ringIo10kMs": 0.02 + }, + "windows": { + "coldMinUs": 1.4, + "coldP50Us": 1.6, + "coldP99Us": 2.3, + "swarm1000Ms": 2.24, + "swarm1000RssMb": 11.82, + "cas500ColdMs": 5.637, + "cas500MemUs": 640, + "ringIo10kMs": 5.11 + } + }, + "httpKeepAlive": { + "sliceTier0": { + "rps": 154794, + "avgUs": 6.46, + "totalMs": 103.4 + }, + "sliceTier1": { + "rps": 147564, + "avgUs": 6.78, + "totalMs": 108.4 + }, + "deno": { + "rps": 99082, + "avgUs": 10.09, + "totalMs": 161.5 + }, + "bun": { + "rps": 100562, + "avgUs": 9.94, + "totalMs": 159.1 + }, + "node": { + "rps": 56447, + "avgUs": 17.72, + "totalMs": 283.5 + } + }, + "primitives": { + "kv1001Us": 564.84, + "kvMemBytes": 8431, + "tot3SandboxesUs": 74.64, + "totSingleSandboxUs": 3.496 + }, + "workloads": [ + { + "num": 1, + "code": "01", + "id": "01-fintech-checkout", + "label": "`01-fintech-checkout` (Multi-File TS + SHA-256)", + "category": "core_edge_crypto", + "flagship": true, + "sliceCasMinMs": 5.883, + "sliceCasAvgMs": 6.278, + "sliceBinMinMs": 6.165, + "sliceBinAvgMs": 6.621, + "sliceSrcAvgMs": 16.378, + "sliceWarmMs": 1.05, + "prevSliceCasAvgMs": 6.698, + "bunAvgMs": 13.377, + "denoAvgMs": 35.217, + "nodeAvgMs": 58.453 + }, + { + "num": 2, + "code": "02", + "id": "02-npm-ecosystem-suite", + "label": "`02-npm-ecosystem-suite` (`semver` + `ms` + `ini`)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 13.358, + "sliceCasAvgMs": 14.228, + "sliceBinMinMs": 13.462, + "sliceBinAvgMs": 14.717, + "sliceSrcAvgMs": 36.143, + "sliceWarmMs": 3.817, + "prevSliceCasAvgMs": 14.785, + "bunAvgMs": 21.069, + "denoAvgMs": 55.166, + "nodeAvgMs": 69.341 + }, + { + "num": 3, + "code": "03", + "id": "03-disk-io-log-pipeline", + "label": "`03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O)", + "category": "npm_ast_disk", + "flagship": true, + "sliceCasMinMs": 6.807, + "sliceCasAvgMs": 7.25, + "sliceBinMinMs": 7.37, + "sliceBinAvgMs": 7.8, + "sliceSrcAvgMs": 25.973, + "sliceWarmMs": 1.289, + "prevSliceCasAvgMs": 7.617, + "bunAvgMs": 14.082, + "denoAvgMs": 43.228, + "nodeAvgMs": 61.792 + }, + { + "num": 4, + "code": "04", + "id": "04-edge-api-gateway", + "label": "`04-edge-api-gateway` (`fast-querystring` + `ms`)", + "category": "core_edge_crypto", + "flagship": false, + "sliceCasMinMs": 6.977, + "sliceCasAvgMs": 7.408, + "sliceBinMinMs": 7.344, + "sliceBinAvgMs": 8.033, + "sliceSrcAvgMs": 21.1, + "sliceWarmMs": 1.736, + "prevSliceCasAvgMs": 7.559, + "bunAvgMs": 15.082, + "denoAvgMs": 41.232, + "nodeAvgMs": 59.873 + }, + { + "num": 5, + "code": "05", + "id": "05-jwt-oauth-session-guard", + "label": "`05-jwt-oauth-session-guard` (`cookie` + `ms` + HMAC)", + "category": "core_edge_crypto", + "flagship": false, + "sliceCasMinMs": 9.447, + "sliceCasAvgMs": 10.074, + "sliceBinMinMs": 9.907, + "sliceBinAvgMs": 10.543, + "sliceSrcAvgMs": 21.049, + "sliceWarmMs": 4.654, + "prevSliceCasAvgMs": 10.511, + "bunAvgMs": 14.766, + "denoAvgMs": 45.411, + "nodeAvgMs": 62.437 + }, + { + "num": 6, + "code": "06", + "id": "06-telemetry-metrics-pipeline", + "label": "`06-telemetry-metrics-pipeline` (`bytes` + `flatted` + WAL)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 12.188, + "sliceCasAvgMs": 12.738, + "sliceBinMinMs": 12.578, + "sliceBinAvgMs": 13.97, + "sliceSrcAvgMs": 31.589, + "sliceWarmMs": 4.33, + "prevSliceCasAvgMs": 14.045, + "bunAvgMs": 16.697, + "denoAvgMs": 46.63, + "nodeAvgMs": 65.983 + }, + { + "num": 7, + "code": "07", + "id": "07-graphql-ast-validator", + "label": "`07-graphql-ast-validator` (`dlv` + `dset` + AST Cost)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 8.403, + "sliceCasAvgMs": 8.937, + "sliceBinMinMs": 8.808, + "sliceBinAvgMs": 9.786, + "sliceSrcAvgMs": 19.218, + "sliceWarmMs": 3.758, + "prevSliceCasAvgMs": 9.193, + "bunAvgMs": 13.02, + "denoAvgMs": 41.561, + "nodeAvgMs": 61.914 + }, + { + "num": 8, + "code": "08", + "id": "08-event-driven-state-journal", + "label": "`08-event-driven-state-journal` (`mitt` + `ms` + JSONL Replay)", + "category": "npm_ast_disk", + "flagship": false, + "sliceCasMinMs": 10.454, + "sliceCasAvgMs": 11.229, + "sliceBinMinMs": 11.147, + "sliceBinAvgMs": 14.547, + "sliceSrcAvgMs": 30.157, + "sliceWarmMs": 5.258, + "prevSliceCasAvgMs": 11.667, + "bunAvgMs": 15.902, + "denoAvgMs": 46.355, + "nodeAvgMs": 62.965 + }, + { + "num": 9, + "code": "09", + "id": "09-wintertc-web-router", + "label": "`09-wintertc-web-router` (`Request` + `Response` + `URL`, 80 reqs)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 14.222, + "sliceCasAvgMs": 14.771, + "sliceBinMinMs": 14.52, + "sliceBinAvgMs": 15.429, + "sliceSrcAvgMs": 30.804, + "sliceWarmMs": 9.085, + "prevSliceCasAvgMs": 16.323, + "bunAvgMs": 13.919, + "denoAvgMs": 47.276, + "nodeAvgMs": 85.354 + }, + { + "num": 10, + "code": "10", + "id": "10-fullstack-bff-microservice", + "label": "`10-fullstack-bff-microservice` (`cookie` + `dlv` + `ms` + `ETag`, 60 reqs)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 12.158, + "sliceCasAvgMs": 12.802, + "sliceBinMinMs": 12.643, + "sliceBinAvgMs": 13.616, + "sliceSrcAvgMs": 30.565, + "sliceWarmMs": 6.308, + "prevSliceCasAvgMs": 13.778, + "bunAvgMs": 14.467, + "denoAvgMs": 50.395, + "nodeAvgMs": 84.816 + }, + { + "num": 11, + "code": "11", + "id": "11-static-asset-cdn-edge", + "label": "`11-static-asset-cdn-edge` (`bytes` + `ms` + `ETag` `304`, 80 reqs)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 9.535, + "sliceCasAvgMs": 10.042, + "sliceBinMinMs": 10.034, + "sliceBinAvgMs": 10.698, + "sliceSrcAvgMs": 27.244, + "sliceWarmMs": 3.656, + "prevSliceCasAvgMs": 10.366, + "bunAvgMs": 13.499, + "denoAvgMs": 47.729, + "nodeAvgMs": 87.639 + }, + { + "num": 12, + "code": "12", + "id": "12-ai-sse-token-streamer", + "label": "`12-ai-sse-token-streamer` (`mitt` + `ms` + SSE + DLP, 320 frames)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 14.853, + "sliceCasAvgMs": 15.593, + "sliceBinMinMs": 14.905, + "sliceBinAvgMs": 15.893, + "sliceSrcAvgMs": 31.524, + "sliceWarmMs": 7.429, + "prevSliceCasAvgMs": 15.43, + "bunAvgMs": 15.213, + "denoAvgMs": 48.694, + "nodeAvgMs": 90.253 + }, + { + "num": 13, + "code": "13", + "id": "13-webhook-orchestrator-ssrf", + "label": "`13-webhook-orchestrator-ssrf` (`fast-querystring` + `ms` + Live `fetch`)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 14.708, + "sliceCasAvgMs": 15.199, + "sliceBinMinMs": 15.196, + "sliceBinAvgMs": 16.293, + "sliceSrcAvgMs": 35.193, + "sliceWarmMs": 6.388, + "prevSliceCasAvgMs": 17.563, + "bunAvgMs": 18.942, + "denoAvgMs": 51.379, + "nodeAvgMs": 111.11 + }, + { + "num": 14, + "code": "14", + "id": "14-federated-api-mesh-dlp", + "label": "`14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`)", + "category": "wintertc_fetch_dlp", + "flagship": true, + "sliceCasMinMs": 15.009, + "sliceCasAvgMs": 15.828, + "sliceBinMinMs": 15.322, + "sliceBinAvgMs": 16.384, + "sliceSrcAvgMs": 32.722, + "sliceWarmMs": 6.697, + "prevSliceCasAvgMs": 16.692, + "bunAvgMs": 21.2, + "denoAvgMs": 56.402, + "nodeAvgMs": 108.617 + }, + { + "num": 15, + "code": "15", + "id": "15-time-travel-test-suite", + "label": "`15-time-travel-test-suite` (`semver` + `ms` + `dlv` + `dset` + 24 Rollbacks)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 14.526, + "sliceCasAvgMs": 15.273, + "sliceBinMinMs": 14.875, + "sliceBinAvgMs": 15.908, + "sliceSrcAvgMs": 45.721, + "sliceWarmMs": 4.757, + "prevSliceCasAvgMs": 16.035, + "bunAvgMs": 24.939, + "denoAvgMs": 66.357, + "nodeAvgMs": 84.077 + }, + { + "num": 16, + "code": "16", + "id": "16-dotenv-dlp-config-vault", + "label": "`16-dotenv-dlp-config-vault` (`ini` + `cookie` + `bytes` + `.env` Auto-DLP)", + "category": "core_edge_crypto", + "flagship": false, + "sliceCasMinMs": 6.834, + "sliceCasAvgMs": 7.598, + "sliceBinMinMs": 7.463, + "sliceBinAvgMs": 8.351, + "sliceSrcAvgMs": 29.672, + "sliceWarmMs": 1.234, + "prevSliceCasAvgMs": 8.079, + "bunAvgMs": 14.844, + "denoAvgMs": 48.547, + "nodeAvgMs": 67.533 + }, + { + "num": 17, + "code": "17", + "id": "17-zero-trust-redirect-keepalive-mesh", + "label": "`17-zero-trust-redirect-keepalive-mesh` (Keep-Alive/307/SSRF/DLP)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 16.695, + "sliceCasAvgMs": 17.333, + "sliceBinMinMs": 17.509, + "sliceBinAvgMs": 18.916, + "sliceSrcAvgMs": 41.891, + "sliceWarmMs": 7.896, + "prevSliceCasAvgMs": 17.376, + "bunAvgMs": 22.634, + "denoAvgMs": 55.132, + "nodeAvgMs": 109.514 + }, + { + "num": 18, + "code": "18", + "id": "18-async-event-loop-fanout-scheduler", + "label": "`18-async-event-loop-fanout-scheduler` (Timer Wheel/`Promise.all`/`AbortSignal`)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 27.785, + "sliceCasAvgMs": 29.326, + "sliceBinMinMs": 28.861, + "sliceBinAvgMs": 30.533, + "sliceSrcAvgMs": 45.923, + "sliceWarmMs": 16.971, + "prevSliceCasAvgMs": 30.841, + "bunAvgMs": 32.616, + "denoAvgMs": 70.809, + "nodeAvgMs": 81.452 + }, + { + "num": 19, + "code": "19", + "id": "19-wintertc-webcrypto-streams-edge", + "label": "`19-wintertc-webcrypto-streams-edge` (WebCrypto/Streams/FormData/Clone)", + "category": "wintertc_fetch_dlp", + "flagship": false, + "sliceCasMinMs": 7.676, + "sliceCasAvgMs": 8.118, + "sliceBinMinMs": 8.181, + "sliceBinAvgMs": 9.079, + "sliceSrcAvgMs": 31.573, + "sliceWarmMs": 1.396, + "prevSliceCasAvgMs": 8.515, + "bunAvgMs": 13.794, + "denoAvgMs": 44.403, + "nodeAvgMs": 86.921 + }, + { + "num": 20, + "code": "20", + "id": "20-node-compat-and-edge-router", + "label": "`20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler)", + "category": "npm_ast_disk", + "flagship": true, + "sliceCasMinMs": 10.205, + "sliceCasAvgMs": 11.261, + "sliceBinMinMs": 10.964, + "sliceBinAvgMs": 11.623, + "sliceSrcAvgMs": 43.366, + "sliceWarmMs": 0.496, + "prevSliceCasAvgMs": 11.298, + "bunAvgMs": 25.08, + "denoAvgMs": 55.776, + "nodeAvgMs": 73.35 + }, + { + "num": 21, + "code": "21", + "id": "21-websocket-realtime-and-security-guard", + "label": "`21-websocket-realtime-and-security-guard` (RFC 6455 `WebSocket` + 5-Ring Guard)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 10.084, + "sliceCasAvgMs": 10.714, + "sliceBinMinMs": 10.452, + "sliceBinAvgMs": 11.463, + "sliceSrcAvgMs": 41.725, + "sliceWarmMs": 2.166, + "prevSliceCasAvgMs": 11.073, + "bunAvgMs": 20.494, + "denoAvgMs": 51.042, + "nodeAvgMs": 116.007 + }, + { + "num": 22, + "code": "22", + "id": "22-worker-threads-and-raw-sockets", + "label": "`22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec)", + "category": "realtime_workers_wasm", + "flagship": true, + "sliceCasMinMs": 20.328, + "sliceCasAvgMs": 20.988, + "sliceBinMinMs": 20.372, + "sliceBinAvgMs": 21.637, + "sliceSrcAvgMs": 40.911, + "sliceWarmMs": 1.739, + "prevSliceCasAvgMs": 20.159, + "bunAvgMs": 57.152, + "denoAvgMs": 114.016, + "nodeAvgMs": 101.723 + }, + { + "num": 23, + "code": "23", + "id": "23-wasm-crypto-and-simd-kernel", + "label": "`23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 14.733, + "sliceCasAvgMs": 15.548, + "sliceBinMinMs": 15.357, + "sliceBinAvgMs": 16.009, + "sliceSrcAvgMs": 27.894, + "sliceWarmMs": 1.97, + "prevSliceCasAvgMs": 15.43, + "bunAvgMs": 21.684, + "denoAvgMs": 40.55, + "nodeAvgMs": 63.213 + }, + { + "num": 24, + "code": "24", + "id": "24-tsx-ssr-and-wasm-edge-pipeline", + "label": "`24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline)", + "category": "realtime_workers_wasm", + "flagship": false, + "sliceCasMinMs": 7.843, + "sliceCasAvgMs": 8.719, + "sliceBinMinMs": 8.124, + "sliceBinAvgMs": 8.994, + "sliceSrcAvgMs": 27.54, + "sliceWarmMs": 1.758, + "prevSliceCasAvgMs": 8.744, + "bunAvgMs": 19.118, + "denoAvgMs": 42.405, + "nodeAvgMs": 67.199 + }, + { + "num": 25, + "code": "FW-01", + "id": "frameworks/01-hono-edge-microservice", + "label": "`FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`)", + "category": "frameworks", + "flagship": true, + "sliceCasMinMs": 14.056, + "sliceCasAvgMs": 14.653, + "sliceBinMinMs": 14.232, + "sliceBinAvgMs": 15.35, + "sliceSrcAvgMs": 49.303, + "sliceWarmMs": 5.593, + "prevSliceCasAvgMs": 15.219, + "bunAvgMs": 19.858, + "denoAvgMs": 51.149, + "nodeAvgMs": 94.15 + }, + { + "num": 26, + "code": "FW-02", + "id": "frameworks/02-itty-router-unjs-nitro-stack", + "label": "`FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS)", + "category": "frameworks", + "flagship": false, + "sliceCasMinMs": 16.631, + "sliceCasAvgMs": 17.364, + "sliceBinMinMs": 16.825, + "sliceBinAvgMs": 17.789, + "sliceSrcAvgMs": 46.638, + "sliceWarmMs": 9.113, + "prevSliceCasAvgMs": 17.819, + "bunAvgMs": 18.943, + "denoAvgMs": 46.132, + "nodeAvgMs": 86.398 + }, + { + "num": 32, + "code": "FW-03", + "id": "frameworks/03-node-http-express-compat", + "label": "`FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka)", + "category": "frameworks", + "flagship": false, + "sliceCasMinMs": 16.237, + "sliceCasAvgMs": 16.742, + "sliceBinMinMs": 16.633, + "sliceBinAvgMs": 18.053, + "sliceSrcAvgMs": 24.203, + "sliceWarmMs": 0.927, + "prevSliceCasAvgMs": 17.267, + "bunAvgMs": 34.374, + "denoAvgMs": 51.235, + "nodeAvgMs": 84.492 + }, + { + "num": 33, + "code": "FW-04", + "id": "frameworks/04-sveltekit-edge-ssr", + "label": "`FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`)", + "category": "frameworks", + "flagship": true, + "sliceCasMinMs": 32.033, + "sliceCasAvgMs": 34.372, + "sliceBinMinMs": 31.777, + "sliceBinAvgMs": 34.188, + "sliceSrcAvgMs": 146.899, + "sliceWarmMs": 14.26, + "prevSliceCasAvgMs": 32.075, + "bunAvgMs": 43.709, + "denoAvgMs": 68.042, + "nodeAvgMs": 108.544 + }, + { + "num": 27, + "code": "CS-01", + "id": "case_studies/01-tot-autonomous-sre-agent", + "label": "`CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes)", + "category": "case_studies", + "flagship": true, + "sliceCasMinMs": 32.956, + "sliceCasAvgMs": 34.837, + "sliceBinMinMs": 32.622, + "sliceBinAvgMs": 36, + "sliceSrcAvgMs": 77.212, + "sliceWarmMs": 12.991, + "prevSliceCasAvgMs": 34.706, + "bunAvgMs": 28.855, + "denoAvgMs": 73.549, + "nodeAvgMs": 91.045 + }, + { + "num": 28, + "code": "CS-02", + "id": "case_studies/02-mcp-code-mode-orchestrator", + "label": "`CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens)", + "category": "case_studies", + "flagship": false, + "sliceCasMinMs": 17.868, + "sliceCasAvgMs": 19.49, + "sliceBinMinMs": 18.675, + "sliceBinAvgMs": 19.711, + "sliceSrcAvgMs": 39.112, + "sliceWarmMs": 3.241, + "prevSliceCasAvgMs": 18.871, + "bunAvgMs": 16.986, + "denoAvgMs": 44.877, + "nodeAvgMs": 68.991 + }, + { + "num": 29, + "code": "CS-03", + "id": "case_studies/03-multi-tenant-saas-plugin-mesh", + "label": "`CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap)", + "category": "case_studies", + "flagship": false, + "sliceCasMinMs": 12.585, + "sliceCasAvgMs": 13.171, + "sliceBinMinMs": 13.192, + "sliceBinAvgMs": 14.508, + "sliceSrcAvgMs": 42.204, + "sliceWarmMs": 5.274, + "prevSliceCasAvgMs": 13.687, + "bunAvgMs": 16.965, + "denoAvgMs": 49.996, + "nodeAvgMs": 87.777 + }, + { + "num": 30, + "code": "CS-04", + "id": "case_studies/04-wasm-zero-trust-cdr-pipeline", + "label": "`CS-04: case_studies/04-wasm-zero-trust-cdr-pipeline` (Wasm SimHash CDR)", + "category": "case_studies", + "flagship": false, + "sliceCasMinMs": 18.725, + "sliceCasAvgMs": 20.235, + "sliceBinMinMs": 19.3, + "sliceBinAvgMs": 21.128, + "sliceSrcAvgMs": 40.69, + "sliceWarmMs": 1.501, + "prevSliceCasAvgMs": 19.96, + "bunAvgMs": 20.878, + "denoAvgMs": 48.725, + "nodeAvgMs": 70.429 + }, + { + "num": 31, + "code": "CS-05", + "id": "case_studies/05-time-travel-chaos-fuzzer-payments", + "label": "`CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas)", + "category": "case_studies", + "flagship": true, + "sliceCasMinMs": 16.441, + "sliceCasAvgMs": 18.139, + "sliceBinMinMs": 16.447, + "sliceBinAvgMs": 19.258, + "sliceSrcAvgMs": 50.52, + "sliceWarmMs": 8.323, + "prevSliceCasAvgMs": 18.213, + "bunAvgMs": 21.102, + "denoAvgMs": 65.542, + "nodeAvgMs": 86.649 + } + ], + "rss": [ + { + "id": "App 2: NPM semver+ms+ini", + "label": "App 2: NPM semver+ms+ini", + "sliceKb": 14464, + "bunKb": 30336, + "denoKb": 47068, + "nodeKb": 71836 + }, + { + "id": "App 6: Telemetry + Flatted", + "label": "App 6: Telemetry + Flatted", + "sliceKb": 13776, + "bunKb": 29952, + "denoKb": 50800, + "nodeKb": 72724 + }, + { + "id": "App 21: RFC 6455 WS + Sec", + "label": "App 21: RFC 6455 WS + Sec", + "sliceKb": 14080, + "bunKb": 31860, + "denoKb": 50564, + "nodeKb": 95236 + }, + { + "id": "App 22: Workers + Sockets", + "label": "App 22: Workers + Sockets", + "sliceKb": 22144, + "bunKb": 40480, + "denoKb": 63880, + "nodeKb": 92416 + }, + { + "id": "App 23: Pure-Rust WASM", + "label": "App 23: Pure-Rust WASM", + "sliceKb": 19072, + "bunKb": 30848, + "denoKb": 48792, + "nodeKb": 80528 + }, + { + "id": "FW 1: Hono v4 Microservice", + "label": "FW 1: Hono v4 Microservice", + "sliceKb": 15360, + "bunKb": 31084, + "denoKb": 49664, + "nodeKb": 89376 + }, + { + "id": "FW 2: itty-router + UnJS", + "label": "FW 2: itty-router + UnJS", + "sliceKb": 14336, + "bunKb": 31872, + "denoKb": 48288, + "nodeKb": 87436 + }, + { + "id": "App 24: WASM + SSR", + "label": "App 24: WASM + SSR", + "sliceKb": 13832, + "bunKb": 32512, + "denoKb": 48528, + "nodeKb": 81024 + }, + { + "id": "FW 3: Express node:http", + "label": "FW 3: Express node:http", + "sliceKb": 15488, + "bunKb": 33152, + "denoKb": 47088, + "nodeKb": 80144 + }, + { + "id": "01-tot-autonomous-sre-agent", + "label": "01-tot-autonomous-sre-agent", + "sliceKb": 20992, + "bunKb": 31104, + "denoKb": 53228, + "nodeKb": 83588 + }, + { + "id": "02-mcp-code-mode-orchestrator", + "label": "02-mcp-code-mode-orchestrator", + "sliceKb": 18552, + "bunKb": 28288, + "denoKb": 46784, + "nodeKb": 80776 + }, + { + "id": "03-multi-tenant-saas-plugin-mesh", + "label": "03-multi-tenant-saas-plugin-mesh", + "sliceKb": 15104, + "bunKb": 26752, + "denoKb": 49484, + "nodeKb": 88456 + }, + { + "id": "04-wasm-zero-trust-cdr-pipeline", + "label": "04-wasm-zero-trust-cdr-pipeline", + "sliceKb": 20608, + "bunKb": 31360, + "denoKb": 49912, + "nodeKb": 80260 + }, + { + "id": "05-time-travel-chaos-fuzzer-payments", + "label": "05-time-travel-chaos-fuzzer-payments", + "sliceKb": 15232, + "bunKb": 29440, + "denoKb": 49488, + "nodeKb": 81444 + }, + { + "id": "FW 4: SvelteKit 3 + Svelte 5", + "label": "FW 4: SvelteKit 3 + Svelte 5", + "sliceKb": 21632, + "bunKb": 41216, + "denoKb": 56580, + "nodeKb": 85536 + } + ] +} diff --git a/tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md b/tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md new file mode 100644 index 0000000..cf164f2 --- /dev/null +++ b/tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md @@ -0,0 +1,113 @@ +# Slice (Nexus-JS) — Full 33-Workload & MicroVM Benchmark Report + +* **Slice Version:** `v0.10.12` (Commit `dc31f74`) +* **Generated Timestamp (UTC):** `2026-11-11T17:58:36Z` +* **Archive File:** [`tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md`](./bench_v0.10.12_20261111_175836Z_dc31f74.md) +* **Canonical Latest Report:** [`tests/reports/latest.md`](./latest.md) +* **Environment:** `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` +* **Compared Runtimes:** + * **Slice:** `v0.10.12` (Default `SLICEBC\x01` Precompiled Boa `CodeBlock` CAS + Monomorphic Inline Caching `get_fast` + Iterative ECMA-404 `JSON.parse`) + * **Bun:** `v1.4.4` (JavaScriptCore) + * **Deno:** `v2.9.8` (V8) + * **Node.js:** `v27.0.0-alpha.0.0.0` (V8 native TypeScript execution) + +--- + +## 1. Executive Summary + +Across all **33 real-world multi-file TypeScript applications, framework suites, and case studies**, Slice beats **Deno (`v2.9.8`)** on **33/33** workloads, beats **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33** workloads, beats **Bun (`v1.4.4`)** on **29/33** workloads in cold one-shot execution, and beats **all 3 runtimes on 33/33 workloads in `--warm` pooled isolate execution**. + +| Metric | Linux (`x86_64` Docker) | Windows (`x86_64` Host) | Comparison vs Runtimes & MicroVMs | +| :--- | :---: | :---: | :--- | +| **Single Isolate Cold-Start (Min / P50 / P99)** | **`0.94 us` / `1.02 us` / `4.27 us`** | **`1.40 us` / `1.60 us` / `2.30 us`** | **~120,000x faster than 125ms Firecracker VM** | +| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.74 ms`** (`9.82 MB` RSS) | **`2.24 ms`** (`11.82 MB` RSS) | **> 10,000x faster than container/VM swarms** | +| **500-Module Monorepo Cold Boot (`0 stat()`)** | **`3.408 ms`** (`467.08 us` in-mem) | **`5.637 ms`** (`640.00 us` in-mem) | **20.6x faster than Node.js (`1,500+ stat()`)** | +| **10,000 Direct Kernel Ring I/O Completions** | **`0.02 ms`** | **`5.11 ms`** | **Zero worker-thread lock contention** | +| **5-Ring Security Containment Verification** | **`5 / 5 PASS`** | **`5 / 5 PASS`** | **OCap + SES + Fuel + SSRF/DLP + MPK** | + +--- + +## 2. `slice serve` Multi-Tenant HTTP/1.1 Keep-Alive Throughput (`16,000` Reqs, 8 Sockets x 8 Pipeline) + +| Server / Runtime | Throughput (`req/s`) | Avg Latency / Req | Total Time (`16k` Reqs) | Relative Speedup vs Runtimes | +| :--- | :---: | :---: | :---: | :--- | +| **`slice serve` (Tier-0 CAS, `--workers=8`)** | **`154,794 req/s`** | **`6.46 us/req`** | **`103.4 ms`** | **`1.54x` faster than `Bun.serve` / `2.74x` Node.js** | +| **`slice serve` (Tier-1 WinterTC, `--workers=8`)** | **`147,564 req/s`** | **`6.78 us/req`** | **`108.4 ms`** | **`1.47x` faster than `Bun.serve` / `2.61x` Node.js** | +| **`Deno.serve` (`v2.9.8`, V8, No Per-Req Sandbox)** | `99,082 req/s` | `10.09 us/req` | `161.5 ms` | `0.99x` vs Bun | +| **`Bun.serve` (`v1.4.4`, JSC, No Per-Req Sandbox)** | `100,562 req/s` | `9.94 us/req` | `159.1 ms` | `1.00x` (Baseline) | +| **`Node.js http.createServer` (`v27.0.0-alpha.0.0.0`, V8)** | `56,447 req/s` | `17.72 us/req` | `283.5 ms` | `0.56x` vs Bun | + +--- + +## 3. Full 33-Workload Latency Comparison (20 Runs Each, Linux `x86_64` Docker) + +| # | Workload (`tests/apps/`, `tests/frameworks/`, `tests/case_studies/`) | Slice Cold `.cas` (`SLICEBC\x01`) | Slice Standalone Bin (`SLICEBC\x01`) | Slice Warm (`--warm`) | Previous `.cas` (`Delta`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Slice Speedup vs Bun / Node.js | +| :- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- | +| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.278 ms`** (`5.88 ms` Min) | **`6.621 ms`** | **`1.050 ms`** | `6.698 ms` (`-6.3%`) | `13.377 ms` | `35.217 ms` | `58.453 ms` | **`2.13x Bun` (`12.74x` Warm) / `9.31x Node`** | +| **02** | `02-npm-ecosystem-suite` (`semver` + `ms` + `ini`) | **`14.228 ms`** (`13.36 ms` Min) | **`14.717 ms`** | **`3.817 ms`** | `14.785 ms` (`-3.8%`) | `21.069 ms` | `55.166 ms` | `69.341 ms` | **`1.48x Bun` (`5.52x` Warm) / `4.87x Node`** | +| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.250 ms`** (`6.81 ms` Min) | **`7.800 ms`** | **`1.289 ms`** | `7.617 ms` (`-4.8%`) | `14.082 ms` | `43.228 ms` | `61.792 ms` | **`1.94x Bun` (`10.92x` Warm) / `8.52x Node`** | +| **04** | `04-edge-api-gateway` (`fast-querystring` + `ms`) | **`7.408 ms`** (`6.98 ms` Min) | **`8.033 ms`** | **`1.736 ms`** | `7.559 ms` (`-2.0%`) | `15.082 ms` | `41.232 ms` | `59.873 ms` | **`2.04x Bun` (`8.69x` Warm) / `8.08x Node`** | +| **05** | `05-jwt-oauth-session-guard` (`cookie` + `ms` + HMAC) | **`10.074 ms`** (`9.45 ms` Min) | **`10.543 ms`** | **`4.654 ms`** | `10.511 ms` (`-4.2%`) | `14.766 ms` | `45.411 ms` | `62.437 ms` | **`1.47x Bun` (`3.17x` Warm) / `6.20x Node`** | +| **06** | `06-telemetry-metrics-pipeline` (`bytes` + `flatted` + WAL) | **`12.738 ms`** (`12.19 ms` Min) | **`13.970 ms`** | **`4.330 ms`** | `14.045 ms` (`-9.3%`) | `16.697 ms` | `46.630 ms` | `65.983 ms` | **`1.31x Bun` (`3.86x` Warm) / `5.18x Node`** | +| **07** | `07-graphql-ast-validator` (`dlv` + `dset` + AST Cost) | **`8.937 ms`** (`8.40 ms` Min) | **`9.786 ms`** | **`3.758 ms`** | `9.193 ms` (`-2.8%`) | `13.020 ms` | `41.561 ms` | `61.914 ms` | **`1.46x Bun` (`3.46x` Warm) / `6.93x Node`** | +| **08** | `08-event-driven-state-journal` (`mitt` + `ms` + JSONL Replay) | **`11.229 ms`** (`10.45 ms` Min) | **`14.547 ms`** | **`5.258 ms`** | `11.667 ms` (`-3.8%`) | `15.902 ms` | `46.355 ms` | `62.965 ms` | **`1.42x Bun` (`3.02x` Warm) / `5.61x Node`** | +| **09** | `09-wintertc-web-router` (`Request` + `Response` + `URL`, 80 reqs) | **`14.771 ms`** (`14.22 ms` Min) | **`15.429 ms`** | **`9.085 ms`** | `16.323 ms` (`-9.5%`) | `13.919 ms` | `47.276 ms` | `85.354 ms` | **`1.53x Bun Warm` / `5.78x Node`** | +| **10** | `10-fullstack-bff-microservice` (`cookie` + `dlv` + `ms` + `ETag`, 60 reqs) | **`12.802 ms`** (`12.16 ms` Min) | **`13.616 ms`** | **`6.308 ms`** | `13.778 ms` (`-7.1%`) | `14.467 ms` | `50.395 ms` | `84.816 ms` | **`1.13x Bun` (`2.29x` Warm) / `6.63x Node`** | +| **11** | `11-static-asset-cdn-edge` (`bytes` + `ms` + `ETag` `304`, 80 reqs) | **`10.042 ms`** (`9.54 ms` Min) | **`10.698 ms`** | **`3.656 ms`** | `10.366 ms` (`-3.1%`) | `13.499 ms` | `47.729 ms` | `87.639 ms` | **`1.34x Bun` (`3.69x` Warm) / `8.73x Node`** | +| **12** | `12-ai-sse-token-streamer` (`mitt` + `ms` + SSE + DLP, 320 frames) | **`15.593 ms`** (`14.85 ms` Min) | **`15.893 ms`** | **`7.429 ms`** | `15.430 ms` (`1.1%`) | `15.213 ms` | `48.694 ms` | `90.253 ms` | **`2.05x Bun Warm` / `5.79x Node`** | +| **13** | `13-webhook-orchestrator-ssrf` (`fast-querystring` + `ms` + Live `fetch`) | **`15.199 ms`** (`14.71 ms` Min) | **`16.293 ms`** | **`6.388 ms`** | `17.563 ms` (`-13.5%`) | `18.942 ms` | `51.379 ms` | `111.110 ms` | **`1.25x Bun` (`2.97x` Warm) / `7.31x Node`** | +| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.828 ms`** (`15.01 ms` Min) | **`16.384 ms`** | **`6.697 ms`** | `16.692 ms` (`-5.2%`) | `21.200 ms` | `56.402 ms` | `108.617 ms` | **`1.34x Bun` (`3.17x` Warm) / `6.86x Node`** | +| **15** | `15-time-travel-test-suite` (`semver` + `ms` + `dlv` + `dset` + 24 Rollbacks) | **`15.273 ms`** (`14.53 ms` Min) | **`15.908 ms`** | **`4.757 ms`** | `16.035 ms` (`-4.8%`) | `24.939 ms` | `66.357 ms` | `84.077 ms` | **`1.63x Bun` (`5.24x` Warm) / `5.50x Node`** | +| **16** | `16-dotenv-dlp-config-vault` (`ini` + `cookie` + `bytes` + `.env` Auto-DLP) | **`7.598 ms`** (`6.83 ms` Min) | **`8.351 ms`** | **`1.234 ms`** | `8.079 ms` (`-6.0%`) | `14.844 ms` | `48.547 ms` | `67.533 ms` | **`1.95x Bun` (`12.03x` Warm) / `8.89x Node`** | +| **17** | `17-zero-trust-redirect-keepalive-mesh` (Keep-Alive/307/SSRF/DLP) | **`17.333 ms`** (`16.70 ms` Min) | **`18.916 ms`** | **`7.896 ms`** | `17.376 ms` (`-0.2%`) | `22.634 ms` | `55.132 ms` | `109.514 ms` | **`1.31x Bun` (`2.87x` Warm) / `6.32x Node`** | +| **18** | `18-async-event-loop-fanout-scheduler` (Timer Wheel/`Promise.all`/`AbortSignal`) | **`29.326 ms`** (`27.79 ms` Min) | **`30.533 ms`** | **`16.971 ms`** | `30.841 ms` (`-4.9%`) | `32.616 ms` | `70.809 ms` | `81.452 ms` | **`1.11x Bun` (`1.92x` Warm) / `2.78x Node`** | +| **19** | `19-wintertc-webcrypto-streams-edge` (WebCrypto/Streams/FormData/Clone) | **`8.118 ms`** (`7.68 ms` Min) | **`9.079 ms`** | **`1.396 ms`** | `8.515 ms` (`-4.7%`) | `13.794 ms` | `44.403 ms` | `86.921 ms` | **`1.70x Bun` (`9.88x` Warm) / `10.71x Node`** | +| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.261 ms`** (`10.21 ms` Min) | **`11.623 ms`** | **`0.496 ms`** | `11.298 ms` (`-0.3%`) | `25.080 ms` | `55.776 ms` | `73.350 ms` | **`2.23x Bun` (`50.56x` Warm) / `6.51x Node`** | +| **21** | `21-websocket-realtime-and-security-guard` (RFC 6455 `WebSocket` + 5-Ring Guard) | **`10.714 ms`** (`10.08 ms` Min) | **`11.463 ms`** | **`2.166 ms`** | `11.073 ms` (`-3.2%`) | `20.494 ms` | `51.042 ms` | `116.007 ms` | **`1.91x Bun` (`9.46x` Warm) / `10.83x Node`** | +| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.988 ms`** (`20.33 ms` Min) | **`21.637 ms`** | **`1.739 ms`** | `20.159 ms` (`4.1%`) | `57.152 ms` | `114.016 ms` | `101.723 ms` | **`2.72x Bun` (`32.86x` Warm) / `4.85x Node`** | +| **23** | `23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec) | **`15.548 ms`** (`14.73 ms` Min) | **`16.009 ms`** | **`1.970 ms`** | `15.430 ms` (`0.8%`) | `21.684 ms` | `40.550 ms` | `63.213 ms` | **`1.39x Bun` (`11.01x` Warm) / `4.07x Node`** | +| **24** | `24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline) | **`8.719 ms`** (`7.84 ms` Min) | **`8.994 ms`** | **`1.758 ms`** | `8.744 ms` (`-0.3%`) | `19.118 ms` | `42.405 ms` | `67.199 ms` | **`2.19x Bun` (`10.87x` Warm) / `7.71x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`14.653 ms`** (`14.06 ms` Min) | **`15.350 ms`** | **`5.593 ms`** | `15.219 ms` (`-3.7%`) | `19.858 ms` | `51.149 ms` | `94.150 ms` | **`1.36x Bun` (`3.55x` Warm) / `6.43x Node`** | +| **FW-02** | `FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS) | **`17.364 ms`** (`16.63 ms` Min) | **`17.789 ms`** | **`9.113 ms`** | `17.819 ms` (`-2.6%`) | `18.943 ms` | `46.132 ms` | `86.398 ms` | **`1.09x Bun` (`2.08x` Warm) / `4.98x Node`** | +| **FW-03** | `FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka) | **`16.742 ms`** (`16.24 ms` Min) | **`18.053 ms`** | **`0.927 ms`** | `17.267 ms` (`-3.0%`) | `34.374 ms` | `51.235 ms` | `84.492 ms` | **`2.05x Bun` (`37.08x` Warm) / `5.05x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`34.372 ms`** (`32.03 ms` Min) | **`34.188 ms`** | **`14.260 ms`** | `32.075 ms` (`7.2%`) | `43.709 ms` | `68.042 ms` | `108.544 ms` | **`1.28x Bun` (`3.07x` Warm) / `3.17x Node`** | +| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.837 ms`** (`32.96 ms` Min) | **`36.000 ms`** | **`12.991 ms`** | `34.706 ms` (`0.4%`) | `28.855 ms` | `73.549 ms` | `91.045 ms` | **`2.22x Bun Warm` / `2.61x Node`** | +| **CS-02** | `CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens) | **`19.490 ms`** (`17.87 ms` Min) | **`19.711 ms`** | **`3.241 ms`** | `18.871 ms` (`3.3%`) | `16.986 ms` | `44.877 ms` | `68.991 ms` | **`5.24x Bun Warm` / `3.54x Node`** | +| **CS-03** | `CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap) | **`13.171 ms`** (`12.59 ms` Min) | **`14.508 ms`** | **`5.274 ms`** | `13.687 ms` (`-3.8%`) | `16.965 ms` | `49.996 ms` | `87.777 ms` | **`1.29x Bun` (`3.22x` Warm) / `6.66x Node`** | +| **CS-04** | `CS-04: case_studies/04-wasm-zero-trust-cdr-pipeline` (Wasm SimHash CDR) | **`20.235 ms`** (`18.73 ms` Min) | **`21.128 ms`** | **`1.501 ms`** | `19.960 ms` (`1.4%`) | `20.878 ms` | `48.725 ms` | `70.429 ms` | **`1.03x Bun` (`13.91x` Warm) / `3.48x Node`** | +| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.139 ms`** (`16.44 ms` Min) | **`19.258 ms`** | **`8.323 ms`** | `18.213 ms` (`-0.4%`) | `21.102 ms` | `65.542 ms` | `86.649 ms` | **`1.16x Bun` (`2.54x` Warm) / `4.78x Node`** | + +--- + +## 4. Peak Process Memory Footprint (`Max RSS` via `/usr/bin/time -v`) + +| Workload | Slice (`SLICEBC\x01` Default) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Memory Advantage | +| :--- | :---: | :---: | :---: | :---: | :--- | +| **App 2: NPM semver+ms+ini** | **14,464 KB (14.13 MB)** | 30,336 KB (29.63 MB) | 47,068 KB (45.96 MB) | 71,836 KB (70.15 MB) | **4.97x less than Node / 2.10x less than Bun** | +| **App 6: Telemetry + Flatted** | **13,776 KB (13.45 MB)** | 29,952 KB (29.25 MB) | 50,800 KB (49.61 MB) | 72,724 KB (71.02 MB) | **5.28x less than Node / 2.17x less than Bun** | +| **App 21: RFC 6455 WS + Sec** | **14,080 KB (13.75 MB)** | 31,860 KB (31.11 MB) | 50,564 KB (49.38 MB) | 95,236 KB (93.00 MB) | **6.76x less than Node / 2.26x less than Bun** | +| **App 22: Workers + Sockets** | **22,144 KB (21.63 MB)** | 40,480 KB (39.53 MB) | 63,880 KB (62.38 MB) | 92,416 KB (90.25 MB) | **4.17x less than Node / 1.83x less than Bun** | +| **App 23: Pure-Rust WASM** | **19,072 KB (18.63 MB)** | 30,848 KB (30.13 MB) | 48,792 KB (47.65 MB) | 80,528 KB (78.64 MB) | **4.22x less than Node / 1.62x less than Bun** | +| **FW 1: Hono v4 Microservice** | **15,360 KB (15.00 MB)** | 31,084 KB (30.36 MB) | 49,664 KB (48.50 MB) | 89,376 KB (87.28 MB) | **5.82x less than Node / 2.02x less than Bun** | +| **FW 2: itty-router + UnJS** | **14,336 KB (14.00 MB)** | 31,872 KB (31.13 MB) | 48,288 KB (47.16 MB) | 87,436 KB (85.39 MB) | **6.10x less than Node / 2.22x less than Bun** | +| **App 24: WASM + SSR** | **13,832 KB (13.51 MB)** | 32,512 KB (31.75 MB) | 48,528 KB (47.39 MB) | 81,024 KB (79.13 MB) | **5.86x less than Node / 2.35x less than Bun** | +| **FW 3: Express node:http** | **15,488 KB (15.13 MB)** | 33,152 KB (32.38 MB) | 47,088 KB (45.98 MB) | 80,144 KB (78.27 MB) | **5.17x less than Node / 2.14x less than Bun** | +| **01-tot-autonomous-sre-agent** | **20,992 KB (20.50 MB)** | 31,104 KB (30.38 MB) | 53,228 KB (51.98 MB) | 83,588 KB (81.63 MB) | **3.98x less than Node / 1.48x less than Bun** | +| **02-mcp-code-mode-orchestrator** | **18,552 KB (18.12 MB)** | 28,288 KB (27.63 MB) | 46,784 KB (45.69 MB) | 80,776 KB (78.88 MB) | **4.35x less than Node / 1.52x less than Bun** | +| **03-multi-tenant-saas-plugin-mesh** | **15,104 KB (14.75 MB)** | 26,752 KB (26.13 MB) | 49,484 KB (48.32 MB) | 88,456 KB (86.38 MB) | **5.86x less than Node / 1.77x less than Bun** | +| **04-wasm-zero-trust-cdr-pipeline** | **20,608 KB (20.13 MB)** | 31,360 KB (30.63 MB) | 49,912 KB (48.74 MB) | 80,260 KB (78.38 MB) | **3.89x less than Node / 1.52x less than Bun** | +| **05-time-travel-chaos-fuzzer-payments** | **15,232 KB (14.88 MB)** | 29,440 KB (28.75 MB) | 49,488 KB (48.33 MB) | 81,444 KB (79.54 MB) | **5.35x less than Node / 1.93x less than Bun** | +| **FW 4: SvelteKit 3 + Svelte 5** | **21,632 KB (21.13 MB)** | 41,216 KB (40.25 MB) | 56,580 KB (55.25 MB) | 85,536 KB (83.53 MB) | **3.95x less than Node / 1.91x less than Bun** | + +--- + +## 5. Multi-Tenant Edge KV, AI Agent Checkpoints & 5-Ring Security Telemetry + +| Subsystem / Benchmark | Measured Telemetry | Status | +| :--- | :--- | :---: | +| **Sharded `Slice.kv` (`1,001` Get/Set/Incr Ops in Isolate)** | **`564.84 us`** total (`--warm`, `8,431 B` memory cage) | `PASS` | +| **Multi-Tenant `--tenant-dir` Zero-Downtime Hot-Swap** | Live atomic replacement of `tenant-alpha.cas` (`v1 -> v2-hot-swapped`) with isolated `Slice.kv` state | `PASS` | +| **Deterministic Time-Travel Replay (`--deterministic=20261019`)** | 100% bit-for-bit identical PRNG (`Math.random`) & virtual clock (`Date.now`, `performance.now`) | `PASS` | +| **Tree-of-Thought AI Agent (`Slice.checkpoint` + 3 `evalSandbox` + `restore`)** | **`74.64 us`** total (`3.50 us` child sandbox) | `PASS` | +| **Cloud Metadata SSRF (`169.254.169.254`) & Base64 Egress DLP Guard** | `SSRF_METADATA_BLOCKED` & `EGRESS_SECRET_LEAK_BLOCKED` deterministically trapped | `PASS` | +| **Built-In Model Context Protocol Server (`slice mcp --smoke-test`)** | JSON-RPC 2.0 `initialize`, `tools/list`, `tools/call` verified over `stdio` | `PASS` | diff --git a/tests/reports/latest.json b/tests/reports/latest.json index cc5a33e..e2f96cd 100644 --- a/tests/reports/latest.json +++ b/tests/reports/latest.json @@ -1,27 +1,27 @@ { "metadata": { - "version": "0.10.11", - "commit": "898e90b", - "timestampUtc": "2026-11-11T05:54:07Z", + "version": "0.10.12", + "commit": "dc31f74", + "timestampUtc": "2026-11-11T17:58:36Z", "environment": "Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)", "runtimes": { - "slice": "v0.10.11", + "slice": "v0.10.12", "bun": "v1.4.4", "deno": "v2.9.8", "node": "v27.0.0-alpha.0.0.0" }, - "archiveFile": "tests/reports/bench_v0.10.11_20261111_055407Z_898e90b.md", + "archiveFile": "tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md", "latestFile": "tests/reports/latest.md" }, "microvm": { "linux": { - "coldMinUs": 0.98, - "coldP50Us": 1.23, - "coldP99Us": 2.03, - "swarm1000Ms": 1.47, - "swarm1000RssMb": 9.7, + "coldMinUs": 0.94, + "coldP50Us": 1.02, + "coldP99Us": 4.27, + "swarm1000Ms": 1.74, + "swarm1000RssMb": 9.82, "cas500ColdMs": 3.408, - "cas500MemUs": 372.98, + "cas500MemUs": 467.08, "ringIo10kMs": 0.02 }, "windows": { @@ -37,36 +37,36 @@ }, "httpKeepAlive": { "sliceTier0": { - "rps": 153174, - "avgUs": 6.53, - "totalMs": 104.5 + "rps": 154794, + "avgUs": 6.46, + "totalMs": 103.4 }, "sliceTier1": { - "rps": 145192, - "avgUs": 6.89, - "totalMs": 110.2 + "rps": 147564, + "avgUs": 6.78, + "totalMs": 108.4 }, "deno": { - "rps": 99307, - "avgUs": 10.07, - "totalMs": 161.1 + "rps": 99082, + "avgUs": 10.09, + "totalMs": 161.5 }, "bun": { - "rps": 101093, - "avgUs": 9.89, - "totalMs": 158.3 + "rps": 100562, + "avgUs": 9.94, + "totalMs": 159.1 }, "node": { - "rps": 54637, - "avgUs": 18.3, - "totalMs": 292.8 + "rps": 56447, + "avgUs": 17.72, + "totalMs": 283.5 } }, "primitives": { - "kv1001Us": 706, + "kv1001Us": 564.84, "kvMemBytes": 8431, - "tot3SandboxesUs": 129.86, - "totSingleSandboxUs": 2.798 + "tot3SandboxesUs": 74.64, + "totSingleSandboxUs": 3.496 }, "workloads": [ { @@ -76,16 +76,16 @@ "label": "`01-fintech-checkout` (Multi-File TS + SHA-256)", "category": "core_edge_crypto", "flagship": true, - "sliceCasMinMs": 5.89, - "sliceCasAvgMs": 6.698, - "sliceBinMinMs": 6.149, - "sliceBinAvgMs": 6.942, - "sliceSrcAvgMs": 19.875, - "sliceWarmMs": 1.679, - "prevSliceCasAvgMs": 5.659, - "bunAvgMs": 13.445, - "denoAvgMs": 35.698, - "nodeAvgMs": 59.152 + "sliceCasMinMs": 5.883, + "sliceCasAvgMs": 6.278, + "sliceBinMinMs": 6.165, + "sliceBinAvgMs": 6.621, + "sliceSrcAvgMs": 16.378, + "sliceWarmMs": 1.05, + "prevSliceCasAvgMs": 6.698, + "bunAvgMs": 13.377, + "denoAvgMs": 35.217, + "nodeAvgMs": 58.453 }, { "num": 2, @@ -94,16 +94,16 @@ "label": "`02-npm-ecosystem-suite` (`semver` + `ms` + `ini`)", "category": "npm_ast_disk", "flagship": false, - "sliceCasMinMs": 13.708, - "sliceCasAvgMs": 14.785, - "sliceBinMinMs": 13.882, - "sliceBinAvgMs": 14.951, - "sliceSrcAvgMs": 39.724, - "sliceWarmMs": 6.431, - "prevSliceCasAvgMs": 12.659, - "bunAvgMs": 21.505, - "denoAvgMs": 52.831, - "nodeAvgMs": 69.235 + "sliceCasMinMs": 13.358, + "sliceCasAvgMs": 14.228, + "sliceBinMinMs": 13.462, + "sliceBinAvgMs": 14.717, + "sliceSrcAvgMs": 36.143, + "sliceWarmMs": 3.817, + "prevSliceCasAvgMs": 14.785, + "bunAvgMs": 21.069, + "denoAvgMs": 55.166, + "nodeAvgMs": 69.341 }, { "num": 3, @@ -112,16 +112,16 @@ "label": "`03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O)", "category": "npm_ast_disk", "flagship": true, - "sliceCasMinMs": 7.241, - "sliceCasAvgMs": 7.617, - "sliceBinMinMs": 7.385, - "sliceBinAvgMs": 7.855, - "sliceSrcAvgMs": 28.05, - "sliceWarmMs": 1.723, - "prevSliceCasAvgMs": 6.727, - "bunAvgMs": 13.792, - "denoAvgMs": 45.409, - "nodeAvgMs": 61.734 + "sliceCasMinMs": 6.807, + "sliceCasAvgMs": 7.25, + "sliceBinMinMs": 7.37, + "sliceBinAvgMs": 7.8, + "sliceSrcAvgMs": 25.973, + "sliceWarmMs": 1.289, + "prevSliceCasAvgMs": 7.617, + "bunAvgMs": 14.082, + "denoAvgMs": 43.228, + "nodeAvgMs": 61.792 }, { "num": 4, @@ -130,16 +130,16 @@ "label": "`04-edge-api-gateway` (`fast-querystring` + `ms`)", "category": "core_edge_crypto", "flagship": false, - "sliceCasMinMs": 7.1, - "sliceCasAvgMs": 7.559, - "sliceBinMinMs": 7.433, - "sliceBinAvgMs": 8.159, - "sliceSrcAvgMs": 23.001, - "sliceWarmMs": 3.956, - "prevSliceCasAvgMs": 6.624, - "bunAvgMs": 14.699, - "denoAvgMs": 41.787, - "nodeAvgMs": 62.835 + "sliceCasMinMs": 6.977, + "sliceCasAvgMs": 7.408, + "sliceBinMinMs": 7.344, + "sliceBinAvgMs": 8.033, + "sliceSrcAvgMs": 21.1, + "sliceWarmMs": 1.736, + "prevSliceCasAvgMs": 7.559, + "bunAvgMs": 15.082, + "denoAvgMs": 41.232, + "nodeAvgMs": 59.873 }, { "num": 5, @@ -148,16 +148,16 @@ "label": "`05-jwt-oauth-session-guard` (`cookie` + `ms` + HMAC)", "category": "core_edge_crypto", "flagship": false, - "sliceCasMinMs": 10.002, - "sliceCasAvgMs": 10.511, - "sliceBinMinMs": 10.381, - "sliceBinAvgMs": 11.042, - "sliceSrcAvgMs": 24.863, - "sliceWarmMs": 7.876, - "prevSliceCasAvgMs": 9.604, - "bunAvgMs": 14.601, - "denoAvgMs": 44.318, - "nodeAvgMs": 62.788 + "sliceCasMinMs": 9.447, + "sliceCasAvgMs": 10.074, + "sliceBinMinMs": 9.907, + "sliceBinAvgMs": 10.543, + "sliceSrcAvgMs": 21.049, + "sliceWarmMs": 4.654, + "prevSliceCasAvgMs": 10.511, + "bunAvgMs": 14.766, + "denoAvgMs": 45.411, + "nodeAvgMs": 62.437 }, { "num": 6, @@ -166,16 +166,16 @@ "label": "`06-telemetry-metrics-pipeline` (`bytes` + `flatted` + WAL)", "category": "npm_ast_disk", "flagship": false, - "sliceCasMinMs": 13.21, - "sliceCasAvgMs": 14.045, - "sliceBinMinMs": 13.09, - "sliceBinAvgMs": 13.994, - "sliceSrcAvgMs": 39.225, - "sliceWarmMs": 6.433, - "prevSliceCasAvgMs": 13.023, - "bunAvgMs": 17.194, - "denoAvgMs": 48.119, - "nodeAvgMs": 65.404 + "sliceCasMinMs": 12.188, + "sliceCasAvgMs": 12.738, + "sliceBinMinMs": 12.578, + "sliceBinAvgMs": 13.97, + "sliceSrcAvgMs": 31.589, + "sliceWarmMs": 4.33, + "prevSliceCasAvgMs": 14.045, + "bunAvgMs": 16.697, + "denoAvgMs": 46.63, + "nodeAvgMs": 65.983 }, { "num": 7, @@ -184,16 +184,16 @@ "label": "`07-graphql-ast-validator` (`dlv` + `dset` + AST Cost)", "category": "npm_ast_disk", "flagship": false, - "sliceCasMinMs": 8.436, - "sliceCasAvgMs": 9.193, - "sliceBinMinMs": 9.125, - "sliceBinAvgMs": 9.804, - "sliceSrcAvgMs": 21.939, - "sliceWarmMs": 5.195, - "prevSliceCasAvgMs": 8.178, - "bunAvgMs": 13.052, - "denoAvgMs": 40.817, - "nodeAvgMs": 61.714 + "sliceCasMinMs": 8.403, + "sliceCasAvgMs": 8.937, + "sliceBinMinMs": 8.808, + "sliceBinAvgMs": 9.786, + "sliceSrcAvgMs": 19.218, + "sliceWarmMs": 3.758, + "prevSliceCasAvgMs": 9.193, + "bunAvgMs": 13.02, + "denoAvgMs": 41.561, + "nodeAvgMs": 61.914 }, { "num": 8, @@ -202,16 +202,16 @@ "label": "`08-event-driven-state-journal` (`mitt` + `ms` + JSONL Replay)", "category": "npm_ast_disk", "flagship": false, - "sliceCasMinMs": 11.041, - "sliceCasAvgMs": 11.667, - "sliceBinMinMs": 11.437, - "sliceBinAvgMs": 11.989, - "sliceSrcAvgMs": 34.016, - "sliceWarmMs": 5.807, - "prevSliceCasAvgMs": 10.036, - "bunAvgMs": 16.467, - "denoAvgMs": 46.579, - "nodeAvgMs": 66.675 + "sliceCasMinMs": 10.454, + "sliceCasAvgMs": 11.229, + "sliceBinMinMs": 11.147, + "sliceBinAvgMs": 14.547, + "sliceSrcAvgMs": 30.157, + "sliceWarmMs": 5.258, + "prevSliceCasAvgMs": 11.667, + "bunAvgMs": 15.902, + "denoAvgMs": 46.355, + "nodeAvgMs": 62.965 }, { "num": 9, @@ -220,16 +220,16 @@ "label": "`09-wintertc-web-router` (`Request` + `Response` + `URL`, 80 reqs)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 15.027, - "sliceCasAvgMs": 16.323, - "sliceBinMinMs": 15.246, - "sliceBinAvgMs": 16.184, - "sliceSrcAvgMs": 35.183, - "sliceWarmMs": 9.689, - "prevSliceCasAvgMs": 13.781, - "bunAvgMs": 13.954, - "denoAvgMs": 47.109, - "nodeAvgMs": 86.236 + "sliceCasMinMs": 14.222, + "sliceCasAvgMs": 14.771, + "sliceBinMinMs": 14.52, + "sliceBinAvgMs": 15.429, + "sliceSrcAvgMs": 30.804, + "sliceWarmMs": 9.085, + "prevSliceCasAvgMs": 16.323, + "bunAvgMs": 13.919, + "denoAvgMs": 47.276, + "nodeAvgMs": 85.354 }, { "num": 10, @@ -238,16 +238,16 @@ "label": "`10-fullstack-bff-microservice` (`cookie` + `dlv` + `ms` + `ETag`, 60 reqs)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 12.697, - "sliceCasAvgMs": 13.778, - "sliceBinMinMs": 12.948, - "sliceBinAvgMs": 13.793, - "sliceSrcAvgMs": 34.717, - "sliceWarmMs": 7.468, - "prevSliceCasAvgMs": 12.008, - "bunAvgMs": 14.611, - "denoAvgMs": 47.719, - "nodeAvgMs": 85.928 + "sliceCasMinMs": 12.158, + "sliceCasAvgMs": 12.802, + "sliceBinMinMs": 12.643, + "sliceBinAvgMs": 13.616, + "sliceSrcAvgMs": 30.565, + "sliceWarmMs": 6.308, + "prevSliceCasAvgMs": 13.778, + "bunAvgMs": 14.467, + "denoAvgMs": 50.395, + "nodeAvgMs": 84.816 }, { "num": 11, @@ -256,16 +256,16 @@ "label": "`11-static-asset-cdn-edge` (`bytes` + `ms` + `ETag` `304`, 80 reqs)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 9.732, - "sliceCasAvgMs": 10.366, - "sliceBinMinMs": 9.97, - "sliceBinAvgMs": 10.611, - "sliceSrcAvgMs": 30.1, - "sliceWarmMs": 4.123, - "prevSliceCasAvgMs": 9.199, - "bunAvgMs": 13.422, - "denoAvgMs": 49.132, - "nodeAvgMs": 86.083 + "sliceCasMinMs": 9.535, + "sliceCasAvgMs": 10.042, + "sliceBinMinMs": 10.034, + "sliceBinAvgMs": 10.698, + "sliceSrcAvgMs": 27.244, + "sliceWarmMs": 3.656, + "prevSliceCasAvgMs": 10.366, + "bunAvgMs": 13.499, + "denoAvgMs": 47.729, + "nodeAvgMs": 87.639 }, { "num": 12, @@ -274,16 +274,16 @@ "label": "`12-ai-sse-token-streamer` (`mitt` + `ms` + SSE + DLP, 320 frames)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 14.883, - "sliceCasAvgMs": 15.43, - "sliceBinMinMs": 14.974, - "sliceBinAvgMs": 15.783, - "sliceSrcAvgMs": 33.461, - "sliceWarmMs": 9.011, - "prevSliceCasAvgMs": 14.114, - "bunAvgMs": 15.047, - "denoAvgMs": 49.863, - "nodeAvgMs": 89.926 + "sliceCasMinMs": 14.853, + "sliceCasAvgMs": 15.593, + "sliceBinMinMs": 14.905, + "sliceBinAvgMs": 15.893, + "sliceSrcAvgMs": 31.524, + "sliceWarmMs": 7.429, + "prevSliceCasAvgMs": 15.43, + "bunAvgMs": 15.213, + "denoAvgMs": 48.694, + "nodeAvgMs": 90.253 }, { "num": 13, @@ -292,16 +292,16 @@ "label": "`13-webhook-orchestrator-ssrf` (`fast-querystring` + `ms` + Live `fetch`)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 15.401, - "sliceCasAvgMs": 17.563, - "sliceBinMinMs": 15.122, - "sliceBinAvgMs": 15.976, - "sliceSrcAvgMs": 38.701, - "sliceWarmMs": 6.678, - "prevSliceCasAvgMs": 12.492, - "bunAvgMs": 19.819, - "denoAvgMs": 51.823, - "nodeAvgMs": 113.097 + "sliceCasMinMs": 14.708, + "sliceCasAvgMs": 15.199, + "sliceBinMinMs": 15.196, + "sliceBinAvgMs": 16.293, + "sliceSrcAvgMs": 35.193, + "sliceWarmMs": 6.388, + "prevSliceCasAvgMs": 17.563, + "bunAvgMs": 18.942, + "denoAvgMs": 51.379, + "nodeAvgMs": 111.11 }, { "num": 14, @@ -310,16 +310,16 @@ "label": "`14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`)", "category": "wintertc_fetch_dlp", "flagship": true, - "sliceCasMinMs": 15.444, - "sliceCasAvgMs": 16.692, - "sliceBinMinMs": 15.467, - "sliceBinAvgMs": 16.84, - "sliceSrcAvgMs": 36.08, - "sliceWarmMs": 7.968, - "prevSliceCasAvgMs": 14.838, - "bunAvgMs": 21.633, - "denoAvgMs": 53.171, - "nodeAvgMs": 112.883 + "sliceCasMinMs": 15.009, + "sliceCasAvgMs": 15.828, + "sliceBinMinMs": 15.322, + "sliceBinAvgMs": 16.384, + "sliceSrcAvgMs": 32.722, + "sliceWarmMs": 6.697, + "prevSliceCasAvgMs": 16.692, + "bunAvgMs": 21.2, + "denoAvgMs": 56.402, + "nodeAvgMs": 108.617 }, { "num": 15, @@ -328,16 +328,16 @@ "label": "`15-time-travel-test-suite` (`semver` + `ms` + `dlv` + `dset` + 24 Rollbacks)", "category": "realtime_workers_wasm", "flagship": false, - "sliceCasMinMs": 15.355, - "sliceCasAvgMs": 16.035, - "sliceBinMinMs": 15.27, - "sliceBinAvgMs": 15.777, - "sliceSrcAvgMs": 50.143, - "sliceWarmMs": 4.855, - "prevSliceCasAvgMs": 14.887, - "bunAvgMs": 25.404, - "denoAvgMs": 67.449, - "nodeAvgMs": 84.002 + "sliceCasMinMs": 14.526, + "sliceCasAvgMs": 15.273, + "sliceBinMinMs": 14.875, + "sliceBinAvgMs": 15.908, + "sliceSrcAvgMs": 45.721, + "sliceWarmMs": 4.757, + "prevSliceCasAvgMs": 16.035, + "bunAvgMs": 24.939, + "denoAvgMs": 66.357, + "nodeAvgMs": 84.077 }, { "num": 16, @@ -346,16 +346,16 @@ "label": "`16-dotenv-dlp-config-vault` (`ini` + `cookie` + `bytes` + `.env` Auto-DLP)", "category": "core_edge_crypto", "flagship": false, - "sliceCasMinMs": 7.456, - "sliceCasAvgMs": 8.079, - "sliceBinMinMs": 7.75, - "sliceBinAvgMs": 8.455, - "sliceSrcAvgMs": 32.34, - "sliceWarmMs": 1.385, - "prevSliceCasAvgMs": 7.467, - "bunAvgMs": 14.281, - "denoAvgMs": 44.477, - "nodeAvgMs": 63.767 + "sliceCasMinMs": 6.834, + "sliceCasAvgMs": 7.598, + "sliceBinMinMs": 7.463, + "sliceBinAvgMs": 8.351, + "sliceSrcAvgMs": 29.672, + "sliceWarmMs": 1.234, + "prevSliceCasAvgMs": 8.079, + "bunAvgMs": 14.844, + "denoAvgMs": 48.547, + "nodeAvgMs": 67.533 }, { "num": 17, @@ -364,16 +364,16 @@ "label": "`17-zero-trust-redirect-keepalive-mesh` (Keep-Alive/307/SSRF/DLP)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 16.669, - "sliceCasAvgMs": 17.376, - "sliceBinMinMs": 17.237, - "sliceBinAvgMs": 19.974, - "sliceSrcAvgMs": 42.924, - "sliceWarmMs": 9.042, - "prevSliceCasAvgMs": 15.779, - "bunAvgMs": 22.206, - "denoAvgMs": 55.655, - "nodeAvgMs": 112.3 + "sliceCasMinMs": 16.695, + "sliceCasAvgMs": 17.333, + "sliceBinMinMs": 17.509, + "sliceBinAvgMs": 18.916, + "sliceSrcAvgMs": 41.891, + "sliceWarmMs": 7.896, + "prevSliceCasAvgMs": 17.376, + "bunAvgMs": 22.634, + "denoAvgMs": 55.132, + "nodeAvgMs": 109.514 }, { "num": 18, @@ -382,16 +382,16 @@ "label": "`18-async-event-loop-fanout-scheduler` (Timer Wheel/`Promise.all`/`AbortSignal`)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 28.841, - "sliceCasAvgMs": 30.841, - "sliceBinMinMs": 29.821, - "sliceBinAvgMs": 31.316, - "sliceSrcAvgMs": 49.817, - "sliceWarmMs": 17.473, - "prevSliceCasAvgMs": 29.409, - "bunAvgMs": 32.649, - "denoAvgMs": 73.881, - "nodeAvgMs": 81.441 + "sliceCasMinMs": 27.785, + "sliceCasAvgMs": 29.326, + "sliceBinMinMs": 28.861, + "sliceBinAvgMs": 30.533, + "sliceSrcAvgMs": 45.923, + "sliceWarmMs": 16.971, + "prevSliceCasAvgMs": 30.841, + "bunAvgMs": 32.616, + "denoAvgMs": 70.809, + "nodeAvgMs": 81.452 }, { "num": 19, @@ -400,16 +400,16 @@ "label": "`19-wintertc-webcrypto-streams-edge` (WebCrypto/Streams/FormData/Clone)", "category": "wintertc_fetch_dlp", "flagship": false, - "sliceCasMinMs": 8.12, - "sliceCasAvgMs": 8.515, - "sliceBinMinMs": 8.353, - "sliceBinAvgMs": 8.959, - "sliceSrcAvgMs": 33.819, - "sliceWarmMs": 1.493, - "prevSliceCasAvgMs": 8.407, - "bunAvgMs": 14.021, - "denoAvgMs": 45.631, - "nodeAvgMs": 87.941 + "sliceCasMinMs": 7.676, + "sliceCasAvgMs": 8.118, + "sliceBinMinMs": 8.181, + "sliceBinAvgMs": 9.079, + "sliceSrcAvgMs": 31.573, + "sliceWarmMs": 1.396, + "prevSliceCasAvgMs": 8.515, + "bunAvgMs": 13.794, + "denoAvgMs": 44.403, + "nodeAvgMs": 86.921 }, { "num": 20, @@ -418,16 +418,16 @@ "label": "`20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler)", "category": "npm_ast_disk", "flagship": true, - "sliceCasMinMs": 10.48, - "sliceCasAvgMs": 11.298, - "sliceBinMinMs": 10.895, - "sliceBinAvgMs": 11.547, - "sliceSrcAvgMs": 48.129, - "sliceWarmMs": 0.612, - "prevSliceCasAvgMs": 10.148, - "bunAvgMs": 22.4, - "denoAvgMs": 54.998, - "nodeAvgMs": 76.295 + "sliceCasMinMs": 10.205, + "sliceCasAvgMs": 11.261, + "sliceBinMinMs": 10.964, + "sliceBinAvgMs": 11.623, + "sliceSrcAvgMs": 43.366, + "sliceWarmMs": 0.496, + "prevSliceCasAvgMs": 11.298, + "bunAvgMs": 25.08, + "denoAvgMs": 55.776, + "nodeAvgMs": 73.35 }, { "num": 21, @@ -436,16 +436,16 @@ "label": "`21-websocket-realtime-and-security-guard` (RFC 6455 `WebSocket` + 5-Ring Guard)", "category": "realtime_workers_wasm", "flagship": false, - "sliceCasMinMs": 10.661, - "sliceCasAvgMs": 11.073, - "sliceBinMinMs": 10.982, - "sliceBinAvgMs": 11.583, - "sliceSrcAvgMs": 45.083, - "sliceWarmMs": 3.777, - "prevSliceCasAvgMs": 10.288, - "bunAvgMs": 20.349, - "denoAvgMs": 52.16, - "nodeAvgMs": 117.179 + "sliceCasMinMs": 10.084, + "sliceCasAvgMs": 10.714, + "sliceBinMinMs": 10.452, + "sliceBinAvgMs": 11.463, + "sliceSrcAvgMs": 41.725, + "sliceWarmMs": 2.166, + "prevSliceCasAvgMs": 11.073, + "bunAvgMs": 20.494, + "denoAvgMs": 51.042, + "nodeAvgMs": 116.007 }, { "num": 22, @@ -454,16 +454,16 @@ "label": "`22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec)", "category": "realtime_workers_wasm", "flagship": true, - "sliceCasMinMs": 19.421, - "sliceCasAvgMs": 20.159, - "sliceBinMinMs": 19.648, - "sliceBinAvgMs": 20.547, - "sliceSrcAvgMs": 37.099, - "sliceWarmMs": 2.228, - "prevSliceCasAvgMs": 19.101, - "bunAvgMs": 55.925, - "denoAvgMs": 112.632, - "nodeAvgMs": 101.841 + "sliceCasMinMs": 20.328, + "sliceCasAvgMs": 20.988, + "sliceBinMinMs": 20.372, + "sliceBinAvgMs": 21.637, + "sliceSrcAvgMs": 40.911, + "sliceWarmMs": 1.739, + "prevSliceCasAvgMs": 20.159, + "bunAvgMs": 57.152, + "denoAvgMs": 114.016, + "nodeAvgMs": 101.723 }, { "num": 23, @@ -472,16 +472,16 @@ "label": "`23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec)", "category": "realtime_workers_wasm", "flagship": false, - "sliceCasMinMs": 14.75, - "sliceCasAvgMs": 15.43, - "sliceBinMinMs": 15.35, - "sliceBinAvgMs": 16.036, - "sliceSrcAvgMs": 26.602, - "sliceWarmMs": 1.954, - "prevSliceCasAvgMs": 13.643, - "bunAvgMs": 21.292, - "denoAvgMs": 42.492, - "nodeAvgMs": 61.274 + "sliceCasMinMs": 14.733, + "sliceCasAvgMs": 15.548, + "sliceBinMinMs": 15.357, + "sliceBinAvgMs": 16.009, + "sliceSrcAvgMs": 27.894, + "sliceWarmMs": 1.97, + "prevSliceCasAvgMs": 15.43, + "bunAvgMs": 21.684, + "denoAvgMs": 40.55, + "nodeAvgMs": 63.213 }, { "num": 24, @@ -490,16 +490,16 @@ "label": "`24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline)", "category": "realtime_workers_wasm", "flagship": false, - "sliceCasMinMs": 8.23, - "sliceCasAvgMs": 8.744, - "sliceBinMinMs": 8.805, - "sliceBinAvgMs": 9.198, - "sliceSrcAvgMs": 31.27, - "sliceWarmMs": 1.838, - "prevSliceCasAvgMs": 8.336, - "bunAvgMs": 20.232, - "denoAvgMs": 43.778, - "nodeAvgMs": 68.091 + "sliceCasMinMs": 7.843, + "sliceCasAvgMs": 8.719, + "sliceBinMinMs": 8.124, + "sliceBinAvgMs": 8.994, + "sliceSrcAvgMs": 27.54, + "sliceWarmMs": 1.758, + "prevSliceCasAvgMs": 8.744, + "bunAvgMs": 19.118, + "denoAvgMs": 42.405, + "nodeAvgMs": 67.199 }, { "num": 25, @@ -508,16 +508,16 @@ "label": "`FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`)", "category": "frameworks", "flagship": true, - "sliceCasMinMs": 14.463, - "sliceCasAvgMs": 15.219, - "sliceBinMinMs": 15.066, - "sliceBinAvgMs": 15.812, - "sliceSrcAvgMs": 54.007, - "sliceWarmMs": 5.631, - "prevSliceCasAvgMs": 13.701, - "bunAvgMs": 19.633, - "denoAvgMs": 52.596, - "nodeAvgMs": 94.61 + "sliceCasMinMs": 14.056, + "sliceCasAvgMs": 14.653, + "sliceBinMinMs": 14.232, + "sliceBinAvgMs": 15.35, + "sliceSrcAvgMs": 49.303, + "sliceWarmMs": 5.593, + "prevSliceCasAvgMs": 15.219, + "bunAvgMs": 19.858, + "denoAvgMs": 51.149, + "nodeAvgMs": 94.15 }, { "num": 26, @@ -526,16 +526,16 @@ "label": "`FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS)", "category": "frameworks", "flagship": false, - "sliceCasMinMs": 17.136, - "sliceCasAvgMs": 17.819, - "sliceBinMinMs": 17.21, - "sliceBinAvgMs": 18.045, - "sliceSrcAvgMs": 50.395, - "sliceWarmMs": 9.665, - "prevSliceCasAvgMs": 16.349, - "bunAvgMs": 20.945, - "denoAvgMs": 46.351, - "nodeAvgMs": 87.095 + "sliceCasMinMs": 16.631, + "sliceCasAvgMs": 17.364, + "sliceBinMinMs": 16.825, + "sliceBinAvgMs": 17.789, + "sliceSrcAvgMs": 46.638, + "sliceWarmMs": 9.113, + "prevSliceCasAvgMs": 17.819, + "bunAvgMs": 18.943, + "denoAvgMs": 46.132, + "nodeAvgMs": 86.398 }, { "num": 32, @@ -544,16 +544,16 @@ "label": "`FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka)", "category": "frameworks", "flagship": false, - "sliceCasMinMs": 16.453, - "sliceCasAvgMs": 17.267, - "sliceBinMinMs": 16.672, - "sliceBinAvgMs": 17.638, - "sliceSrcAvgMs": 24.115, - "sliceWarmMs": 1.311, - "prevSliceCasAvgMs": 14.809, - "bunAvgMs": 34.805, - "denoAvgMs": 51.001, - "nodeAvgMs": 82.31 + "sliceCasMinMs": 16.237, + "sliceCasAvgMs": 16.742, + "sliceBinMinMs": 16.633, + "sliceBinAvgMs": 18.053, + "sliceSrcAvgMs": 24.203, + "sliceWarmMs": 0.927, + "prevSliceCasAvgMs": 17.267, + "bunAvgMs": 34.374, + "denoAvgMs": 51.235, + "nodeAvgMs": 84.492 }, { "num": 33, @@ -562,16 +562,16 @@ "label": "`FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`)", "category": "frameworks", "flagship": true, - "sliceCasMinMs": 31.118, - "sliceCasAvgMs": 32.075, - "sliceBinMinMs": 31.303, - "sliceBinAvgMs": 32.819, - "sliceSrcAvgMs": 154.938, - "sliceWarmMs": 16.953, - "prevSliceCasAvgMs": 33.452, - "bunAvgMs": 43.525, - "denoAvgMs": 74.247, - "nodeAvgMs": 112.271 + "sliceCasMinMs": 32.033, + "sliceCasAvgMs": 34.372, + "sliceBinMinMs": 31.777, + "sliceBinAvgMs": 34.188, + "sliceSrcAvgMs": 146.899, + "sliceWarmMs": 14.26, + "prevSliceCasAvgMs": 32.075, + "bunAvgMs": 43.709, + "denoAvgMs": 68.042, + "nodeAvgMs": 108.544 }, { "num": 27, @@ -580,16 +580,16 @@ "label": "`CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes)", "category": "case_studies", "flagship": true, - "sliceCasMinMs": 30.764, - "sliceCasAvgMs": 34.706, - "sliceBinMinMs": 31.082, - "sliceBinAvgMs": 32.179, - "sliceSrcAvgMs": 76.709, - "sliceWarmMs": 13.019, - "prevSliceCasAvgMs": 29.806, - "bunAvgMs": 28.387, - "denoAvgMs": 72.119, - "nodeAvgMs": 88.96 + "sliceCasMinMs": 32.956, + "sliceCasAvgMs": 34.837, + "sliceBinMinMs": 32.622, + "sliceBinAvgMs": 36, + "sliceSrcAvgMs": 77.212, + "sliceWarmMs": 12.991, + "prevSliceCasAvgMs": 34.706, + "bunAvgMs": 28.855, + "denoAvgMs": 73.549, + "nodeAvgMs": 91.045 }, { "num": 28, @@ -598,16 +598,16 @@ "label": "`CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens)", "category": "case_studies", "flagship": false, - "sliceCasMinMs": 18.21, - "sliceCasAvgMs": 18.871, - "sliceBinMinMs": 18.557, - "sliceBinAvgMs": 19.492, - "sliceSrcAvgMs": 40.3, - "sliceWarmMs": 5.409, - "prevSliceCasAvgMs": 16.342, - "bunAvgMs": 16.618, - "denoAvgMs": 43.05, - "nodeAvgMs": 68.969 + "sliceCasMinMs": 17.868, + "sliceCasAvgMs": 19.49, + "sliceBinMinMs": 18.675, + "sliceBinAvgMs": 19.711, + "sliceSrcAvgMs": 39.112, + "sliceWarmMs": 3.241, + "prevSliceCasAvgMs": 18.871, + "bunAvgMs": 16.986, + "denoAvgMs": 44.877, + "nodeAvgMs": 68.991 }, { "num": 29, @@ -616,16 +616,16 @@ "label": "`CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap)", "category": "case_studies", "flagship": false, - "sliceCasMinMs": 13.074, - "sliceCasAvgMs": 13.687, - "sliceBinMinMs": 13.642, - "sliceBinAvgMs": 14.343, - "sliceSrcAvgMs": 45.905, - "sliceWarmMs": 5.404, - "prevSliceCasAvgMs": 12.12, - "bunAvgMs": 16.388, - "denoAvgMs": 48.628, - "nodeAvgMs": 85.608 + "sliceCasMinMs": 12.585, + "sliceCasAvgMs": 13.171, + "sliceBinMinMs": 13.192, + "sliceBinAvgMs": 14.508, + "sliceSrcAvgMs": 42.204, + "sliceWarmMs": 5.274, + "prevSliceCasAvgMs": 13.687, + "bunAvgMs": 16.965, + "denoAvgMs": 49.996, + "nodeAvgMs": 87.777 }, { "num": 30, @@ -634,16 +634,16 @@ "label": "`CS-04: case_studies/04-wasm-zero-trust-cdr-pipeline` (Wasm SimHash CDR)", "category": "case_studies", "flagship": false, - "sliceCasMinMs": 19.136, - "sliceCasAvgMs": 19.96, - "sliceBinMinMs": 19.78, - "sliceBinAvgMs": 20.818, - "sliceSrcAvgMs": 44.226, - "sliceWarmMs": 2.104, - "prevSliceCasAvgMs": 15.992, - "bunAvgMs": 19.218, - "denoAvgMs": 44.875, - "nodeAvgMs": 68.073 + "sliceCasMinMs": 18.725, + "sliceCasAvgMs": 20.235, + "sliceBinMinMs": 19.3, + "sliceBinAvgMs": 21.128, + "sliceSrcAvgMs": 40.69, + "sliceWarmMs": 1.501, + "prevSliceCasAvgMs": 19.96, + "bunAvgMs": 20.878, + "denoAvgMs": 48.725, + "nodeAvgMs": 70.429 }, { "num": 31, @@ -652,138 +652,138 @@ "label": "`CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas)", "category": "case_studies", "flagship": true, - "sliceCasMinMs": 17.274, - "sliceCasAvgMs": 18.213, - "sliceBinMinMs": 17.634, - "sliceBinAvgMs": 19.284, - "sliceSrcAvgMs": 55.703, - "sliceWarmMs": 7.924, - "prevSliceCasAvgMs": 18.391, - "bunAvgMs": 20.307, - "denoAvgMs": 62.714, - "nodeAvgMs": 84.144 + "sliceCasMinMs": 16.441, + "sliceCasAvgMs": 18.139, + "sliceBinMinMs": 16.447, + "sliceBinAvgMs": 19.258, + "sliceSrcAvgMs": 50.52, + "sliceWarmMs": 8.323, + "prevSliceCasAvgMs": 18.213, + "bunAvgMs": 21.102, + "denoAvgMs": 65.542, + "nodeAvgMs": 86.649 } ], "rss": [ { "id": "App 2: NPM semver+ms+ini", "label": "App 2: NPM semver+ms+ini", - "sliceKb": 14592, - "bunKb": 29952, - "denoKb": 47344, - "nodeKb": 71584 + "sliceKb": 14464, + "bunKb": 30336, + "denoKb": 47068, + "nodeKb": 71836 }, { "id": "App 6: Telemetry + Flatted", "label": "App 6: Telemetry + Flatted", - "sliceKb": 15104, - "bunKb": 30464, - "denoKb": 50928, - "nodeKb": 72860 + "sliceKb": 13776, + "bunKb": 29952, + "denoKb": 50800, + "nodeKb": 72724 }, { "id": "App 21: RFC 6455 WS + Sec", "label": "App 21: RFC 6455 WS + Sec", - "sliceKb": 15104, - "bunKb": 31732, - "denoKb": 50756, - "nodeKb": 95356 + "sliceKb": 14080, + "bunKb": 31860, + "denoKb": 50564, + "nodeKb": 95236 }, { "id": "App 22: Workers + Sockets", "label": "App 22: Workers + Sockets", - "sliceKb": 22272, - "bunKb": 41688, - "denoKb": 63236, - "nodeKb": 94180 + "sliceKb": 22144, + "bunKb": 40480, + "denoKb": 63880, + "nodeKb": 92416 }, { "id": "App 23: Pure-Rust WASM", "label": "App 23: Pure-Rust WASM", - "sliceKb": 19200, - "bunKb": 30720, - "denoKb": 48784, - "nodeKb": 80660 + "sliceKb": 19072, + "bunKb": 30848, + "denoKb": 48792, + "nodeKb": 80528 }, { "id": "FW 1: Hono v4 Microservice", "label": "FW 1: Hono v4 Microservice", - "sliceKb": 15872, - "bunKb": 30976, - "denoKb": 49144, - "nodeKb": 88816 + "sliceKb": 15360, + "bunKb": 31084, + "denoKb": 49664, + "nodeKb": 89376 }, { "id": "FW 2: itty-router + UnJS", "label": "FW 2: itty-router + UnJS", - "sliceKb": 15232, - "bunKb": 32128, - "denoKb": 48640, - "nodeKb": 87308 + "sliceKb": 14336, + "bunKb": 31872, + "denoKb": 48288, + "nodeKb": 87436 }, { "id": "App 24: WASM + SSR", "label": "App 24: WASM + SSR", - "sliceKb": 14592, - "bunKb": 30592, - "denoKb": 49332, - "nodeKb": 81028 + "sliceKb": 13832, + "bunKb": 32512, + "denoKb": 48528, + "nodeKb": 81024 }, { "id": "FW 3: Express node:http", "label": "FW 3: Express node:http", - "sliceKb": 15616, + "sliceKb": 15488, "bunKb": 33152, - "denoKb": 47340, - "nodeKb": 80140 + "denoKb": 47088, + "nodeKb": 80144 }, { "id": "01-tot-autonomous-sre-agent", "label": "01-tot-autonomous-sre-agent", - "sliceKb": 20736, - "bunKb": 32128, - "denoKb": 53360, - "nodeKb": 83128 + "sliceKb": 20992, + "bunKb": 31104, + "denoKb": 53228, + "nodeKb": 83588 }, { "id": "02-mcp-code-mode-orchestrator", "label": "02-mcp-code-mode-orchestrator", - "sliceKb": 18668, + "sliceKb": 18552, "bunKb": 28288, - "denoKb": 46624, - "nodeKb": 82692 + "denoKb": 46784, + "nodeKb": 80776 }, { "id": "03-multi-tenant-saas-plugin-mesh", "label": "03-multi-tenant-saas-plugin-mesh", - "sliceKb": 16000, + "sliceKb": 15104, "bunKb": 26752, - "denoKb": 49776, - "nodeKb": 88100 + "denoKb": 49484, + "nodeKb": 88456 }, { "id": "04-wasm-zero-trust-cdr-pipeline", "label": "04-wasm-zero-trust-cdr-pipeline", "sliceKb": 20608, - "bunKb": 31232, - "denoKb": 49748, - "nodeKb": 80264 + "bunKb": 31360, + "denoKb": 49912, + "nodeKb": 80260 }, { "id": "05-time-travel-chaos-fuzzer-payments", "label": "05-time-travel-chaos-fuzzer-payments", - "sliceKb": 17024, - "bunKb": 29184, - "denoKb": 49524, - "nodeKb": 81696 + "sliceKb": 15232, + "bunKb": 29440, + "denoKb": 49488, + "nodeKb": 81444 }, { "id": "FW 4: SvelteKit 3 + Svelte 5", "label": "FW 4: SvelteKit 3 + Svelte 5", - "sliceKb": 22400, - "bunKb": 42112, - "denoKb": 56616, - "nodeKb": 85792 + "sliceKb": 21632, + "bunKb": 41216, + "denoKb": 56580, + "nodeKb": 85536 } ] } diff --git a/tests/reports/latest.md b/tests/reports/latest.md index 21530e6..cf164f2 100644 --- a/tests/reports/latest.md +++ b/tests/reports/latest.md @@ -1,12 +1,12 @@ # Slice (Nexus-JS) — Full 33-Workload & MicroVM Benchmark Report -* **Slice Version:** `v0.10.11` (Commit `898e90b`) -* **Generated Timestamp (UTC):** `2026-11-11T05:54:07Z` -* **Archive File:** [`tests/reports/bench_v0.10.11_20261111_055407Z_898e90b.md`](./bench_v0.10.11_20261111_055407Z_898e90b.md) +* **Slice Version:** `v0.10.12` (Commit `dc31f74`) +* **Generated Timestamp (UTC):** `2026-11-11T17:58:36Z` +* **Archive File:** [`tests/reports/bench_v0.10.12_20261111_175836Z_dc31f74.md`](./bench_v0.10.12_20261111_175836Z_dc31f74.md) * **Canonical Latest Report:** [`tests/reports/latest.md`](./latest.md) * **Environment:** `Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)` * **Compared Runtimes:** - * **Slice:** `v0.10.11` (Default `SLICEBC\x01` Precompiled Boa `CodeBlock` CAS + Monomorphic Inline Caching `get_fast` + Iterative ECMA-404 `JSON.parse`) + * **Slice:** `v0.10.12` (Default `SLICEBC\x01` Precompiled Boa `CodeBlock` CAS + Monomorphic Inline Caching `get_fast` + Iterative ECMA-404 `JSON.parse`) * **Bun:** `v1.4.4` (JavaScriptCore) * **Deno:** `v2.9.8` (V8) * **Node.js:** `v27.0.0-alpha.0.0.0` (V8 native TypeScript execution) @@ -15,13 +15,13 @@ ## 1. Executive Summary -Across all **33 real-world multi-file TypeScript applications, framework suites, and case studies**, Slice beats **Deno (`v2.9.8`)** on **33/33** workloads, beats **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33** workloads, beats **Bun (`v1.4.4`)** on **28/33** workloads in cold one-shot execution, and beats **all 3 runtimes on 33/33 workloads in `--warm` pooled isolate execution**. +Across all **33 real-world multi-file TypeScript applications, framework suites, and case studies**, Slice beats **Deno (`v2.9.8`)** on **33/33** workloads, beats **Node.js (`v27.0.0-alpha.0.0.0`)** on **33/33** workloads, beats **Bun (`v1.4.4`)** on **29/33** workloads in cold one-shot execution, and beats **all 3 runtimes on 33/33 workloads in `--warm` pooled isolate execution**. | Metric | Linux (`x86_64` Docker) | Windows (`x86_64` Host) | Comparison vs Runtimes & MicroVMs | | :--- | :---: | :---: | :--- | -| **Single Isolate Cold-Start (Min / P50 / P99)** | **`0.98 us` / `1.23 us` / `2.03 us`** | **`1.40 us` / `1.60 us` / `2.30 us`** | **~120,000x faster than 125ms Firecracker VM** | -| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.47 ms`** (`9.70 MB` RSS) | **`2.24 ms`** (`11.82 MB` RSS) | **> 10,000x faster than container/VM swarms** | -| **500-Module Monorepo Cold Boot (`0 stat()`)** | **`3.408 ms`** (`372.98 us` in-mem) | **`5.637 ms`** (`640.00 us` in-mem) | **20.6x faster than Node.js (`1,500+ stat()`)** | +| **Single Isolate Cold-Start (Min / P50 / P99)** | **`0.94 us` / `1.02 us` / `4.27 us`** | **`1.40 us` / `1.60 us` / `2.30 us`** | **~120,000x faster than 125ms Firecracker VM** | +| **1,000-Tenant MicroVM Swarm (Boot + Exec)** | **`1.74 ms`** (`9.82 MB` RSS) | **`2.24 ms`** (`11.82 MB` RSS) | **> 10,000x faster than container/VM swarms** | +| **500-Module Monorepo Cold Boot (`0 stat()`)** | **`3.408 ms`** (`467.08 us` in-mem) | **`5.637 ms`** (`640.00 us` in-mem) | **20.6x faster than Node.js (`1,500+ stat()`)** | | **10,000 Direct Kernel Ring I/O Completions** | **`0.02 ms`** | **`5.11 ms`** | **Zero worker-thread lock contention** | | **5-Ring Security Containment Verification** | **`5 / 5 PASS`** | **`5 / 5 PASS`** | **OCap + SES + Fuel + SSRF/DLP + MPK** | @@ -31,11 +31,11 @@ Across all **33 real-world multi-file TypeScript applications, framework suites, | Server / Runtime | Throughput (`req/s`) | Avg Latency / Req | Total Time (`16k` Reqs) | Relative Speedup vs Runtimes | | :--- | :---: | :---: | :---: | :--- | -| **`slice serve` (Tier-0 CAS, `--workers=8`)** | **`153,174 req/s`** | **`6.53 us/req`** | **`104.5 ms`** | **`1.52x` faster than `Bun.serve` / `2.80x` Node.js** | -| **`slice serve` (Tier-1 WinterTC, `--workers=8`)** | **`145,192 req/s`** | **`6.89 us/req`** | **`110.2 ms`** | **`1.44x` faster than `Bun.serve` / `2.66x` Node.js** | -| **`Deno.serve` (`v2.9.8`, V8, No Per-Req Sandbox)** | `99,307 req/s` | `10.07 us/req` | `161.1 ms` | `0.98x` vs Bun | -| **`Bun.serve` (`v1.4.4`, JSC, No Per-Req Sandbox)** | `101,093 req/s` | `9.89 us/req` | `158.3 ms` | `1.00x` (Baseline) | -| **`Node.js http.createServer` (`v27.0.0-alpha.0.0.0`, V8)** | `54,637 req/s` | `18.30 us/req` | `292.8 ms` | `0.54x` vs Bun | +| **`slice serve` (Tier-0 CAS, `--workers=8`)** | **`154,794 req/s`** | **`6.46 us/req`** | **`103.4 ms`** | **`1.54x` faster than `Bun.serve` / `2.74x` Node.js** | +| **`slice serve` (Tier-1 WinterTC, `--workers=8`)** | **`147,564 req/s`** | **`6.78 us/req`** | **`108.4 ms`** | **`1.47x` faster than `Bun.serve` / `2.61x` Node.js** | +| **`Deno.serve` (`v2.9.8`, V8, No Per-Req Sandbox)** | `99,082 req/s` | `10.09 us/req` | `161.5 ms` | `0.99x` vs Bun | +| **`Bun.serve` (`v1.4.4`, JSC, No Per-Req Sandbox)** | `100,562 req/s` | `9.94 us/req` | `159.1 ms` | `1.00x` (Baseline) | +| **`Node.js http.createServer` (`v27.0.0-alpha.0.0.0`, V8)** | `56,447 req/s` | `17.72 us/req` | `283.5 ms` | `0.56x` vs Bun | --- @@ -43,39 +43,39 @@ Across all **33 real-world multi-file TypeScript applications, framework suites, | # | Workload (`tests/apps/`, `tests/frameworks/`, `tests/case_studies/`) | Slice Cold `.cas` (`SLICEBC\x01`) | Slice Standalone Bin (`SLICEBC\x01`) | Slice Warm (`--warm`) | Previous `.cas` (`Delta`) | Bun `v1.4.4` | Deno `v2.9.8` | Node.js `v27.0.0-alpha.0.0.0` | Slice Speedup vs Bun / Node.js | | :- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- | -| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.698 ms`** (`5.89 ms` Min) | **`6.942 ms`** | **`1.679 ms`** | `5.659 ms` (`18.4%`) | `13.445 ms` | `35.698 ms` | `59.152 ms` | **`2.01x Bun` (`8.01x` Warm) / `8.83x Node`** | -| **02** | `02-npm-ecosystem-suite` (`semver` + `ms` + `ini`) | **`14.785 ms`** (`13.71 ms` Min) | **`14.951 ms`** | **`6.431 ms`** | `12.659 ms` (`16.8%`) | `21.505 ms` | `52.831 ms` | `69.235 ms` | **`1.45x Bun` (`3.34x` Warm) / `4.68x Node`** | -| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.617 ms`** (`7.24 ms` Min) | **`7.855 ms`** | **`1.723 ms`** | `6.727 ms` (`13.2%`) | `13.792 ms` | `45.409 ms` | `61.734 ms` | **`1.81x Bun` (`8.00x` Warm) / `8.10x Node`** | -| **04** | `04-edge-api-gateway` (`fast-querystring` + `ms`) | **`7.559 ms`** (`7.10 ms` Min) | **`8.159 ms`** | **`3.956 ms`** | `6.624 ms` (`14.1%`) | `14.699 ms` | `41.787 ms` | `62.835 ms` | **`1.94x Bun` (`3.72x` Warm) / `8.31x Node`** | -| **05** | `05-jwt-oauth-session-guard` (`cookie` + `ms` + HMAC) | **`10.511 ms`** (`10.00 ms` Min) | **`11.042 ms`** | **`7.876 ms`** | `9.604 ms` (`9.4%`) | `14.601 ms` | `44.318 ms` | `62.788 ms` | **`1.39x Bun` (`1.85x` Warm) / `5.97x Node`** | -| **06** | `06-telemetry-metrics-pipeline` (`bytes` + `flatted` + WAL) | **`14.045 ms`** (`13.21 ms` Min) | **`13.994 ms`** | **`6.433 ms`** | `13.023 ms` (`7.8%`) | `17.194 ms` | `48.119 ms` | `65.404 ms` | **`1.23x Bun` (`2.67x` Warm) / `4.67x Node`** | -| **07** | `07-graphql-ast-validator` (`dlv` + `dset` + AST Cost) | **`9.193 ms`** (`8.44 ms` Min) | **`9.804 ms`** | **`5.195 ms`** | `8.178 ms` (`12.4%`) | `13.052 ms` | `40.817 ms` | `61.714 ms` | **`1.42x Bun` (`2.51x` Warm) / `6.71x Node`** | -| **08** | `08-event-driven-state-journal` (`mitt` + `ms` + JSONL Replay) | **`11.667 ms`** (`11.04 ms` Min) | **`11.989 ms`** | **`5.807 ms`** | `10.036 ms` (`16.3%`) | `16.467 ms` | `46.579 ms` | `66.675 ms` | **`1.41x Bun` (`2.84x` Warm) / `5.71x Node`** | -| **09** | `09-wintertc-web-router` (`Request` + `Response` + `URL`, 80 reqs) | **`16.323 ms`** (`15.03 ms` Min) | **`16.184 ms`** | **`9.689 ms`** | `13.781 ms` (`18.4%`) | `13.954 ms` | `47.109 ms` | `86.236 ms` | **`1.44x Bun Warm` / `5.33x Node`** | -| **10** | `10-fullstack-bff-microservice` (`cookie` + `dlv` + `ms` + `ETag`, 60 reqs) | **`13.778 ms`** (`12.70 ms` Min) | **`13.793 ms`** | **`7.468 ms`** | `12.008 ms` (`14.7%`) | `14.611 ms` | `47.719 ms` | `85.928 ms` | **`1.06x Bun` (`1.96x` Warm) / `6.24x Node`** | -| **11** | `11-static-asset-cdn-edge` (`bytes` + `ms` + `ETag` `304`, 80 reqs) | **`10.366 ms`** (`9.73 ms` Min) | **`10.611 ms`** | **`4.123 ms`** | `9.199 ms` (`12.7%`) | `13.422 ms` | `49.132 ms` | `86.083 ms` | **`1.29x Bun` (`3.26x` Warm) / `8.30x Node`** | -| **12** | `12-ai-sse-token-streamer` (`mitt` + `ms` + SSE + DLP, 320 frames) | **`15.430 ms`** (`14.88 ms` Min) | **`15.783 ms`** | **`9.011 ms`** | `14.114 ms` (`9.3%`) | `15.047 ms` | `49.863 ms` | `89.926 ms` | **`1.67x Bun Warm` / `5.83x Node`** | -| **13** | `13-webhook-orchestrator-ssrf` (`fast-querystring` + `ms` + Live `fetch`) | **`17.563 ms`** (`15.40 ms` Min) | **`15.976 ms`** | **`6.678 ms`** | `12.492 ms` (`40.6%`) | `19.819 ms` | `51.823 ms` | `113.097 ms` | **`1.24x Bun` (`2.97x` Warm) / `7.08x Node`** | -| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`16.692 ms`** (`15.44 ms` Min) | **`16.840 ms`** | **`7.968 ms`** | `14.838 ms` (`12.5%`) | `21.633 ms` | `53.171 ms` | `112.883 ms` | **`1.30x Bun` (`2.71x` Warm) / `6.76x Node`** | -| **15** | `15-time-travel-test-suite` (`semver` + `ms` + `dlv` + `dset` + 24 Rollbacks) | **`16.035 ms`** (`15.36 ms` Min) | **`15.777 ms`** | **`4.855 ms`** | `14.887 ms` (`7.7%`) | `25.404 ms` | `67.449 ms` | `84.002 ms` | **`1.61x Bun` (`5.23x` Warm) / `5.32x Node`** | -| **16** | `16-dotenv-dlp-config-vault` (`ini` + `cookie` + `bytes` + `.env` Auto-DLP) | **`8.079 ms`** (`7.46 ms` Min) | **`8.455 ms`** | **`1.385 ms`** | `7.467 ms` (`8.2%`) | `14.281 ms` | `44.477 ms` | `63.767 ms` | **`1.77x Bun` (`10.31x` Warm) / `7.89x Node`** | -| **17** | `17-zero-trust-redirect-keepalive-mesh` (Keep-Alive/307/SSRF/DLP) | **`17.376 ms`** (`16.67 ms` Min) | **`19.974 ms`** | **`9.042 ms`** | `15.779 ms` (`10.1%`) | `22.206 ms` | `55.655 ms` | `112.300 ms` | **`1.28x Bun` (`2.46x` Warm) / `6.46x Node`** | -| **18** | `18-async-event-loop-fanout-scheduler` (Timer Wheel/`Promise.all`/`AbortSignal`) | **`30.841 ms`** (`28.84 ms` Min) | **`31.316 ms`** | **`17.473 ms`** | `29.409 ms` (`4.9%`) | `32.649 ms` | `73.881 ms` | `81.441 ms` | **`1.06x Bun` (`1.87x` Warm) / `2.64x Node`** | -| **19** | `19-wintertc-webcrypto-streams-edge` (WebCrypto/Streams/FormData/Clone) | **`8.515 ms`** (`8.12 ms` Min) | **`8.959 ms`** | **`1.493 ms`** | `8.407 ms` (`1.3%`) | `14.021 ms` | `45.631 ms` | `87.941 ms` | **`1.65x Bun` (`9.39x` Warm) / `10.33x Node`** | -| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.298 ms`** (`10.48 ms` Min) | **`11.547 ms`** | **`0.612 ms`** | `10.148 ms` (`11.3%`) | `22.400 ms` | `54.998 ms` | `76.295 ms` | **`1.98x Bun` (`36.60x` Warm) / `6.75x Node`** | -| **21** | `21-websocket-realtime-and-security-guard` (RFC 6455 `WebSocket` + 5-Ring Guard) | **`11.073 ms`** (`10.66 ms` Min) | **`11.583 ms`** | **`3.777 ms`** | `10.288 ms` (`7.6%`) | `20.349 ms` | `52.160 ms` | `117.179 ms` | **`1.84x Bun` (`5.39x` Warm) / `10.58x Node`** | -| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.159 ms`** (`19.42 ms` Min) | **`20.547 ms`** | **`2.228 ms`** | `19.101 ms` (`5.5%`) | `55.925 ms` | `112.632 ms` | `101.841 ms` | **`2.77x Bun` (`25.10x` Warm) / `5.05x Node`** | -| **23** | `23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec) | **`15.430 ms`** (`14.75 ms` Min) | **`16.036 ms`** | **`1.954 ms`** | `13.643 ms` (`13.1%`) | `21.292 ms` | `42.492 ms` | `61.274 ms` | **`1.38x Bun` (`10.90x` Warm) / `3.97x Node`** | -| **24** | `24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline) | **`8.744 ms`** (`8.23 ms` Min) | **`9.198 ms`** | **`1.838 ms`** | `8.336 ms` (`4.9%`) | `20.232 ms` | `43.778 ms` | `68.091 ms` | **`2.31x Bun` (`11.01x` Warm) / `7.79x Node`** | -| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`15.219 ms`** (`14.46 ms` Min) | **`15.812 ms`** | **`5.631 ms`** | `13.701 ms` (`11.1%`) | `19.633 ms` | `52.596 ms` | `94.610 ms` | **`1.29x Bun` (`3.49x` Warm) / `6.22x Node`** | -| **FW-02** | `FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS) | **`17.819 ms`** (`17.14 ms` Min) | **`18.045 ms`** | **`9.665 ms`** | `16.349 ms` (`9.0%`) | `20.945 ms` | `46.351 ms` | `87.095 ms` | **`1.18x Bun` (`2.17x` Warm) / `4.89x Node`** | -| **FW-03** | `FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka) | **`17.267 ms`** (`16.45 ms` Min) | **`17.638 ms`** | **`1.311 ms`** | `14.809 ms` (`16.6%`) | `34.805 ms` | `51.001 ms` | `82.310 ms` | **`2.02x Bun` (`26.55x` Warm) / `4.77x Node`** | -| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`32.075 ms`** (`31.12 ms` Min) | **`32.819 ms`** | **`16.953 ms`** | `33.452 ms` (`-4.1%`) | `43.525 ms` | `74.247 ms` | `112.271 ms` | **`1.36x Bun` (`2.57x` Warm) / `3.50x Node`** | -| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.706 ms`** (`30.76 ms` Min) | **`32.179 ms`** | **`13.019 ms`** | `29.806 ms` (`16.4%`) | `28.387 ms` | `72.119 ms` | `88.960 ms` | **`2.18x Bun Warm` / `2.76x Node`** | -| **CS-02** | `CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens) | **`18.871 ms`** (`18.21 ms` Min) | **`19.492 ms`** | **`5.409 ms`** | `16.342 ms` (`15.5%`) | `16.618 ms` | `43.050 ms` | `68.969 ms` | **`3.07x Bun Warm` / `3.65x Node`** | -| **CS-03** | `CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap) | **`13.687 ms`** (`13.07 ms` Min) | **`14.343 ms`** | **`5.404 ms`** | `12.120 ms` (`12.9%`) | `16.388 ms` | `48.628 ms` | `85.608 ms` | **`1.20x Bun` (`3.03x` Warm) / `6.25x Node`** | -| **CS-04** | `CS-04: case_studies/04-wasm-zero-trust-cdr-pipeline` (Wasm SimHash CDR) | **`19.960 ms`** (`19.14 ms` Min) | **`20.818 ms`** | **`2.104 ms`** | `15.992 ms` (`24.8%`) | `19.218 ms` | `44.875 ms` | `68.073 ms` | **`9.13x Bun Warm` / `3.41x Node`** | -| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.213 ms`** (`17.27 ms` Min) | **`19.284 ms`** | **`7.924 ms`** | `18.391 ms` (`-1.0%`) | `20.307 ms` | `62.714 ms` | `84.144 ms` | **`1.11x Bun` (`2.56x` Warm) / `4.62x Node`** | +| **01** | `01-fintech-checkout` (Multi-File TS + SHA-256) | **`6.278 ms`** (`5.88 ms` Min) | **`6.621 ms`** | **`1.050 ms`** | `6.698 ms` (`-6.3%`) | `13.377 ms` | `35.217 ms` | `58.453 ms` | **`2.13x Bun` (`12.74x` Warm) / `9.31x Node`** | +| **02** | `02-npm-ecosystem-suite` (`semver` + `ms` + `ini`) | **`14.228 ms`** (`13.36 ms` Min) | **`14.717 ms`** | **`3.817 ms`** | `14.785 ms` (`-3.8%`) | `21.069 ms` | `55.166 ms` | `69.341 ms` | **`1.48x Bun` (`5.52x` Warm) / `4.87x Node`** | +| **03** | `03-disk-io-log-pipeline` (10 JSONL Shards Disk I/O) | **`7.250 ms`** (`6.81 ms` Min) | **`7.800 ms`** | **`1.289 ms`** | `7.617 ms` (`-4.8%`) | `14.082 ms` | `43.228 ms` | `61.792 ms` | **`1.94x Bun` (`10.92x` Warm) / `8.52x Node`** | +| **04** | `04-edge-api-gateway` (`fast-querystring` + `ms`) | **`7.408 ms`** (`6.98 ms` Min) | **`8.033 ms`** | **`1.736 ms`** | `7.559 ms` (`-2.0%`) | `15.082 ms` | `41.232 ms` | `59.873 ms` | **`2.04x Bun` (`8.69x` Warm) / `8.08x Node`** | +| **05** | `05-jwt-oauth-session-guard` (`cookie` + `ms` + HMAC) | **`10.074 ms`** (`9.45 ms` Min) | **`10.543 ms`** | **`4.654 ms`** | `10.511 ms` (`-4.2%`) | `14.766 ms` | `45.411 ms` | `62.437 ms` | **`1.47x Bun` (`3.17x` Warm) / `6.20x Node`** | +| **06** | `06-telemetry-metrics-pipeline` (`bytes` + `flatted` + WAL) | **`12.738 ms`** (`12.19 ms` Min) | **`13.970 ms`** | **`4.330 ms`** | `14.045 ms` (`-9.3%`) | `16.697 ms` | `46.630 ms` | `65.983 ms` | **`1.31x Bun` (`3.86x` Warm) / `5.18x Node`** | +| **07** | `07-graphql-ast-validator` (`dlv` + `dset` + AST Cost) | **`8.937 ms`** (`8.40 ms` Min) | **`9.786 ms`** | **`3.758 ms`** | `9.193 ms` (`-2.8%`) | `13.020 ms` | `41.561 ms` | `61.914 ms` | **`1.46x Bun` (`3.46x` Warm) / `6.93x Node`** | +| **08** | `08-event-driven-state-journal` (`mitt` + `ms` + JSONL Replay) | **`11.229 ms`** (`10.45 ms` Min) | **`14.547 ms`** | **`5.258 ms`** | `11.667 ms` (`-3.8%`) | `15.902 ms` | `46.355 ms` | `62.965 ms` | **`1.42x Bun` (`3.02x` Warm) / `5.61x Node`** | +| **09** | `09-wintertc-web-router` (`Request` + `Response` + `URL`, 80 reqs) | **`14.771 ms`** (`14.22 ms` Min) | **`15.429 ms`** | **`9.085 ms`** | `16.323 ms` (`-9.5%`) | `13.919 ms` | `47.276 ms` | `85.354 ms` | **`1.53x Bun Warm` / `5.78x Node`** | +| **10** | `10-fullstack-bff-microservice` (`cookie` + `dlv` + `ms` + `ETag`, 60 reqs) | **`12.802 ms`** (`12.16 ms` Min) | **`13.616 ms`** | **`6.308 ms`** | `13.778 ms` (`-7.1%`) | `14.467 ms` | `50.395 ms` | `84.816 ms` | **`1.13x Bun` (`2.29x` Warm) / `6.63x Node`** | +| **11** | `11-static-asset-cdn-edge` (`bytes` + `ms` + `ETag` `304`, 80 reqs) | **`10.042 ms`** (`9.54 ms` Min) | **`10.698 ms`** | **`3.656 ms`** | `10.366 ms` (`-3.1%`) | `13.499 ms` | `47.729 ms` | `87.639 ms` | **`1.34x Bun` (`3.69x` Warm) / `8.73x Node`** | +| **12** | `12-ai-sse-token-streamer` (`mitt` + `ms` + SSE + DLP, 320 frames) | **`15.593 ms`** (`14.85 ms` Min) | **`15.893 ms`** | **`7.429 ms`** | `15.430 ms` (`1.1%`) | `15.213 ms` | `48.694 ms` | `90.253 ms` | **`2.05x Bun Warm` / `5.79x Node`** | +| **13** | `13-webhook-orchestrator-ssrf` (`fast-querystring` + `ms` + Live `fetch`) | **`15.199 ms`** (`14.71 ms` Min) | **`16.293 ms`** | **`6.388 ms`** | `17.563 ms` (`-13.5%`) | `18.942 ms` | `51.379 ms` | `111.110 ms` | **`1.25x Bun` (`2.97x` Warm) / `7.31x Node`** | +| **14** | `14-federated-api-mesh-dlp` (`bytes` + `dlv` + `dset` + Live `fetch`) | **`15.828 ms`** (`15.01 ms` Min) | **`16.384 ms`** | **`6.697 ms`** | `16.692 ms` (`-5.2%`) | `21.200 ms` | `56.402 ms` | `108.617 ms` | **`1.34x Bun` (`3.17x` Warm) / `6.86x Node`** | +| **15** | `15-time-travel-test-suite` (`semver` + `ms` + `dlv` + `dset` + 24 Rollbacks) | **`15.273 ms`** (`14.53 ms` Min) | **`15.908 ms`** | **`4.757 ms`** | `16.035 ms` (`-4.8%`) | `24.939 ms` | `66.357 ms` | `84.077 ms` | **`1.63x Bun` (`5.24x` Warm) / `5.50x Node`** | +| **16** | `16-dotenv-dlp-config-vault` (`ini` + `cookie` + `bytes` + `.env` Auto-DLP) | **`7.598 ms`** (`6.83 ms` Min) | **`8.351 ms`** | **`1.234 ms`** | `8.079 ms` (`-6.0%`) | `14.844 ms` | `48.547 ms` | `67.533 ms` | **`1.95x Bun` (`12.03x` Warm) / `8.89x Node`** | +| **17** | `17-zero-trust-redirect-keepalive-mesh` (Keep-Alive/307/SSRF/DLP) | **`17.333 ms`** (`16.70 ms` Min) | **`18.916 ms`** | **`7.896 ms`** | `17.376 ms` (`-0.2%`) | `22.634 ms` | `55.132 ms` | `109.514 ms` | **`1.31x Bun` (`2.87x` Warm) / `6.32x Node`** | +| **18** | `18-async-event-loop-fanout-scheduler` (Timer Wheel/`Promise.all`/`AbortSignal`) | **`29.326 ms`** (`27.79 ms` Min) | **`30.533 ms`** | **`16.971 ms`** | `30.841 ms` (`-4.9%`) | `32.616 ms` | `70.809 ms` | `81.452 ms` | **`1.11x Bun` (`1.92x` Warm) / `2.78x Node`** | +| **19** | `19-wintertc-webcrypto-streams-edge` (WebCrypto/Streams/FormData/Clone) | **`8.118 ms`** (`7.68 ms` Min) | **`9.079 ms`** | **`1.396 ms`** | `8.515 ms` (`-4.7%`) | `13.794 ms` | `44.403 ms` | `86.921 ms` | **`1.70x Bun` (`9.88x` Warm) / `10.71x Node`** | +| **20** | `20-node-compat-and-edge-router` (`Uint8Array` `Buffer`/Node Core/AST Bundler) | **`11.261 ms`** (`10.21 ms` Min) | **`11.623 ms`** | **`0.496 ms`** | `11.298 ms` (`-0.3%`) | `25.080 ms` | `55.776 ms` | `73.350 ms` | **`2.23x Bun` (`50.56x` Warm) / `6.51x Node`** | +| **21** | `21-websocket-realtime-and-security-guard` (RFC 6455 `WebSocket` + 5-Ring Guard) | **`10.714 ms`** (`10.08 ms` Min) | **`11.463 ms`** | **`2.166 ms`** | `11.073 ms` (`-3.2%`) | `20.494 ms` | `51.042 ms` | `116.007 ms` | **`1.91x Bun` (`9.46x` Warm) / `10.83x Node`** | +| **22** | `22-worker-threads-and-raw-sockets` (3 Worker Threads + TCP/UDP + 5-Ring Sec) | **`20.988 ms`** (`20.33 ms` Min) | **`21.637 ms`** | **`1.739 ms`** | `20.159 ms` (`4.1%`) | `57.152 ms` | `114.016 ms` | `101.723 ms` | **`2.72x Bun` (`32.86x` Warm) / `4.85x Node`** | +| **23** | `23-wasm-crypto-and-simd-kernel` (Pure-Rust `WebAssembly` + 5-Ring WASM Sec) | **`15.548 ms`** (`14.73 ms` Min) | **`16.009 ms`** | **`1.970 ms`** | `15.430 ms` (`0.8%`) | `21.684 ms` | `40.550 ms` | `63.213 ms` | **`1.39x Bun` (`11.01x` Warm) / `4.07x Node`** | +| **24** | `24-tsx-ssr-and-wasm-edge-pipeline` (`WebAssembly` SLA Scorer + SSR Pipeline) | **`8.719 ms`** (`7.84 ms` Min) | **`8.994 ms`** | **`1.758 ms`** | `8.744 ms` (`-0.3%`) | `19.118 ms` | `42.405 ms` | `67.199 ms` | **`2.19x Bun` (`10.87x` Warm) / `7.71x Node`** | +| **FW-01** | `FW-01: frameworks/01-hono-edge-microservice` (`hono@4.6.20` + `hono/cookie` + `ms`) | **`14.653 ms`** (`14.06 ms` Min) | **`15.350 ms`** | **`5.593 ms`** | `15.219 ms` (`-3.7%`) | `19.858 ms` | `51.149 ms` | `94.150 ms` | **`1.36x Bun` (`3.55x` Warm) / `6.43x Node`** | +| **FW-02** | `FW-02: frameworks/02-itty-router-unjs-nitro-stack` (`itty-router` + UnJS) | **`17.364 ms`** (`16.63 ms` Min) | **`17.789 ms`** | **`9.113 ms`** | `17.819 ms` (`-2.6%`) | `18.943 ms` | `46.132 ms` | `86.398 ms` | **`1.09x Bun` (`2.08x` Warm) / `4.98x Node`** | +| **FW-03** | `FW-03: frameworks/03-node-http-express-compat` (`node:http` + `node:stream` Express/Polka) | **`16.742 ms`** (`16.24 ms` Min) | **`18.053 ms`** | **`0.927 ms`** | `17.267 ms` (`-3.0%`) | `34.374 ms` | `51.235 ms` | `84.492 ms` | **`2.05x Bun` (`37.08x` Warm) / `5.05x Node`** | +| **FW-04** | `FW-04: frameworks/04-sveltekit-edge-ssr` (`@sveltejs/kit@3.1.1` + `svelte@5.57.3` + `devalue@6.0.3`) | **`34.372 ms`** (`32.03 ms` Min) | **`34.188 ms`** | **`14.260 ms`** | `32.075 ms` (`7.2%`) | `43.709 ms` | `68.042 ms` | `108.544 ms` | **`1.28x Bun` (`3.07x` Warm) / `3.17x Node`** | +| **CS-01** | `CS-01: case_studies/01-tot-autonomous-sre-agent` (20 ToT Sandboxes) | **`34.837 ms`** (`32.96 ms` Min) | **`36.000 ms`** | **`12.991 ms`** | `34.706 ms` (`0.4%`) | `28.855 ms` | `73.549 ms` | `91.045 ms` | **`2.22x Bun Warm` / `2.61x Node`** | +| **CS-02** | `CS-02: case_studies/02-mcp-code-mode-orchestrator` (`-98.4%` Tokens) | **`19.490 ms`** (`17.87 ms` Min) | **`19.711 ms`** | **`3.241 ms`** | `18.871 ms` (`3.3%`) | `16.986 ms` | `44.877 ms` | `68.991 ms` | **`5.24x Bun Warm` / `3.54x Node`** | +| **CS-03** | `CS-03: case_studies/03-multi-tenant-saas-plugin-mesh` (12 Tenants + Hot-Swap) | **`13.171 ms`** (`12.59 ms` Min) | **`14.508 ms`** | **`5.274 ms`** | `13.687 ms` (`-3.8%`) | `16.965 ms` | `49.996 ms` | `87.777 ms` | **`1.29x Bun` (`3.22x` Warm) / `6.66x Node`** | +| **CS-04** | `CS-04: case_studies/04-wasm-zero-trust-cdr-pipeline` (Wasm SimHash CDR) | **`20.235 ms`** (`18.73 ms` Min) | **`21.128 ms`** | **`1.501 ms`** | `19.960 ms` (`1.4%`) | `20.878 ms` | `48.725 ms` | `70.429 ms` | **`1.03x Bun` (`13.91x` Warm) / `3.48x Node`** | +| **CS-05** | `CS-05: case_studies/05-time-travel-chaos-fuzzer-payments` (48 Payment Sagas) | **`18.139 ms`** (`16.44 ms` Min) | **`19.258 ms`** | **`8.323 ms`** | `18.213 ms` (`-0.4%`) | `21.102 ms` | `65.542 ms` | `86.649 ms` | **`1.16x Bun` (`2.54x` Warm) / `4.78x Node`** | --- @@ -83,21 +83,21 @@ Across all **33 real-world multi-file TypeScript applications, framework suites, | Workload | Slice (`SLICEBC\x01` Default) | Bun (`v1.4.4`) | Deno (`v2.9.8`) | Node.js (`v27.0.0-alpha.0.0.0`) | Slice Memory Advantage | | :--- | :---: | :---: | :---: | :---: | :--- | -| **App 2: NPM semver+ms+ini** | **14,592 KB (14.25 MB)** | 29,952 KB (29.25 MB) | 47,344 KB (46.23 MB) | 71,584 KB (69.91 MB) | **4.91x less than Node / 2.05x less than Bun** | -| **App 6: Telemetry + Flatted** | **15,104 KB (14.75 MB)** | 30,464 KB (29.75 MB) | 50,928 KB (49.73 MB) | 72,860 KB (71.15 MB) | **4.82x less than Node / 2.02x less than Bun** | -| **App 21: RFC 6455 WS + Sec** | **15,104 KB (14.75 MB)** | 31,732 KB (30.99 MB) | 50,756 KB (49.57 MB) | 95,356 KB (93.12 MB) | **6.31x less than Node / 2.10x less than Bun** | -| **App 22: Workers + Sockets** | **22,272 KB (21.75 MB)** | 41,688 KB (40.71 MB) | 63,236 KB (61.75 MB) | 94,180 KB (91.97 MB) | **4.23x less than Node / 1.87x less than Bun** | -| **App 23: Pure-Rust WASM** | **19,200 KB (18.75 MB)** | 30,720 KB (30.00 MB) | 48,784 KB (47.64 MB) | 80,660 KB (78.77 MB) | **4.20x less than Node / 1.60x less than Bun** | -| **FW 1: Hono v4 Microservice** | **15,872 KB (15.50 MB)** | 30,976 KB (30.25 MB) | 49,144 KB (47.99 MB) | 88,816 KB (86.73 MB) | **5.60x less than Node / 1.95x less than Bun** | -| **FW 2: itty-router + UnJS** | **15,232 KB (14.88 MB)** | 32,128 KB (31.38 MB) | 48,640 KB (47.50 MB) | 87,308 KB (85.26 MB) | **5.73x less than Node / 2.11x less than Bun** | -| **App 24: WASM + SSR** | **14,592 KB (14.25 MB)** | 30,592 KB (29.88 MB) | 49,332 KB (48.18 MB) | 81,028 KB (79.13 MB) | **5.55x less than Node / 2.10x less than Bun** | -| **FW 3: Express node:http** | **15,616 KB (15.25 MB)** | 33,152 KB (32.38 MB) | 47,340 KB (46.23 MB) | 80,140 KB (78.26 MB) | **5.13x less than Node / 2.12x less than Bun** | -| **01-tot-autonomous-sre-agent** | **20,736 KB (20.25 MB)** | 32,128 KB (31.38 MB) | 53,360 KB (52.11 MB) | 83,128 KB (81.18 MB) | **4.01x less than Node / 1.55x less than Bun** | -| **02-mcp-code-mode-orchestrator** | **18,668 KB (18.23 MB)** | 28,288 KB (27.63 MB) | 46,624 KB (45.53 MB) | 82,692 KB (80.75 MB) | **4.43x less than Node / 1.52x less than Bun** | -| **03-multi-tenant-saas-plugin-mesh** | **16,000 KB (15.63 MB)** | 26,752 KB (26.13 MB) | 49,776 KB (48.61 MB) | 88,100 KB (86.04 MB) | **5.51x less than Node / 1.67x less than Bun** | -| **04-wasm-zero-trust-cdr-pipeline** | **20,608 KB (20.13 MB)** | 31,232 KB (30.50 MB) | 49,748 KB (48.58 MB) | 80,264 KB (78.38 MB) | **3.89x less than Node / 1.52x less than Bun** | -| **05-time-travel-chaos-fuzzer-payments** | **17,024 KB (16.63 MB)** | 29,184 KB (28.50 MB) | 49,524 KB (48.36 MB) | 81,696 KB (79.78 MB) | **4.80x less than Node / 1.71x less than Bun** | -| **FW 4: SvelteKit 3 + Svelte 5** | **22,400 KB (21.88 MB)** | 42,112 KB (41.13 MB) | 56,616 KB (55.29 MB) | 85,792 KB (83.78 MB) | **3.83x less than Node / 1.88x less than Bun** | +| **App 2: NPM semver+ms+ini** | **14,464 KB (14.13 MB)** | 30,336 KB (29.63 MB) | 47,068 KB (45.96 MB) | 71,836 KB (70.15 MB) | **4.97x less than Node / 2.10x less than Bun** | +| **App 6: Telemetry + Flatted** | **13,776 KB (13.45 MB)** | 29,952 KB (29.25 MB) | 50,800 KB (49.61 MB) | 72,724 KB (71.02 MB) | **5.28x less than Node / 2.17x less than Bun** | +| **App 21: RFC 6455 WS + Sec** | **14,080 KB (13.75 MB)** | 31,860 KB (31.11 MB) | 50,564 KB (49.38 MB) | 95,236 KB (93.00 MB) | **6.76x less than Node / 2.26x less than Bun** | +| **App 22: Workers + Sockets** | **22,144 KB (21.63 MB)** | 40,480 KB (39.53 MB) | 63,880 KB (62.38 MB) | 92,416 KB (90.25 MB) | **4.17x less than Node / 1.83x less than Bun** | +| **App 23: Pure-Rust WASM** | **19,072 KB (18.63 MB)** | 30,848 KB (30.13 MB) | 48,792 KB (47.65 MB) | 80,528 KB (78.64 MB) | **4.22x less than Node / 1.62x less than Bun** | +| **FW 1: Hono v4 Microservice** | **15,360 KB (15.00 MB)** | 31,084 KB (30.36 MB) | 49,664 KB (48.50 MB) | 89,376 KB (87.28 MB) | **5.82x less than Node / 2.02x less than Bun** | +| **FW 2: itty-router + UnJS** | **14,336 KB (14.00 MB)** | 31,872 KB (31.13 MB) | 48,288 KB (47.16 MB) | 87,436 KB (85.39 MB) | **6.10x less than Node / 2.22x less than Bun** | +| **App 24: WASM + SSR** | **13,832 KB (13.51 MB)** | 32,512 KB (31.75 MB) | 48,528 KB (47.39 MB) | 81,024 KB (79.13 MB) | **5.86x less than Node / 2.35x less than Bun** | +| **FW 3: Express node:http** | **15,488 KB (15.13 MB)** | 33,152 KB (32.38 MB) | 47,088 KB (45.98 MB) | 80,144 KB (78.27 MB) | **5.17x less than Node / 2.14x less than Bun** | +| **01-tot-autonomous-sre-agent** | **20,992 KB (20.50 MB)** | 31,104 KB (30.38 MB) | 53,228 KB (51.98 MB) | 83,588 KB (81.63 MB) | **3.98x less than Node / 1.48x less than Bun** | +| **02-mcp-code-mode-orchestrator** | **18,552 KB (18.12 MB)** | 28,288 KB (27.63 MB) | 46,784 KB (45.69 MB) | 80,776 KB (78.88 MB) | **4.35x less than Node / 1.52x less than Bun** | +| **03-multi-tenant-saas-plugin-mesh** | **15,104 KB (14.75 MB)** | 26,752 KB (26.13 MB) | 49,484 KB (48.32 MB) | 88,456 KB (86.38 MB) | **5.86x less than Node / 1.77x less than Bun** | +| **04-wasm-zero-trust-cdr-pipeline** | **20,608 KB (20.13 MB)** | 31,360 KB (30.63 MB) | 49,912 KB (48.74 MB) | 80,260 KB (78.38 MB) | **3.89x less than Node / 1.52x less than Bun** | +| **05-time-travel-chaos-fuzzer-payments** | **15,232 KB (14.88 MB)** | 29,440 KB (28.75 MB) | 49,488 KB (48.33 MB) | 81,444 KB (79.54 MB) | **5.35x less than Node / 1.93x less than Bun** | +| **FW 4: SvelteKit 3 + Svelte 5** | **21,632 KB (21.13 MB)** | 41,216 KB (40.25 MB) | 56,580 KB (55.25 MB) | 85,536 KB (83.53 MB) | **3.95x less than Node / 1.91x less than Bun** | --- @@ -105,9 +105,9 @@ Across all **33 real-world multi-file TypeScript applications, framework suites, | Subsystem / Benchmark | Measured Telemetry | Status | | :--- | :--- | :---: | -| **Sharded `Slice.kv` (`1,001` Get/Set/Incr Ops in Isolate)** | **`706.00 us`** total (`--warm`, `8,431 B` memory cage) | `PASS` | +| **Sharded `Slice.kv` (`1,001` Get/Set/Incr Ops in Isolate)** | **`564.84 us`** total (`--warm`, `8,431 B` memory cage) | `PASS` | | **Multi-Tenant `--tenant-dir` Zero-Downtime Hot-Swap** | Live atomic replacement of `tenant-alpha.cas` (`v1 -> v2-hot-swapped`) with isolated `Slice.kv` state | `PASS` | | **Deterministic Time-Travel Replay (`--deterministic=20261019`)** | 100% bit-for-bit identical PRNG (`Math.random`) & virtual clock (`Date.now`, `performance.now`) | `PASS` | -| **Tree-of-Thought AI Agent (`Slice.checkpoint` + 3 `evalSandbox` + `restore`)** | **`129.86 us`** total (`2.80 us` child sandbox) | `PASS` | +| **Tree-of-Thought AI Agent (`Slice.checkpoint` + 3 `evalSandbox` + `restore`)** | **`74.64 us`** total (`3.50 us` child sandbox) | `PASS` | | **Cloud Metadata SSRF (`169.254.169.254`) & Base64 Egress DLP Guard** | `SSRF_METADATA_BLOCKED` & `EGRESS_SECRET_LEAK_BLOCKED` deterministically trapped | `PASS` | | **Built-In Model Context Protocol Server (`slice mcp --smoke-test`)** | JSON-RPC 2.0 `initialize`, `tools/list`, `tools/call` verified over `stdio` | `PASS` | diff --git a/tests/run_real_stack_benchmarks.sh b/tests/run_real_stack_benchmarks.sh index f6d3eab..7ec873c 100644 --- a/tests/run_real_stack_benchmarks.sh +++ b/tests/run_real_stack_benchmarks.sh @@ -44,7 +44,7 @@ BENCH_TAGS="${1:-${SLICE_BENCH_TAGS:-all}}" METRICS_JSONL="${SLICE_BENCH_JSONL:-/tmp/slice_bench_metrics.jsonl}" rm -f "$METRICS_JSONL" -SLICE_VERSION="${SLICE_VERSION:-0.10.11}" +SLICE_VERSION="${SLICE_VERSION:-0.10.12}" SLICE_GIT_COMMIT="${SLICE_GIT_COMMIT:-$(git -C "$ROOT_DIR" rev-parse --short HEAD 2>/dev/null || echo "abdbf89")}" SLICE_BENCH_TS_UTC="${SLICE_BENCH_TS_UTC:-$(date -u +"%Y-%m-%dT%H:%M:%SZ")}" CURRENT_APP_IDX="" @@ -358,14 +358,26 @@ measure_rss_kb() { record_warm_metrics() { local app_idx="$1" local cas_path="$2" - local out - out=$("$SLICE_BIN" run "$cas_path" --warm --quiet --metrics) - echo "$out" - local total_us - total_us=$(echo "$out" | awk -F'Total: ' '{print $2}' | awk '{print $1}') - if [ -n "$total_us" ]; then + local samples="" + local last_out="" + local r out us + for r in 1 2 3 4 5; do + out=$("$SLICE_BIN" run "$cas_path" --warm --quiet --metrics) + last_out="$out" + us=$(echo "$out" | awk -F'Total: ' '{print $2}' | awk '{print $1}') + if [ -n "$us" ]; then + samples="$samples $us" + fi + done + echo "$last_out" + local median_us + median_us=$(echo "$samples" | tr ' ' '\n' | grep -E '^[0-9.]+' | sort -n | sed -n '3p') + if [ -z "$median_us" ]; then + median_us=$(echo "$samples" | tr ' ' '\n' | grep -E '^[0-9.]+' | sort -n | head -n 1) + fi + if [ -n "$median_us" ]; then local total_ms - total_ms=$(awk -v us="$total_us" 'BEGIN { printf "%.3f", us / 1000.0 }') + total_ms=$(awk -v us="$median_us" 'BEGIN { printf "%.3f", us / 1000.0 }') record_jsonl "{\"type\":\"warm_metrics\",\"appIdx\":$app_idx,\"totalMs\":$total_ms}" fi } diff --git a/tests/scripts/generate_bench_report.mjs b/tests/scripts/generate_bench_report.mjs index 2d94088..0ada3a5 100644 --- a/tests/scripts/generate_bench_report.mjs +++ b/tests/scripts/generate_bench_report.mjs @@ -330,12 +330,12 @@ function parseJsonlMetrics(jsonlPath, previousReport) { return { metadata: { - version: metaRec.version || previousReport?.metadata?.version || "0.10.11", + version: metaRec.version || previousReport?.metadata?.version || "0.10.12", commit: metaRec.commit || previousReport?.metadata?.commit || "abdbf89", timestampUtc: metaRec.timestampUtc || new Date().toISOString(), environment: metaRec.environment || previousReport?.metadata?.environment || "Linux x86_64 Docker (io_uring SQPOLL + WRPKRU)", runtimes: { - slice: `v${metaRec.version || "0.10.11"}`, + slice: `v${metaRec.version || "0.10.12"}`, bun: metaRec.bunVersion || previousReport?.metadata?.runtimes?.bun || "v1.4.4", deno: metaRec.denoVersion || previousReport?.metadata?.runtimes?.deno || "v2.9.8", node: metaRec.nodeVersion || previousReport?.metadata?.runtimes?.node || "v27.0.0-alpha" diff --git a/vendor/boa_engine/SLICE_PATCH.md b/vendor/boa_engine/SLICE_PATCH.md index 1daecf3..1a84671 100644 --- a/vendor/boa_engine/SLICE_PATCH.md +++ b/vendor/boa_engine/SLICE_PATCH.md @@ -15,22 +15,26 @@ This minimal `[patch.crates-io]` overlay exposes two public methods on `boa_engi - `pub fn compile_to_slicebc(&self, context: &mut Context) -> JsResult>` - `pub fn from_slicebc_bytes(bytes: &[u8], context: &mut Context) -> Option` -By serializing the compiled `Gc` tree and global `Scope` bindings into `.cas` archives (`SLICEBC\x01`) at `slice pack` time and reconstructing `Gc` directly at `slice run` time, Slice bypasses `boa_lexer`, `boa_parser`, `Scope::analyze_scope`, and `ByteCompiler` on cold start — reducing cold VM execution from **`5.6–7.0 ms` down to `0.60–0.77 ms` (`9.0x–9.5x` faster in `--release`)**. +By serializing the compiled `Gc` tree and global `Scope` bindings into `.cas` archives (`SLICEBC\x01`) at `slice pack` time and reconstructing `Gc` directly at `slice run` time, Slice bypasses `boa_lexer`, `boa_parser`, `Scope::analyze_scope`, and `ByteCompiler` on cold start, reducing cold VM execution from **`5.6-7.0 ms` down to `0.60-0.77 ms` (`9.0x-9.5x` faster in `--release`)**. --- ## 2. Modified Files -Thirteen files in `vendor/boa_engine` differ from upstream `boa_engine v0.22.0`: +Fifteen files in `vendor/boa_engine` differ from upstream `boa_engine v0.22.0`: - [`vendor/boa_engine/src/script.rs`](./src/script.rs) & [`vendor/boa_engine/src/slice_precompile.rs`](./src/slice_precompile.rs): - `Script::compile_to_slicebc(&self, context: &mut Context) -> JsResult>` - `Script::from_slicebc_bytes(bytes: &[u8], context: &mut Context) -> Option` + - `Script::can_reuse_across_runs(&self) -> bool`: verifies that a compiled `Script` introduces no global `let`/`const`/`class` lexical declarations so warm pooled isolates can retain and re-run compiled `Script` instances (keeping populated `InlineCache` slots warm across executions). - Internal recursive helpers `encode_codeblock` / `decode_codeblock` (including bytecode-to-line `SourceMap` entries and deferred `0x11` function source spans) and `write_js_string` / `read_js_string`. -- [`vendor/boa_engine/src/builtins/json/mod.rs`](./src/builtins/json/mod.rs) & [`vendor/boa_engine/src/object/property_map.rs`](./src/object/property_map.rs): - - `Json::parse_ecma404` & `PropertyMap::insert_data_property`: Direct iterative ECMA-404 state-machine parser (`MAX_DEPTH = 2048` on heap-allocated `Vec`, `O(1)` C/Rust call stack) over `JsStrVariant::Latin1` and `JsStrVariant::Utf16` with `fast-float2` exact IEEE-754 float parsing (`±Infinity` on overflow), lone UTF-16 surrogate preservation, zero-copy Latin1/UTF-16 string slicing, Latin1 escaped-string fast path, direct `PropertyMap::insert_data_property` slot insertion, and optional `WITH_SOURCE` source-span tracking for `reviver` (`context.source`). - - `Json::try_fast_stringify`: Direct single-buffer `Vec` serializer fast-path in `JSON.stringify` when no `replacer` or `space` argument is supplied, traversing ordinary `JsObject`s (via `Shape::with_property_keys` + direct storage slots) and dense `Array`s (`DenseI32`, `DenseF64`, `DenseElement`) with `ryu_js` number formatting, inline `\uXXXX` escaping for lone UTF-16 surrogates, and automatic fallback for `toJSON`, getters, or exotic objects. +- [`vendor/boa_engine/src/property/mod.rs`](./src/property/mod.rs): + - Fast-path `PropertyKey::from(JsStr)` and `PropertyKey::from(JsString)` via `parse_u32_index_bytes` / `parse_u32_index_js_str`, avoiding `JsStrIter` construction and returning immediately when the leading byte is outside `'0'..='9'`. +- [`vendor/boa_engine/src/builtins/json/mod.rs`](./src/builtins/json/mod.rs), [`vendor/boa_engine/src/object/property_map.rs`](./src/object/property_map.rs), & [`vendor/boa_engine/src/object/jsobject.rs`](./src/object/jsobject.rs): + - `Json::parse_ecma404`, `PropertyMap::insert_data_property`, `PropertyMap::from_parts`, and `JsObject::from_property_map`: Direct iterative ECMA-404 state-machine parser (`MAX_DEPTH = 2048` on heap-allocated `Vec`, `O(1)` C/Rust call stack) over `JsStrVariant::Latin1` and `JsStrVariant::Utf16` with 8-byte SWAR unescaped string scanning, single-branch whitespace skipping, single-pass exact integer accumulation (`<= 16` digits) plus `fast-float2` float parsing (`+-Infinity` on overflow) over stack buffers, lone UTF-16 surrogate preservation, zero-drop `SourceTracker` (`NoSource` ZST when `reviver` is absent vs `WithSource` for `context.source`), `SharedShape` object construction (`ordinary_object` root shape), and per-depth `ShapeChain` prediction so homogeneous arrays/trees of JSON objects skip `JsString` key allocation, hashing, transition lookups, and `GcRefCell` borrows while enabling downstream monomorphic `InlineCache` hits. + - `Json::try_fast_stringify`: Direct single-buffer `Vec` serializer fast-path in `JSON.stringify` when no `replacer` or `space` argument is supplied, traversing ordinary `JsObject`s (via `Shape::with_property_keys`, `verified_obj_shape_addr` `toJSON` shape caching, + direct storage slots) and dense `Array`s (`DenseI32`, `DenseF64`, `DenseElement`) with 8-byte SWAR ASCII string scanning, `ryu_js` number formatting, inline `\uXXXX` escaping for lone UTF-16 surrogates, and automatic fallback for `toJSON`, getters, or exotic objects. - [`vendor/boa_engine/src/object/shape/mod.rs`](./src/object/shape/mod.rs), [`vendor/boa_engine/src/object/shape/shared_shape/mod.rs`](./src/object/shape/shared_shape/mod.rs), & [`vendor/boa_engine/src/object/shape/unique_shape.rs`](./src/object/shape/unique_shape.rs): - `Shape::with_property_keys`: Zero-allocation slice/iterator callback over ordinary object property keys for `Json::try_fast_stringify`. + - `Shape::as_shared`, `Shape::from_shared_checked`, `SharedShape::try_fast_insert_property_transition`, and `SharedShape::insert_property_transition_missed`: Single-lookup `SharedShape` property transition fast path for `PropertyMap::insert_data_property` and `Json::parse_ecma404`. - [`vendor/boa_engine/src/vm/inline_cache/mod.rs`](./src/vm/inline_cache/mod.rs): - `InlineCache::mono_shape_addr`, `InlineCache::mono_slot`, and `InlineCache::get_fast(&self, shape: &Shape) -> Option<(Option, Slot)>`: Zero-borrow monomorphic fast-path for own-property `Shape -> Slot` hits without locking `GcRefCell` or upgrading `WeakGc` pointers, with automatic polymorphic (`PIC_CAPACITY = 4`) and megamorphic fallback. - [`vendor/boa_engine/src/vm/opcode/get/property.rs`](./src/vm/opcode/get/property.rs) & [`vendor/boa_engine/src/vm/opcode/set/property.rs`](./src/vm/opcode/set/property.rs): diff --git a/vendor/boa_engine/src/builtins/json/mod.rs b/vendor/boa_engine/src/builtins/json/mod.rs index 0e7ae9d..1713492 100644 --- a/vendor/boa_engine/src/builtins/json/mod.rs +++ b/vendor/boa_engine/src/builtins/json/mod.rs @@ -13,7 +13,7 @@ //! [json]: https://www.json.org/json-en.html //! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON -use std::{borrow::Cow, iter::once}; +use std::{borrow::Cow, iter::once, rc::Rc}; use rustc_hash::FxHashSet; @@ -53,12 +53,84 @@ mod tests; #[derive(Debug, Trace, Finalize, JsData)] pub(crate) struct RawJson; +/// Scans `bytes[pos..]` 8 bytes at a time for the first byte that is `< 0x20`, `b'"'`, or `b'\\'`. +#[inline] +fn scan_latin1_unescaped_json_bytes(bytes: &[u8], mut pos: usize) -> usize { + const QUOTE_MASK: u64 = 0x2222_2222_2222_2222; + const BS_MASK: u64 = 0x5C5C_5C5C_5C5C_5C5C; + const LO_ONES: u64 = 0x0101_0101_0101_0101; + const HI_BITS: u64 = 0x8080_8080_8080_8080; + + let len = bytes.len(); + while pos + 8 <= len { + let chunk = u64::from_le_bytes(bytes[pos..pos + 8].try_into().unwrap()); + // Byte `b` is `>= 0x20` iff `(b & 0xE0) != 0` (at least one of bits 7, 6, 5 is set). + let ge_20 = (chunk | (chunk << 1) | (chunk << 2)) & HI_BITS; + let lt_20 = !ge_20 & HI_BITS; + let xq = chunk ^ QUOTE_MASK; + let eq_quote = xq.wrapping_sub(LO_ONES) & !xq & HI_BITS; + let xb = chunk ^ BS_MASK; + let eq_bs = xb.wrapping_sub(LO_ONES) & !xb & HI_BITS; + let stop_mask = lt_20 | eq_quote | eq_bs; + if stop_mask != 0 { + return pos + ((stop_mask.trailing_zeros() >> 3) as usize); + } + pos += 8; + } + while pos < len { + let b = bytes[pos]; + if b == b'"' || b == b'\\' || b < 0x20 { + return pos; + } + pos += 1; + } + pos +} + +/// Scans `bytes[pos..]` 8 bytes at a time for the first byte that requires JSON escaping or UTF-8 +/// expansion (`< 0x20`, `b'"'`, `b'\\'`, or `>= 0x80`). +#[inline] +fn scan_ascii_unescaped_json_bytes(bytes: &[u8], mut pos: usize) -> usize { + const QUOTE_MASK: u64 = 0x2222_2222_2222_2222; + const BS_MASK: u64 = 0x5C5C_5C5C_5C5C_5C5C; + const SPACE_MASK: u64 = 0x2020_2020_2020_2020; + const LO_ONES: u64 = 0x0101_0101_0101_0101; + const HI_BITS: u64 = 0x8080_8080_8080_8080; + + let len = bytes.len(); + while pos + 8 <= len { + let chunk = u64::from_le_bytes(bytes[pos..pos + 8].try_into().unwrap()); + let non_ascii = chunk & HI_BITS; + let lt_20 = chunk.wrapping_sub(SPACE_MASK) & !chunk & HI_BITS; + let xq = chunk ^ QUOTE_MASK; + let eq_quote = xq.wrapping_sub(LO_ONES) & !xq & HI_BITS; + let xb = chunk ^ BS_MASK; + let eq_bs = xb.wrapping_sub(LO_ONES) & !xb & HI_BITS; + let stop_mask = non_ascii | lt_20 | eq_quote | eq_bs; + if stop_mask != 0 { + return pos + ((stop_mask.trailing_zeros() >> 3) as usize); + } + pos += 8; + } + while pos < len { + let b = bytes[pos]; + if b < 0x20 || b == b'"' || b == b'\\' || b >= 0x80 { + return pos; + } + pos += 1; + } + pos +} + trait JsonInput<'a>: Copy { fn len(self) -> usize; fn code_unit(self, idx: usize) -> u16; fn slice_to_js_string(self, start: usize, end: usize) -> JsString; - fn ascii_bytes(self, start: usize, end: usize) -> Cow<'a, [u8]>; fn latin1_slice(self, start: usize, end: usize) -> Option<&'a [u8]>; + fn skip_ws(self, pos: usize) -> usize; + fn scan_unescaped_string(self, pos: usize) -> usize; + fn try_match_unescaped_key(self, pos: usize, expected: &JsString) -> Option; + fn parse_f64(self, start: usize, end: usize) -> Option; } impl<'a> JsonInput<'a> for &'a [u8] { @@ -78,13 +150,50 @@ impl<'a> JsonInput<'a> for &'a [u8] { } #[inline] - fn ascii_bytes(self, start: usize, end: usize) -> Cow<'a, [u8]> { - Cow::Borrowed(&self[start..end]) + fn latin1_slice(self, start: usize, end: usize) -> Option<&'a [u8]> { + Some(&self[start..end]) } #[inline] - fn latin1_slice(self, start: usize, end: usize) -> Option<&'a [u8]> { - Some(&self[start..end]) + fn skip_ws(self, mut pos: usize) -> usize { + let len = self.len(); + if pos < len && self[pos] > 0x20 { + return pos; + } + while pos < len { + match self[pos] { + 0x20 | 0x09 | 0x0A | 0x0D => pos += 1, + _ => break, + } + } + pos + } + + #[inline] + fn scan_unescaped_string(self, pos: usize) -> usize { + scan_latin1_unescaped_json_bytes(self, pos) + } + + #[inline] + fn try_match_unescaped_key(self, pos: usize, expected: &JsString) -> Option { + let boa_string::JsStrVariant::Latin1(exp_bytes) = expected.as_str().variant() else { + return None; + }; + let content_start = pos + 1; + let content_end = content_start.checked_add(exp_bytes.len())?; + if content_end < self.len() + && self[content_end] == b'"' + && &self[content_start..content_end] == exp_bytes + { + Some(content_end + 1) + } else { + None + } + } + + #[inline] + fn parse_f64(self, start: usize, end: usize) -> Option { + fast_float2::parse(&self[start..end]).ok() } } @@ -105,13 +214,105 @@ impl<'a> JsonInput<'a> for &'a [u16] { } #[inline] - fn ascii_bytes(self, start: usize, end: usize) -> Cow<'a, [u8]> { - Cow::Owned(self[start..end].iter().map(|&u| u as u8).collect()) + fn latin1_slice(self, _start: usize, _end: usize) -> Option<&'a [u8]> { + None } #[inline] - fn latin1_slice(self, _start: usize, _end: usize) -> Option<&'a [u8]> { - None + fn skip_ws(self, mut pos: usize) -> usize { + let len = self.len(); + if pos < len && self[pos] > 0x20 { + return pos; + } + while pos < len { + match self[pos] { + 0x20 | 0x09 | 0x0A | 0x0D => pos += 1, + _ => break, + } + } + pos + } + + #[inline] + fn scan_unescaped_string(self, mut pos: usize) -> usize { + let len = self.len(); + while pos + 4 <= len { + let u0 = self[pos]; + let u1 = self[pos + 1]; + let u2 = self[pos + 2]; + let u3 = self[pos + 3]; + if u0 < 0x20 + || u0 == 0x22 + || u0 == 0x5C + || u1 < 0x20 + || u1 == 0x22 + || u1 == 0x5C + || u2 < 0x20 + || u2 == 0x22 + || u2 == 0x5C + || u3 < 0x20 + || u3 == 0x22 + || u3 == 0x5C + { + break; + } + pos += 4; + } + while pos < len { + let u = self[pos]; + if u == 0x22 || u == 0x5C || u < 0x20 { + return pos; + } + pos += 1; + } + pos + } + + #[inline] + fn try_match_unescaped_key(self, pos: usize, expected: &JsString) -> Option { + let content_start = pos + 1; + match expected.as_str().variant() { + boa_string::JsStrVariant::Latin1(exp_bytes) => { + let content_end = content_start.checked_add(exp_bytes.len())?; + if content_end < self.len() + && self[content_end] == 0x22 + && self[content_start..content_end] + .iter() + .copied() + .eq(exp_bytes.iter().copied().map(u16::from)) + { + Some(content_end + 1) + } else { + None + } + } + boa_string::JsStrVariant::Utf16(exp_units) => { + let content_end = content_start.checked_add(exp_units.len())?; + if content_end < self.len() + && self[content_end] == 0x22 + && &self[content_start..content_end] == exp_units + { + Some(content_end + 1) + } else { + None + } + } + } + } + + #[inline] + fn parse_f64(self, start: usize, end: usize) -> Option { + let slice = &self[start..end]; + if slice.len() <= 64 { + let mut stack_buf = [0u8; 64]; + for (dst, &u) in stack_buf[..slice.len()].iter_mut().zip(slice.iter()) { + *dst = u as u8; + } + fast_float2::parse(&stack_buf[..slice.len()]).ok() + } else { + let heap_buf: Vec = slice.iter().map(|&u| u as u8).collect(); + fast_float2::parse(&heap_buf).ok() + } } } @@ -125,6 +326,111 @@ enum JsonNode { Object(Vec<(JsString, JsonNode)>), } +trait SourceTracker { + type Node; + type ArrayNodes: Default; + type ObjEntries: Default; + + fn primitive<'a, I: JsonInput<'a>>( + input: I, + start: usize, + end: usize, + val: &JsValue, + ) -> Self::Node; + fn literal_primitive(lit: JsString, val: &JsValue) -> Self::Node; + fn push_array_node(nodes: &mut Self::ArrayNodes, node: Self::Node); + fn finish_array(nodes: Self::ArrayNodes) -> Self::Node; + fn push_obj_entry(entries: &mut Self::ObjEntries, key: &JsString, node: Self::Node); + fn finish_object(entries: Self::ObjEntries) -> Self::Node; +} + +struct NoSource; + +impl SourceTracker for NoSource { + type Node = (); + type ArrayNodes = (); + type ObjEntries = (); + + #[inline(always)] + fn primitive<'a, I: JsonInput<'a>>( + _input: I, + _start: usize, + _end: usize, + _val: &JsValue, + ) -> Self::Node { + } + + #[inline(always)] + fn literal_primitive(_lit: JsString, _val: &JsValue) -> Self::Node {} + + #[inline(always)] + fn push_array_node(_nodes: &mut Self::ArrayNodes, _node: Self::Node) {} + + #[inline(always)] + fn finish_array(_nodes: Self::ArrayNodes) -> Self::Node {} + + #[inline(always)] + fn push_obj_entry(_entries: &mut Self::ObjEntries, _key: &JsString, _node: Self::Node) {} + + #[inline(always)] + fn finish_object(_entries: Self::ObjEntries) -> Self::Node {} +} + +struct WithSource; + +impl SourceTracker for WithSource { + type Node = JsonNode; + type ArrayNodes = Vec; + type ObjEntries = Vec<(JsString, JsonNode)>; + + #[inline] + fn primitive<'a, I: JsonInput<'a>>( + input: I, + start: usize, + end: usize, + val: &JsValue, + ) -> Self::Node { + JsonNode::Primitive(input.slice_to_js_string(start, end), val.clone()) + } + + #[inline] + fn literal_primitive(lit: JsString, val: &JsValue) -> Self::Node { + JsonNode::Primitive(lit, val.clone()) + } + + #[inline] + fn push_array_node(nodes: &mut Self::ArrayNodes, node: Self::Node) { + nodes.push(node); + } + + #[inline] + fn finish_array(nodes: Self::ArrayNodes) -> Self::Node { + JsonNode::Array(nodes) + } + + #[inline] + fn push_obj_entry(entries: &mut Self::ObjEntries, key: &JsString, node: Self::Node) { + entries.push((key.clone(), node)); + } + + #[inline] + fn finish_object(entries: Self::ObjEntries) -> Self::Node { + JsonNode::Object(entries) + } +} + +#[inline] +fn is_cacheable_chain_key(key: &JsString) -> bool { + match key.as_str().variant() { + boa_string::JsStrVariant::Latin1(bytes) => { + bytes.iter().all(|&b| b >= 0x20 && b != b'"' && b != b'\\') + } + boa_string::JsStrVariant::Utf16(units) => { + units.iter().all(|&u| u >= 0x20 && u != 0x22 && u != 0x5C) + } + } +} + /// JavaScript `JSON` global object. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct Json; @@ -180,19 +486,19 @@ impl Json { let (unfiltered, source_tree) = match js_str.as_str().variant() { boa_string::JsStrVariant::Latin1(bytes) => { if reviver_obj.is_some() { - let (val, node) = Self::parse_ecma404::<_, true>(bytes, context)?; + let (val, node) = Self::parse_ecma404::<_, WithSource>(bytes, context)?; (val, Some(node)) } else { - let (val, _) = Self::parse_ecma404::<_, false>(bytes, context)?; + let (val, ()) = Self::parse_ecma404::<_, NoSource>(bytes, context)?; (val, None) } } boa_string::JsStrVariant::Utf16(units) => { if reviver_obj.is_some() { - let (val, node) = Self::parse_ecma404::<_, true>(units, context)?; + let (val, node) = Self::parse_ecma404::<_, WithSource>(units, context)?; (val, Some(node)) } else { - let (val, _) = Self::parse_ecma404::<_, false>(units, context)?; + let (val, ()) = Self::parse_ecma404::<_, NoSource>(units, context)?; (val, None) } } @@ -225,31 +531,50 @@ impl Json { /// Direct ECMA-404 iterative JSON parser over `Latin1(&[u8])` or `Utf16(&[u16])`. /// - /// - Uses `fast-float2` for exact IEEE-754 round-to-nearest-even `f64` conversion and `±Infinity` on overflow. - /// - Preserves lone UTF-16 surrogates (`\uD800`–`\uDFFF` and literal unpaired surrogates). - /// - Zero-copy `JsStr::latin1` / `utf16` slicing for unescaped strings. + /// - Uses `fast-float2` for exact IEEE-754 round-to-nearest-even `f64` conversion and `+-Infinity` on overflow. + /// - Preserves lone UTF-16 surrogates (`\uD800`..`\uDFFF` and literal unpaired surrogates). + /// - Zero-copy `JsStr::latin1` / `utf16` slicing with 8-byte SWAR string scanning. + /// - Uses `SharedShape` and per-depth shape-chain prediction for ordinary objects so homogeneous object arrays skip key allocation, hashing, and shape transitions. /// - Uses an explicit heap-allocated container stack (`O(1)` C/Rust call stack) supporting up to 2048 nesting levels. - fn parse_ecma404<'a, I: JsonInput<'a>, const WITH_SOURCE: bool>( + fn parse_ecma404<'a, I: JsonInput<'a>, S: SourceTracker>( input: I, context: &mut Context, - ) -> JsResult<(JsValue, JsonNode)> { + ) -> JsResult<(JsValue, S::Node)> { + use crate::builtins::OrdinaryObject; + use crate::object::{IndexedProperties, PropertyMap, shape::SharedShape}; + use crate::property::PropertyKey; + const MAX_DEPTH: usize = 2048; + const SHAPE_CACHE_DEPTHS: usize = 16; + const MAX_CHAIN_KEYS: usize = 64; + + type ShapeChain = Rc<[(JsString, SharedShape)]>; - enum ContainerFrame { + enum ContainerFrame { Array { elements: thin_vec::ThinVec, - child_nodes: Vec, + child_nodes: S::ArrayNodes, }, - Object { - obj: JsObject, + ObjectFast { + chain: ShapeChain, + matched_len: usize, + storage: Vec, + entries: S::ObjEntries, + depth: usize, + }, + ObjectGeneric { + props: PropertyMap, + chain_builder: Option>, current_key: JsString, - entries: Vec<(JsString, JsonNode)>, + entries: S::ObjEntries, + depth: usize, }, } struct ParserState<'a, I> { input: I, pos: usize, + depth_chains: [Option; SHAPE_CACHE_DEPTHS], _marker: std::marker::PhantomData<&'a ()>, } @@ -269,25 +594,20 @@ impl Json { #[inline] fn skip_ws(&mut self) { - let len = self.input.len(); - while self.pos < len { - match self.input.code_unit(self.pos) { - 0x20 | 0x09 | 0x0A | 0x0D => self.pos += 1, - _ => break, - } - } - } - - #[inline] - fn dummy_node() -> JsonNode { - JsonNode::Primitive(js_string!(), JsValue::undefined()) + self.pos = self.input.skip_ws(self.pos); } - fn parse_root( + fn parse_root( &mut self, context: &mut Context, - ) -> JsResult<(JsValue, JsonNode)> { - let mut stack: Vec = Vec::new(); + ) -> JsResult<(JsValue, St::Node)> { + let mut stack: Vec> = Vec::new(); + let base_obj_shape = context + .intrinsics() + .templates() + .ordinary_object() + .shape() + .clone(); 'parse_val: loop { self.skip_ws(); @@ -299,14 +619,7 @@ impl Json { let start = self.pos; let s = self.parse_string()?; let val = JsValue::new(s); - let node = if SRC { - JsonNode::Primitive( - self.input.slice_to_js_string(start, self.pos), - val.clone(), - ) - } else { - Self::dummy_node() - }; + let node = St::primitive(self.input, start, self.pos, &val); (val, node) } 0x5B => { @@ -319,35 +632,32 @@ impl Json { { self.pos += 1; let arr = crate::builtins::Array::array_create(0, None, context)?; - let node = if SRC { - JsonNode::Array(Vec::new()) - } else { - Self::dummy_node() - }; + let node = St::finish_array(St::ArrayNodes::default()); (arr.into(), node) } else { stack.push(ContainerFrame::Array { elements: thin_vec::ThinVec::new(), - child_nodes: Vec::new(), + child_nodes: St::ArrayNodes::default(), }); continue 'parse_val; } } 0x7B => { - if stack.len() >= MAX_DEPTH { + let depth = stack.len(); + if depth >= MAX_DEPTH { return Err(self.syntax_err("JSON nesting depth exceeded")); } self.pos += 1; self.skip_ws(); - let obj = JsObject::with_object_proto(context.intrinsics()); if self.pos < self.input.len() && self.input.code_unit(self.pos) == 0x7D { self.pos += 1; - let node = if SRC { - JsonNode::Object(Vec::new()) - } else { - Self::dummy_node() - }; + let obj = context + .intrinsics() + .templates() + .ordinary_object() + .create(OrdinaryObject, Vec::new()); + let node = St::finish_object(St::ObjEntries::default()); (obj.into(), node) } else { if self.pos >= self.input.len() @@ -357,6 +667,34 @@ impl Json { self.syntax_err("expected string key in JSON object") ); } + if depth < SHAPE_CACHE_DEPTHS + && let Some(ref chain) = self.depth_chains[depth] + && let Some((exp_key, _)) = chain.first() + && let Some(after_quote) = + self.input.try_match_unescaped_key(self.pos, exp_key) + { + let chain_cloned = chain.clone(); + let cap = chain_cloned.len(); + self.pos = after_quote; + self.skip_ws(); + if self.pos >= self.input.len() + || self.input.code_unit(self.pos) != 0x3A + { + return Err(self.syntax_err( + "expected ':' after key in JSON object", + )); + } + self.pos += 1; + stack.push(ContainerFrame::ObjectFast { + chain: chain_cloned, + matched_len: 0, + storage: Vec::with_capacity(cap), + entries: St::ObjEntries::default(), + depth, + }); + continue 'parse_val; + } + let key = self.parse_string()?; self.skip_ws(); if self.pos >= self.input.len() @@ -367,10 +705,19 @@ impl Json { ); } self.pos += 1; - stack.push(ContainerFrame::Object { - obj, + let props = PropertyMap::from_parts( + base_obj_shape.clone().into(), + Vec::with_capacity(4), + IndexedProperties::default(), + ); + let chain_builder = (depth < SHAPE_CACHE_DEPTHS) + .then(|| Vec::with_capacity(8)); + stack.push(ContainerFrame::ObjectGeneric { + props, + chain_builder, current_key: key, - entries: Vec::new(), + entries: St::ObjEntries::default(), + depth, }); continue 'parse_val; } @@ -383,11 +730,7 @@ impl Json { { self.pos += 4; let val = JsValue::new(true); - let node = if SRC { - JsonNode::Primitive(js_string!("true"), val.clone()) - } else { - Self::dummy_node() - }; + let node = St::literal_primitive(js_string!("true"), &val); (val, node) } else { return Err(self.syntax_err("expected 'true'")); @@ -402,11 +745,7 @@ impl Json { { self.pos += 5; let val = JsValue::new(false); - let node = if SRC { - JsonNode::Primitive(js_string!("false"), val.clone()) - } else { - Self::dummy_node() - }; + let node = St::literal_primitive(js_string!("false"), &val); (val, node) } else { return Err(self.syntax_err("expected 'false'")); @@ -420,11 +759,7 @@ impl Json { { self.pos += 4; let val = JsValue::null(); - let node = if SRC { - JsonNode::Primitive(js_string!("null"), val.clone()) - } else { - Self::dummy_node() - }; + let node = St::literal_primitive(js_string!("null"), &val); (val, node) } else { return Err(self.syntax_err("expected 'null'")); @@ -433,14 +768,7 @@ impl Json { 0x2D | 0x30..=0x39 => { let start = self.pos; let val = self.parse_number()?; - let node = if SRC { - JsonNode::Primitive( - self.input.slice_to_js_string(start, self.pos), - val.clone(), - ) - } else { - Self::dummy_node() - }; + let node = St::primitive(self.input, start, self.pos, &val); (val, node) } _ => return Err(self.syntax_err("unexpected token in JSON")), @@ -456,9 +784,7 @@ impl Json { child_nodes, } => { elements.push(cur_val); - if SRC { - child_nodes.push(cur_node); - } + St::push_array_node(child_nodes, cur_node); self.skip_ws(); if self.pos >= self.input.len() { return Err(self.syntax_err("unterminated array in JSON")); @@ -494,11 +820,7 @@ impl Json { .properties_mut() .override_indexed_properties(elements); cur_val = arr.into(); - cur_node = if SRC { - JsonNode::Array(child_nodes) - } else { - Self::dummy_node() - }; + cur_node = St::finish_array(child_nodes); continue 'attach; } _ => { @@ -508,19 +830,155 @@ impl Json { } } } - ContainerFrame::Object { - obj, + ContainerFrame::ObjectFast { + chain, + matched_len, + storage, + entries, + depth, + } => { + St::push_obj_entry(entries, &chain[*matched_len].0, cur_node); + storage.push(cur_val); + *matched_len += 1; + self.skip_ws(); + if self.pos >= self.input.len() { + return Err(self.syntax_err("unterminated object in JSON")); + } + match self.input.code_unit(self.pos) { + 0x2C => { + self.pos += 1; + self.skip_ws(); + if self.pos < self.input.len() + && self.input.code_unit(self.pos) == 0x7D + { + return Err( + self.syntax_err("trailing comma in JSON object") + ); + } + if self.pos >= self.input.len() + || self.input.code_unit(self.pos) != 0x22 + { + return Err(self + .syntax_err("expected string key in JSON object")); + } + if *matched_len < chain.len() + && let Some(after_quote) = self + .input + .try_match_unescaped_key( + self.pos, + &chain[*matched_len].0, + ) + { + self.pos = after_quote; + self.skip_ws(); + if self.pos >= self.input.len() + || self.input.code_unit(self.pos) != 0x3A + { + return Err(self.syntax_err( + "expected ':' after key in JSON object", + )); + } + self.pos += 1; + continue 'parse_val; + } + + let next_key = self.parse_string()?; + self.skip_ws(); + if self.pos >= self.input.len() + || self.input.code_unit(self.pos) != 0x3A + { + return Err(self.syntax_err( + "expected ':' after key in JSON object", + )); + } + self.pos += 1; + let matched = *matched_len; + let frame_depth = *depth; + let prev_shape = chain[matched - 1].1.clone(); + let chain_builder = (frame_depth < SHAPE_CACHE_DEPTHS + && matched < MAX_CHAIN_KEYS) + .then(|| chain[..matched].to_vec()); + let props = PropertyMap::from_parts( + prev_shape.into(), + std::mem::take(storage), + IndexedProperties::default(), + ); + let entries_taken = std::mem::take(entries); + *top = ContainerFrame::ObjectGeneric { + props, + chain_builder, + current_key: next_key, + entries: entries_taken, + depth: frame_depth, + }; + continue 'parse_val; + } + 0x7D => { + self.pos += 1; + let Some(ContainerFrame::ObjectFast { + chain, + matched_len, + storage, + entries, + .. + }) = stack.pop() + else { + unreachable!() + }; + let final_shape = chain[matched_len - 1].1.clone(); + let obj = JsObject::from_property_map( + PropertyMap::from_parts( + final_shape.into(), + storage, + IndexedProperties::default(), + ), + ); + cur_val = obj.into(); + cur_node = St::finish_object(entries); + continue 'attach; + } + _ => { + return Err( + self.syntax_err("expected ',' or '}' in JSON object") + ); + } + } + } + ContainerFrame::ObjectGeneric { + props, + chain_builder, current_key, entries, + .. } => { let key = std::mem::take(current_key); - if SRC { - entries.push((key.clone(), cur_node)); + St::push_obj_entry(entries, &key, cur_node); + let prev_storage_len = props.storage.len(); + let pk = PropertyKey::from(key); + let key_for_chain = if chain_builder.is_some() { + match &pk { + PropertyKey::String(s) + if prev_storage_len < MAX_CHAIN_KEYS + && is_cacheable_chain_key(s) => + { + Some(s.clone()) + } + _ => None, + } + } else { + None + }; + props.insert_data_property(pk, cur_val); + if let Some(builder) = chain_builder { + if let Some(chain_key) = key_for_chain + && props.storage.len() == prev_storage_len + 1 + && let Some(s) = props.shape.as_shared() + { + builder.push((chain_key, s.clone())); + } else { + *chain_builder = None; + } } - obj.borrow_mut().properties_mut().insert_data_property( - crate::property::PropertyKey::from(key), - cur_val, - ); self.skip_ws(); if self.pos >= self.input.len() { return Err(self.syntax_err("unterminated object in JSON")); @@ -557,17 +1015,25 @@ impl Json { } 0x7D => { self.pos += 1; - let Some(ContainerFrame::Object { obj, entries, .. }) = - stack.pop() + let Some(ContainerFrame::ObjectGeneric { + props, + chain_builder, + entries, + depth, + .. + }) = stack.pop() else { unreachable!() }; + if depth < SHAPE_CACHE_DEPTHS + && let Some(built) = chain_builder + && !built.is_empty() + { + self.depth_chains[depth] = Some(built.into()); + } + let obj = JsObject::from_property_map(props); cur_val = obj.into(); - cur_node = if SRC { - JsonNode::Object(entries) - } else { - Self::dummy_node() - }; + cur_node = St::finish_object(entries); continue 'attach; } _ => { @@ -582,26 +1048,24 @@ impl Json { } } + #[inline] fn parse_string(&mut self) -> JsResult { debug_assert_eq!(self.input.code_unit(self.pos), 0x22); self.pos += 1; let content_start = self.pos; - let len = self.input.len(); - - while self.pos < len { - let c = self.input.code_unit(self.pos); + let stop = self.input.scan_unescaped_string(content_start); + self.pos = stop; + if stop < self.input.len() { + let c = self.input.code_unit(stop); if c == 0x22 { - let s = self.input.slice_to_js_string(content_start, self.pos); - self.pos += 1; + let s = self.input.slice_to_js_string(content_start, stop); + self.pos = stop + 1; return Ok(s); } if c == 0x5C { return self.parse_string_escaped(content_start); } - if c < 0x20 { - return Err(self.syntax_err("unescaped control character in JSON string")); - } - self.pos += 1; + return Err(self.syntax_err("unescaped control character in JSON string")); } Err(self.syntax_err("unterminated string in JSON")) } @@ -680,14 +1144,7 @@ impl Json { } } else { let chunk_start = self.pos; - self.pos += 1; - while self.pos < len { - let ch = self.input.code_unit(self.pos); - if ch == 0x22 || ch == 0x5C || ch < 0x20 { - break; - } - self.pos += 1; - } + self.pos = self.input.scan_unescaped_string(chunk_start + 1); if let Some(chunk) = self.input.latin1_slice(chunk_start, self.pos) { latin1.extend_from_slice(chunk); } @@ -763,6 +1220,7 @@ impl Json { Err(self.syntax_err("unterminated string in JSON")) } + #[inline] fn parse_number(&mut self) -> JsResult { let start = self.pos; let len = self.input.len(); @@ -774,18 +1232,30 @@ impl Json { if self.pos >= len { return Err(self.syntax_err("unexpected end of number in JSON")); } - match self.input.code_unit(self.pos) { + let mut acc: u64 = 0; + let mut digits: usize; + let first = self.input.code_unit(self.pos); + match first { 0x30 => { self.pos += 1; + digits = 1; if self.pos < len && matches!(self.input.code_unit(self.pos), 0x30..=0x39) { return Err(self.syntax_err("leading zero in JSON number")); } } 0x31..=0x39 => { + acc = u64::from(first - 0x30); + digits = 1; self.pos += 1; - while self.pos < len - && matches!(self.input.code_unit(self.pos), 0x30..=0x39) - { + while self.pos < len { + let d = self.input.code_unit(self.pos); + if !matches!(d, 0x30..=0x39) { + break; + } + if digits < 19 { + acc = acc * 10 + u64::from(d - 0x30); + } + digits += 1; self.pos += 1; } } @@ -799,6 +1269,7 @@ impl Json { if self.pos >= len || !matches!(self.input.code_unit(self.pos), 0x30..=0x39) { return Err(self.syntax_err("expected digit after decimal point in JSON")); } + self.pos += 1; while self.pos < len && matches!(self.input.code_unit(self.pos), 0x30..=0x39) { self.pos += 1; } @@ -813,36 +1284,34 @@ impl Json { if self.pos >= len || !matches!(self.input.code_unit(self.pos), 0x30..=0x39) { return Err(self.syntax_err("expected digit in JSON exponent")); } + self.pos += 1; while self.pos < len && matches!(self.input.code_unit(self.pos), 0x30..=0x39) { self.pos += 1; } } - let num_bytes = self.input.ascii_bytes(start, self.pos); - let bytes = num_bytes.as_ref(); - if !is_float { - if is_neg && bytes.len() == 2 && bytes[1] == b'0' { + if is_neg && acc == 0 { return Ok(JsValue::new(-0.0f64)); } - let digits = if is_neg { &bytes[1..] } else { bytes }; - if digits.len() <= 15 { - let mut acc: i64 = 0; - for &b in digits { - acc = acc * 10 + i64::from(b - b'0'); - } + if digits <= 16 && acc <= 9_007_199_254_740_992 { if is_neg { - acc = -acc; + if acc <= (i32::MAX as u64) + 1 { + return Ok(JsValue::new((-(acc as i64)) as i32)); + } + return Ok(JsValue::new(-(acc as f64))); } - if let Ok(i) = i32::try_from(acc) { - return Ok(JsValue::new(i)); + if acc <= i32::MAX as u64 { + return Ok(JsValue::new(acc as i32)); } return Ok(JsValue::new(acc as f64)); } } - let f: f64 = fast_float2::parse(bytes) - .map_err(|_| self.syntax_err("invalid number in JSON"))?; + let f = self + .input + .parse_f64(start, self.pos) + .ok_or_else(|| self.syntax_err("invalid number in JSON"))?; Ok(JsValue::new(f)) } } @@ -850,9 +1319,10 @@ impl Json { let mut state = ParserState { input, pos: 0, + depth_chains: std::array::from_fn(|_| None), _marker: std::marker::PhantomData, }; - let res = state.parse_root::(context)?; + let res = state.parse_root::(context)?; state.skip_ws(); if state.pos != state.input.len() { return Err(state.syntax_err("unexpected trailing characters in JSON")); @@ -1023,10 +1493,10 @@ impl Json { // 3. Parse StringToCodePoints(jsonString) as a JSON text as specified in ECMA-404. match json_string.as_str().variant() { boa_string::JsStrVariant::Latin1(bytes) => { - Self::parse_ecma404::<_, false>(bytes, context)?; + Self::parse_ecma404::<_, NoSource>(bytes, context)?; } boa_string::JsStrVariant::Utf16(units) => { - Self::parse_ecma404::<_, false>(units, context)?; + Self::parse_ecma404::<_, NoSource>(units, context)?; } } @@ -1286,40 +1756,41 @@ impl Json { boa_string::JsStrVariant::Latin1(bytes) => { buf.push(b'"'); let mut start = 0usize; - for (i, &b) in bytes.iter().enumerate() { - if b < 0x20 || b == b'"' || b == b'\\' || b >= 0x80 { - if i > start { - buf.extend_from_slice(&bytes[start..i]); + let len = bytes.len(); + while start < len { + let i = scan_ascii_unescaped_json_bytes(bytes, start); + if i > start { + buf.extend_from_slice(&bytes[start..i]); + } + if i >= len { + break; + } + let b = bytes[i]; + match b { + b'"' => buf.extend_from_slice(b"\\\""), + b'\\' => buf.extend_from_slice(b"\\\\"), + 0x08 => buf.extend_from_slice(b"\\b"), + 0x09 => buf.extend_from_slice(b"\\t"), + 0x0A => buf.extend_from_slice(b"\\n"), + 0x0C => buf.extend_from_slice(b"\\f"), + 0x0D => buf.extend_from_slice(b"\\r"), + b if b < 0x20 => { + buf.extend_from_slice(&[ + b'\\', + b'u', + b'0', + b'0', + HEX[(b >> 4) as usize], + HEX[(b & 0xF) as usize], + ]); } - match b { - b'"' => buf.extend_from_slice(b"\\\""), - b'\\' => buf.extend_from_slice(b"\\\\"), - 0x08 => buf.extend_from_slice(b"\\b"), - 0x09 => buf.extend_from_slice(b"\\t"), - 0x0A => buf.extend_from_slice(b"\\n"), - 0x0C => buf.extend_from_slice(b"\\f"), - 0x0D => buf.extend_from_slice(b"\\r"), - b if b < 0x20 => { - buf.extend_from_slice(&[ - b'\\', - b'u', - b'0', - b'0', - HEX[(b >> 4) as usize], - HEX[(b & 0xF) as usize], - ]); - } - b => { - *all_ascii = false; - buf.push(0xC0 | (b >> 6)); - buf.push(0x80 | (b & 0x3F)); - } + b => { + *all_ascii = false; + buf.push(0xC0 | (b >> 6)); + buf.push(0x80 | (b & 0x3F)); } - start = i + 1; } - } - if start < bytes.len() { - buf.extend_from_slice(&bytes[start..]); + start = i + 1; } buf.push(b'"'); true @@ -1387,6 +1858,7 @@ impl Json { obj_proto: &JsObject, arr_proto: &JsObject, arr_template_shape_addr: usize, + verified_obj_shape_addr: &mut usize, to_json_key: &PropertyKey, ) -> JsResult { match val.variant() { @@ -1418,7 +1890,10 @@ impl Json { JsVariant::Object(obj) => { let borrow = obj.borrow(); let props = borrow.properties(); - if props.shape.lookup(to_json_key).is_some() { + let shape_addr = props.shape.to_addr_usize(); + let shape_preverified = + shape_addr != 0 && shape_addr == *verified_obj_shape_addr; + if !shape_preverified && props.shape.lookup(to_json_key).is_some() { return Ok(FastStatus::Fallback); } if obj.is_callable() { @@ -1432,7 +1907,7 @@ impl Json { } if obj.is_array() { - if props.shape.to_addr_usize() != arr_template_shape_addr { + if shape_addr != arr_template_shape_addr { if let Some(ref p) = props.shape.prototype() { if p != arr_proto { return Ok(FastStatus::Fallback); @@ -1489,6 +1964,7 @@ impl Json { obj_proto, arr_proto, arr_template_shape_addr, + verified_obj_shape_addr, to_json_key, ) { Ok(FastStatus::Written) => {} @@ -1527,10 +2003,13 @@ impl Json { if !obj.is_ordinary() || !indexed_empty { return Ok(FastStatus::Fallback); } - if let Some(ref p) = props.shape.prototype() { - if p != obj_proto { - return Ok(FastStatus::Fallback); + if !shape_preverified { + if let Some(ref p) = props.shape.prototype() { + if p != obj_proto { + return Ok(FastStatus::Fallback); + } } + *verified_obj_shape_addr = shape_addr; } stack.push(addr); @@ -1581,6 +2060,7 @@ impl Json { obj_proto, arr_proto, arr_template_shape_addr, + verified_obj_shape_addr, to_json_key, )? { FastStatus::Written => { @@ -1628,6 +2108,7 @@ impl Json { let mut buf = Vec::with_capacity(128); let mut all_ascii = true; let mut stack = Vec::with_capacity(8); + let mut verified_obj_shape_addr = 0usize; match write_val( value, @@ -1637,6 +2118,7 @@ impl Json { &obj_proto, &arr_proto, arr_template_shape_addr, + &mut verified_obj_shape_addr, &to_json_key, )? { FastStatus::Written => { diff --git a/vendor/boa_engine/src/object/jsobject.rs b/vendor/boa_engine/src/object/jsobject.rs index d755236..ec7f774 100644 --- a/vendor/boa_engine/src/object/jsobject.rs +++ b/vendor/boa_engine/src/object/jsobject.rs @@ -135,6 +135,24 @@ impl JsObject { JsObject { inner }.upcast() } + /// Creates a new ordinary `JsObject` directly from a prebuilt [`PropertyMap`]. + #[inline] + #[must_use] + pub(crate) fn from_property_map(properties: PropertyMap) -> Self { + let internal_methods = OrdinaryObject.internal_methods(); + let inner = Gc::new(VTableObject { + object: GcRefCell::new(Object { + data: ObjectData::new(OrdinaryObject), + properties, + extensible: true, + private_elements: ThinVec::new(), + }), + vtable: internal_methods, + }); + + JsObject { inner }.upcast() + } + /// Creates a new ordinary object with its prototype set to the `Object` prototype. /// /// This is equivalent to calling the specification's abstract operation diff --git a/vendor/boa_engine/src/object/property_map.rs b/vendor/boa_engine/src/object/property_map.rs index e16254d..c2c591b 100644 --- a/vendor/boa_engine/src/object/property_map.rs +++ b/vendor/boa_engine/src/object/property_map.rs @@ -503,6 +503,21 @@ impl PropertyMap { } } + /// Construct a [`PropertyMap`] directly from prebuilt [`Shape`], storage, and [`IndexedProperties`]. + #[must_use] + #[inline] + pub(crate) const fn from_parts( + shape: Shape, + storage: Vec, + indexed_properties: IndexedProperties, + ) -> Self { + Self { + indexed_properties, + shape, + storage, + } + } + /// Construct a [`PropertyMap`] with the given prototype with a unique [`Shape`]. #[must_use] #[inline] @@ -611,6 +626,29 @@ impl PropertyMap { let attributes = SlotAttributes::WRITABLE | SlotAttributes::ENUMERABLE | SlotAttributes::CONFIGURABLE; + if let Some(shared) = self.shape.as_shared() { + let transition_key = TransitionKey { + property_key: key, + attributes, + }; + if let Some(next_shape) = shared.try_fast_insert_property_transition(&transition_key) { + self.shape = Shape::from_shared_checked(next_shape); + self.storage.push(value); + return; + } + if let Some(slot) = shared.lookup(&transition_key.property_key) { + let index = slot.index as usize; + if slot.attributes == attributes { + self.storage[index] = value; + return; + } + } + self.shape = + Shape::from_shared_checked(shared.insert_property_transition_missed(transition_key)); + self.storage.push(value); + return; + } + if let Some(slot) = self.shape.lookup(&key) { let index = slot.index as usize; if slot.attributes == attributes { diff --git a/vendor/boa_engine/src/object/shape/mod.rs b/vendor/boa_engine/src/object/shape/mod.rs index ea27ece..2c0fd2a 100644 --- a/vendor/boa_engine/src/object/shape/mod.rs +++ b/vendor/boa_engine/src/object/shape/mod.rs @@ -103,6 +103,22 @@ impl Shape { None } + #[inline] + pub(crate) const fn as_shared(&self) -> Option<&SharedShape> { + if let Inner::Shared(shape) = &self.inner { + return Some(shape); + } + None + } + + #[inline] + pub(crate) fn from_shared_checked(shape: SharedShape) -> Self { + if shape.transition_count() >= Self::TRANSITION_COUNT_MAX { + return shape.to_unique().into(); + } + shape.into() + } + /// Create an insert property transitions returning the new transitioned [`Shape`]. /// /// NOTE: This assumes that there is no property with the given key! diff --git a/vendor/boa_engine/src/object/shape/shared_shape/mod.rs b/vendor/boa_engine/src/object/shape/shared_shape/mod.rs index 2cca315..0820079 100644 --- a/vendor/boa_engine/src/object/shape/shared_shape/mod.rs +++ b/vendor/boa_engine/src/object/shape/shared_shape/mod.rs @@ -211,17 +211,28 @@ impl SharedShape { new_shape } - /// Create a [`SharedShape`] insert property transition. - pub(crate) fn insert_property_transition(&self, key: TransitionKey) -> Self { - // Check if we have already created such a transition, if so use it! - if let Some(shape) = self.forward_transitions().get_property(&key) { + /// Fast lookup of an existing `insert_property_transition` without touching `PropertyTable`. + /// + /// Because an insert transition out of `self` is only created for a key not already present + /// in `self`, a hit here guarantees both that `key.property_key` is a new property on `self` + /// and that the resulting `SharedShape` already exists. + #[inline] + pub(crate) fn try_fast_insert_property_transition(&self, key: &TransitionKey) -> Option { + if let Some(shape) = self.forward_transitions().get_property(key) { if let Some(inner) = shape.upgrade() { - return Self { inner }; + if inner.flags.is_insert_transition_type() { + return Some(Self { inner }); + } + return None; } - self.forward_transitions().prune_property_transitions(); } + None + } + /// Create a [`SharedShape`] insert property transition when the caller has already verified + /// `try_fast_insert_property_transition` missed and `lookup` returned `None`. + pub(crate) fn insert_property_transition_missed(&self, key: TransitionKey) -> Self { let property_table = self.property_table().add_property_deep_clone_if_needed( key.property_key.clone(), key.attributes, @@ -244,6 +255,20 @@ impl SharedShape { new_shape } + /// Create a [`SharedShape`] insert property transition. + pub(crate) fn insert_property_transition(&self, key: TransitionKey) -> Self { + // Check if we have already created such a transition, if so use it! + if let Some(shape) = self.forward_transitions().get_property(&key) { + if let Some(inner) = shape.upgrade() { + return Self { inner }; + } + + self.forward_transitions().prune_property_transitions(); + } + + self.insert_property_transition_missed(key) + } + /// Create a [`SharedShape`] change prototype transition, returning [`ChangeTransition`]. pub(crate) fn change_attributes_transition( &self, diff --git a/vendor/boa_engine/src/property/mod.rs b/vendor/boa_engine/src/property/mod.rs index 4bad2a2..b301a1e 100644 --- a/vendor/boa_engine/src/property/mod.rs +++ b/vendor/boa_engine/src/property/mod.rs @@ -685,17 +685,64 @@ where } } +#[inline] +fn parse_u32_index_bytes(bytes: &[u8]) -> Option { + let first = *bytes.first()?; + if !first.is_ascii_digit() || bytes.len() > 10 { + return None; + } + if first == b'0' { + return (bytes.len() == 1).then(|| { + // SAFETY: `0` is not `u32::MAX`. + unsafe { NonMaxU32::new_unchecked(0) } + }); + } + let mut result = u32::from(first - b'0'); + if bytes.len() == 10 { + for &b in &bytes[1..] { + if !b.is_ascii_digit() { + return None; + } + result = result.checked_mul(10)?.checked_add(u32::from(b - b'0'))?; + } + NonMaxU32::new(result) + } else { + for &b in &bytes[1..] { + if !b.is_ascii_digit() { + return None; + } + result = result * 10 + u32::from(b - b'0'); + } + // SAFETY: `bytes.len() < 10`, so `result <= 999_999_999 < u32::MAX`. + Some(unsafe { NonMaxU32::new_unchecked(result) }) + } +} + +#[inline] +fn parse_u32_index_js_str(string: JsStr<'_>) -> Option { + match string.variant() { + boa_string::JsStrVariant::Latin1(bytes) => parse_u32_index_bytes(bytes), + boa_string::JsStrVariant::Utf16(units) => { + let first = *units.first()?; + if !matches!(first, 0x30..=0x39) || units.len() > 10 { + return None; + } + parse_u32_index(units.iter().copied()) + } + } +} + impl From> for PropertyKey { #[inline] fn from(string: JsStr<'_>) -> Self { - parse_u32_index(string.iter()).map_or_else(|| Self::String(string.into()), Self::Index) + parse_u32_index_js_str(string).map_or_else(|| Self::String(string.into()), Self::Index) } } impl From for PropertyKey { #[inline] fn from(string: JsString) -> Self { - parse_u32_index(string.as_str().iter()).map_or(Self::String(string), Self::Index) + parse_u32_index_js_str(string.as_str()).map_or(Self::String(string), Self::Index) } } diff --git a/vendor/boa_engine/src/script.rs b/vendor/boa_engine/src/script.rs index 29d5969..108b1eb 100644 --- a/vendor/boa_engine/src/script.rs +++ b/vendor/boa_engine/src/script.rs @@ -167,6 +167,15 @@ impl Script { Ok(cb) } + /// Returns `true` when this compiled script has no top-level lexical declarations + /// (`let`/`const`/`class` at global scope), allowing it to be evaluated repeatedly + /// on the same warm realm without `GlobalDeclarationInstantiation` lexical redeclaration errors. + pub fn can_reuse_across_runs(&self, context: &mut Context) -> bool { + self.codeblock(context) + .map(|cb| cb.global_lexs.is_empty()) + .unwrap_or(false) + } + /// Evaluates this script and returns its result. /// /// Note that this won't run any scheduled promise jobs; you need to call [`Context::run_jobs`]