Repository navigation
v1.0.0
1.0 is a contract: jz, compile, instantiate, jz/interop, the options and the CLI flags change only in a major version, and an accepted program keeps JavaScript's values, exceptions and evaluation order at every optimization level, outside the listed differences.
Breaking
- JS semantics where 0.9 diverged: strings are UTF-16 (
'中'.lengthis 1, was 3), integers no longer wrap at 2³¹,null.xthrows,a[1.5]isundefined,catch (e)gets the thrownError. - The root exports
jz(withjz.memory),compileandinstantiateonly;compileModule,transform,jz.pool,jz/wasiandjz/transformare gone. - Options are a closed set: an unknown key throws a
TypeErrornaming it.optimizetakestrue,false,'size','speed'or{ level, simd, tailCall, exceptions, alloc, compact, rationalConst }(no 0–3); memory settings live inmemory: { initial, maximum, shared, import, fixed }. instantiate(wasm, { imports, memory, wasi })links what the module declares and refuses the rest by name.exportsholds the program's exports alone; jz's own are named__jz_*oninstance.exports.- An exported class is a class (
new mod.C()); an exported value is its live binding (exports.K, not.value). - A thrown value reaches the host as thrown:
throw 5arrives as5, an Error as the host's Error of its class. Early errors areSyntaxError. - A memory has the constructors,
read,write,resetandused, nothing else;allocTypedis gone. warningsis a callback of{ code, message, file, line, column, fn };whyreplaceswhyNotSimd.- CLI:
-O0,-O2,-O3,-Osor-O '{…}';--whyreplaces--why-not-simd; a dozen 0.9 flags are gone (jz --helplists what stays). .wasmbuilt by 0.9 needs a rebuild: load a prebuilt module with thejz/interopof the jz that built it.
New
- Memory comes back: a call frees on return what it allocated and did not keep, a loop each iteration, and replaced state is compacted. 20,000 calls that each build and drop 200 strings hold 1.1 MB, where 0.9.2 grew to 512 MB.
- try/catch/finally across
awaitandyield, getters and setters,await using, resizableArrayBuffer. - Under the JS host, undeclared names are the host's globals (
new Response(s),typeof WebSocket), andconsole.logprints as the host's console does. memory: { fixed: ['process'] }proves the named exports allocation-free, or fails the compile with the call path.- Source maps:
sourceMap: true,--source-map. - A
--host wasimodule is a WASI command (_startruns the program, then its own_start, then its timers) or a reactor when it exports_initialize;instantiateruns it in a JS host throughwasi: { write, read }. node scripts/native/compile.mjs app.js -o app(repo checkout) builds a native executable through wasm2c;--no-simdoutput needs no SIMD library.- Newly compiling: three.js's math layer (unmodified), web-audio-api (120 modules), @stdlib's math and distribution functions, guest271314's WebSocket server.
Faster, smaller
- Reference run at the release commit (run 41439115302, AMD EPYC 9V45, 91 cases, 52 in 0.9.2), geomean of rival time over jz time: V8 2.44× over 83 cases, JavaScriptCore 1.98× (83); against each case's nearest wasm rivals, clang→wasm 1.86× (33), rustc→wasm 1.86× (30), AssemblyScript 2.00× (19).
-Osoutput is 0.79× AssemblyScript's bytes over the 51 cases both compile. - Not ahead on that run: watr and jz compiling itself (every JS engine), vm (JSC 0.94×, clang→wasm 0.96×, bun 0.98×), threecull (Deno 0.96×), strbuild (zig→wasm 0.985×), hashjoin (bun 0.994×), webaudio (JSC 0.997×). fabrik, polytri and stdlib-exp carry no claim yet.
Fixed
- Wrong answers 0.9.2 gave without an error: an array lost
===and Map-key identity once it grew, an inherited static readundefined,x instanceof pick(k)read false, for-of over a host Set ran zero times,flat(2)flattened one level,'hello'.substr(-3, 2)was empty. new Array(3e9)throws a RangeError where its length read 2147483647;trycatches whato.m?.()throws.- A void export returns
undefinedon bun and Safari, not NaN; a Symbol reaches the host as a Symbol, not NaN. - Warnings name the program's own identifiers and positions, not compiler-minted names.
Full Changelog: v0.9.2...v1.0.0