Releases: thelabcorner/es-b64
Releases · thelabcorner/es-b64
Release list
ESB64 v1.2.1 — allocator exhaustion fix (10004) + facade ES3 fallback
ESB64 v1.2.1
Fixes
- Native allocator exhaustion (error 10004) in long-lived sessions — ESB64Native now uses a segmented growable arena: 16 MiB static BSS segment + VirtualAlloc growth segments (32 MiB default, unbounded count), address-ordered free list with same-segment coalescing, and VirtualFree release of fully-free segments (RSS returns to baseline when the host GC frees). 10004 now only fires on true process OOM. Verified live in Illustrator: 57 MiB retained without freeing succeeds where the old fixed pool died at ~16 MiB.
- Facade resilience — a positive native error (e.g. 10004) now falls back to the ES3 lane for that call instead of rethrowing; negative/fatal codes still rethrow. No permanent lane disable: the native lane retries next call and recovers after the host GC runs ESFreeMem.
Rollout
- Shared accelerator cache version bumped to v2 (ESB64Native_v2.dll), coordinated across the espack family (ESON/ESARR/ESCHARS/ESSTR/ESHTTP) so hosts replace the stale v1 pool.
- Bundles rebuilt with the canonical patched DLL (byte-verified in every artifact).
- All existing parity/validation green: 411 Node checks, WPT corpus, differential fuzz, live-engine battery, espack suite 39/39 + 6/6, adversarial allocator stress.
ESB64 v1.2.0 — espack merge architecture (attach accelerator by name)
ESB64 v1.2.0
New in this release
- espack merge architecture (espack v0.3.0):
ESPAK.attachnow targets the accelerator by name ("ESB64Native") instead of the default index 0 — index is not a stable API under a merged bundle. The empty-payload short-circuit keeps the standalone accel-only bundle loading exactly as before. ESB64.accel.jsxrebuilt on the espack v0.3.0 loader: shared-accel discovery for accel-less bundles (embedded-accel failure falls back to the on-disk shared accel), same WHATWG-exact native lane.- ESB64 stays the standalone shared "1" in the 1 + n model by design — no manifest/facade artifacts (its DLL is the accel embedded in every payload bundle, e.g. ESON/ESARR).
Assets
ESB64.accel.jsx/ESB64.accel.min.jsx— self-extracting accelerator bundleESB64Native.dll— freestanding WHATWG-exact accelerator (9,728 B), for embedding in your own espack bundleESB64.jsx,vendor-esb64.js,vendor-esb64-runtime.js,esb64-core.esm.mjs— facade/vendor/ESM builds
Validation
411 checks passed (WHATWG differential battery + vendored-runtime parity).
ESB64 v1.1.0 - ESPACK-accelerated native base64 lane
v1.1.0 — 2026-08-08
SemVer: minor — adds the self-extracting accelerated bundle (a new, opt-in artifact); no existing API, artifact, or behavior changed for existing callers.
Gate: 411 Node assertions / WPT base64.json 80/80 / 144,000 differential fuzz checks vs V8 (0 divergences, seed 42) / 66/66 live-engine vectors in ES3 mode + 66/66 in native mode, byte-identical across modes, Illustrator 30.6.0. All green on this commit.
Added
ESB64.accel.jsx(+ minifiedESB64.accel.min.jsx, banner preserved): self-extracting single-file bundle in the espack "1 + n" model — the freestandingESB64Native.dll(9,728 B) is embedded as base64, unpacked once per system into%LOCALAPPDATA%\espack\, andbtoa/atob(plusencodeLatin1/decodeLatin1) swap to the native lane viaESPAK.attach, ES3-first with full fallback. See README → Performance → Native acceleration.npm run build:accel(builds + minifies the accel bundle via the adobe-extendscript-minification conservative pipeline) andnpm run native-build(clang+lld freestanding DLL, x86-64-v2,-O3 -flto, no CRT).- live-verify parity gate:
npm run live-verifynow runs the 66-vector WHATWG battery in both modes (--mode es3|native|both) and requires byte-identical results across modes.
Fixed
- Host-heap corruption on native returns — the first freestanding allocator wrote its free-list header at
p - 16without validation; a foreign pointer or double-free corrupted the host heap (Illustrator access violations in ntdll heap code, observed live).espk_freenow validates pool bounds + alignment and scans the free list — foreign pointers and double-frees are ignored no-ops (see README → Performance → Native acceleration).
Changed
- Deterministic native build — the DLL's PE timestamp is now fixed (
/timestamp:0on lld,/Breproon the MSVC fallback), sonpm run native-buildproduces byte-identical output every time. Rebuilds no longer trip espack's vendor drift guard, which compares DLL bytes. (espack'svendor/ESB64Native.dllrefreshed to match.) - live-verify harness path — COM tool path updated to the current
comtool/location;ILLUSTRATOR_COM_TOOLenv override supported, matching the eson/espack harnesses.
Performance
btoa16,384 units: ES3 16,272 µs → native 272 µs (59.8×, live, this release; README's 2026-08-07 measurement: 18.6 ms → 317 µs, 58.5×).atob48 K units: ES3 63,558 µs → native 846 µs (75.1×, live, this release; README: 66.8 ms → 957 µs, 69.8×).- DLL size: 107,520 B (MSVC) → 9,728 B freestanding (−91%);
ESB64.accel.jsx203,920 → 73,528 B, minified 44,573 B.
Security
- The accelerated bundle loads and executes a native DLL via
ExternalObject— opt-in, and only afterESPAK.attachsucceeds; any failure keeps the WHATWG-exact ES3 lane. NUL-bearing and non-ASCII payloads never cross the string boundary (kTypeString truncates at NUL, verified live): they are dispatched to the ES3 lane, so the native lane cannot corrupt or truncate them (README → Performance → Native acceleration, "Parity contract").
Compatibility
- No change: the pure-ES3 bundles, hosts, and Node ≥ 18 tooling are untouched; the accelerated bundle is Windows x64 for the native lane with the full ES3 fallback everywhere else.
Release deliverables
| Deliverable | Purpose |
|---|---|
ESB64.accel.jsx |
Self-extracting accelerated bundle — the new single-file production artifact |
ESB64.accel.min.jsx |
Minified accel bundle (banner preserved) |
ESB64Native.dll |
The freestanding WHATWG-exact accelerator DLL (9,728 B) — for embedding into your own espack bundles |
ESB64.jsx |
Full-facade ES3 bundle (all lanes, capabilities, install, benchmark) |
vendor-esb64.js |
Drop-in vendor, gap-fills the globals |
vendor-esb64-runtime.js |
15.8 KB atob/btoa-only runtime for per-eval injection |
esb64-core.esm.mjs |
ESM core for Node/testing |
License: GPL-3.0-or-later.
ESB64 1.0.0
ESB64 - ExtendScript Base64: a drop-in atob/btoa polyfill plus UTF-8 codec library for ExtendScript (ES3) engines. First stable release.
What ESB64 does
- Drop-in
atob/btoa- true polyfill semantics: installs the globals only when absent, leaves a correct native alone; standardInvalidCharacterError-named errors - WHATWG forgiving-base64
atob- whitespace stripped, missing padding tolerated,length % 4 == 1and non-alphabet characters rejected; matches the WPTbase64.jsoncorpus (80/80 vectors) that browsers themselves are tested against - Extended UTF-8 lanes (
encodeUtf8/decodeUtf8,utf8Encode/utf8Decode) - WHATWG TextEncoder/Decoder semantics; round-trips any Unicode through base64 - Fast in the ES3 engine - the UTF-8 encode fast path rides the engine's native escaping functions (~50x over hand-rolled on 450 KB); an ASCII-identity fast path skips the decode state machine entirely; two-tier memoization makes repeat 1 MB payloads ~1000x faster
- Engine-hardened - charCodeAt-based scanning (the engine's
charAtis NUL-broken), array+join output building, split bitwise temporaries (the engine mis-compiles mixed|/&chains) - ES3-safe - no let/const/Promise; ES5 TypeScript target, esbuild
platform=neutral - No runtime dependencies - four artifacts, nothing to install
Attachments
| File | Purpose |
|---|---|
vendor-esb64.js |
Production drop-in: ESB64 + gap-fill install footer (28.6 KB) |
ESB64.jsx |
Bannerless IIFE facade ($.evalFile / COM-eval safe); defines ESB64 |
vendor-esb64-runtime.js |
Slim atob/btoa-only vendor (15.8 KB) for per-eval injection |
esb64-core.esm.mjs |
ESM core bundle for Node/automation (19 exports) |
Validation (v1.0.0)
- npm test: 411 Node assertions - PASS (WPT base64.json corpus + differential vs native + UTF-8)
- Fuzz: 144,000 differential checks vs V8 native atob/btoa, Node Buffer and TextDecoder, 0 divergences (12,000 iterations/lane, seed 12648430)
- Live engine battery (Illustrator 30.6.0 / ExtendScript 4.5.6): 66/66 vectors (documented in README; re-run via
npm run live-verify) - typecheck (tsc strict): clean
Notes
- The UTF-8 decoder follows WHATWG error grouping (one U+FFFD per bad sequence), not Node's ICU-backed TextDecoder (one per bad byte); malformed-sequence expectations are hardcoded vectors
- The engine has no native base64 at all (probed live:
typeof atob === "undefined") - ESB64 fills the gap - License: GPL-3.0-or-later