Skip to content

Releases: thelabcorner/es-b64

ESB64 v1.2.1 — allocator exhaustion fix (10004) + facade ES3 fallback

Choose a tag to compare

@thelabcorner thelabcorner released this 11 Aug 03:35

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)

Choose a tag to compare

@thelabcorner thelabcorner released this 10 Aug 19:22

ESB64 v1.2.0

New in this release

  • espack merge architecture (espack v0.3.0): ESPAK.attach now 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.jsx rebuilt 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 bundle
  • ESB64Native.dll — freestanding WHATWG-exact accelerator (9,728 B), for embedding in your own espack bundle
  • ESB64.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

Choose a tag to compare

@thelabcorner thelabcorner released this 08 Aug 20:08

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 (+ minified ESB64.accel.min.jsx, banner preserved): self-extracting single-file bundle in the espack "1 + n" model — the freestanding ESB64Native.dll (9,728 B) is embedded as base64, unpacked once per system into %LOCALAPPDATA%\espack\, and btoa/atob (plus encodeLatin1/decodeLatin1) swap to the native lane via ESPAK.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) and npm run native-build (clang+lld freestanding DLL, x86-64-v2, -O3 -flto, no CRT).
  • live-verify parity gate: npm run live-verify now 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 - 16 without validation; a foreign pointer or double-free corrupted the host heap (Illustrator access violations in ntdll heap code, observed live). espk_free now 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:0 on lld, /Brepro on the MSVC fallback), so npm run native-build produces byte-identical output every time. Rebuilds no longer trip espack's vendor drift guard, which compares DLL bytes. (espack's vendor/ESB64Native.dll refreshed to match.)
  • live-verify harness path — COM tool path updated to the current comtool/ location; ILLUSTRATOR_COM_TOOL env override supported, matching the eson/espack harnesses.

Performance

  • btoa 16,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×).
  • atob 48 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.jsx 203,920 → 73,528 B, minified 44,573 B.

Security

  • The accelerated bundle loads and executes a native DLL via ExternalObject — opt-in, and only after ESPAK.attach succeeds; 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

Choose a tag to compare

@thelabcorner thelabcorner released this 07 Aug 17:14

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; standard InvalidCharacterError-named errors
  • WHATWG forgiving-base64 atob - whitespace stripped, missing padding tolerated, length % 4 == 1 and non-alphabet characters rejected; matches the WPT base64.json corpus (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 charAt is 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