github ocsigen/js_of_ocaml 6.4.0

6 hours ago

CHANGES:

Features/Changes

  • Compiler: initial support for OCaml 5.5.0 (#2197, #2220)
  • Compiler: OxCaml support (#2105, #2225)
  • Compiler: new variable coalescing pass, plus faster variable-naming,
    free-variable and shape-computation passes (#2166, #2321, #2198)
  • Compiler: add the --build-config and --apply-build-config flags (#2177)
  • Compiler: put more values into global variables (#2211)
  • Compiler: cosmetic minification in compact mode — !0/!1 booleans,
    drop the leading 0 in 0.x fractions, normalise exponents
    (1e+051e5), and pick backtick strings when they reduce escapes;
    --pretty output is unchanged (#1117)
  • Wasm: dynlink and toplevel support (#2186)
  • Compiler/wasm: WASI 0.1 support (#1831)
  • Wasm_of_ocaml: alternative effect implementation based on the Stack
    Switching proposal (#2189)
  • Runtime/wasm: implement the legacy num library nat primitives
    (previously no-op stubs), so arbitrary-precision integers and rationals
    now work as on the JavaScript runtime (#2263)
  • Runtime/wasm: faster string↔ArrayBuffer copies, faster small-string
    conversions, and optimized bigstring primitives (#2124, #2144)
  • Runtime/wasm: pure-Wasm zstd and BLAKE2b implementations; the runtime
    no longer relies on the JavaScript zstd/BLAKE2 shims to unmarshal
    compressed values or compute Digest.BLAKE512/256/128. This also makes
    both available under the WASI target, which has no JavaScript (#2249)
  • Runtime: initial support for quickjs-ng (#2229)
  • Lib: add Promise — type-safe bindings to JavaScript promises (even for
    'a Promise.t Promise.t), with Lwt interop in Js_of_ocaml_lwt.Promise
    (to_lwt/of_lwt) and Promise-typed Dom_html bindings
    (requestFullscreen, requestPointerLock, exitFullscreen,
    mediaElement.play, imageElement.decode, Animation.{finished,ready}).
    Breaking: mediaElement.play now returns unit Promise.t (#2031)
  • Lib: add Fetch and Abort — Fetch API binding with a typed
    AbortController/AbortSignal primitive for cancellation (#596)
  • Lib: many additional Dom_html bindings and a new Performance module
    (#2221, #2248)
  • Lib: add Console bindings for table, count, countReset and
    timeLog (#2350)
  • Lib: align Dom_svg with SVG 2 — new graphicsElement/geometryElement
    parents, style/className/dataset merged into element, SVG 2
    members, markerElement and the full SVGFE* filter-primitive family,
    every SVG element is now an event target (#519), and prop/readonly_prop
    fixes. Breaking: drops the SVG 1.1-only getTransformToElement;
    nearestViewportElement/farthestViewportElement are now typed optdef
  • Lib: implement the popover API (#1734)
  • Lib: add Intl.RelativeTimeFormat (#2070)
  • Lib: remove dead legacy-browser code from the DOM bindings (IE
    attachEvent/createElement/cancelBubble fallbacks, prefixed
    requestAnimationFrame, the Firefox 3.x File.fileName property).
    Breaking: drops the obsolete Gecko MouseScrollEvent/_DOMMouseScroll
    bindings — the mouseScrollEvent type, the MouseScrollEvent
    taggedEvent variant, CoerceTo.mouseScrollEvent and
    Event._DOMMouseScroll (#2350)

Bug fixes

  • Compiler: don't rewrite x = e + x into x += e for + (not
    commutative on strings), which reversed Filename.concat operands and
    broke Filename.temp_file in whole-program builds (#2228)
  • Compiler: fix the dead require() guard in share_constant (it matched
    "requires"), which could replace require string arguments and confuse
    bundlers (#2284)
  • Compiler: parenthesize in in conditional else-branches, arrow concise
    bodies and for-initializer yields when re-printing parsed JavaScript,
    which previously emitted output that did not parse (#2282)
  • Compiler: emit a flat dispatch loop instead of deeply nested labelled
    blocks for many sibling merge targets, avoiding parser "too much
    recursion" overflows (#2122)
  • Compiler: avoid JS stack overflow on deep mutually-recursive direct-style
    calls under --effects=double-translation (#2243)
  • Compiler: fix reference unboxing (#2210), a missing conditional
    simplification (#2217), Js_assign.simpl (#2218), and UGEINT lowering
  • Compiler/wasm: fix the int-division return type (#2197), preserve the
    physical identity of empty closures (#2207), and fix a crash on some
    function calls (#2208)
  • Runtime: hashing is now consistent across backends — JS strings with code
    points above U+00FF mix two 16-bit units per word, Hashtbl.hash of float
    arrays, bigarray tail zero-extension and float32_hash normalize like
    native; ASCII/Latin-1 strings are unchanged (#2263, #2270, #2332)
  • Runtime/wasm: bring many primitives in line with the JavaScript runtime —
    caml_wrap_exception only wraps real Errors, caml_js_meth_call
    decodes method names as UTF-8, the exception formatter grows its buffer,
    Sys.is_directory/file_exists follow symlinks, isatty returns false
    in browsers, caml_seek_in validates the destination, Array.make/
    Obj.new_block build proper float arrays, caml_unregister_named_value
    handles non-head bucket entries, the lexer only moves position memory on
    memory-action transitions, the bytecode-section accessors raise without
    --toplevel, format-string #/%+f/% f corner cases, and
    Condition.wait is a no-op with each condition variable having a distinct
    identity (#2263)
  • Runtime: marshalling fixes on both backends — Marshal.to_buffer returns
    the byte count; float arrays use CODE_DOUBLE_ARRAY (readable by native
    and Wasm); BLOCK32 sizes are decoded with an unsigned shift (≥ 2^21 fields
    no longer truncated) and a block with ≥ 2^22 fields raises instead of
    truncating; input_value on a bad object raises Failure; bigarray
    deserialization rejects bad dimensions; big-endian double arrays are
    registered in the object table (#2263, #2270)
  • Runtime: filesystem fixes (#2270) — the fake device no longer destroys a
    directory renamed into its own subtree, refuses to unlink directories,
    honors Open_append (which now implies write access), reports proper Unix
    error codes/syscalls/paths, no longer matches mount points as regexes,
    raises Sys_error on cross-device renames, keeps file sizes 64-bit on the
    node backend, and no longer deletes a file renamed onto itself; flush on
    a closed channel no longer raises
  • Runtime: O_APPEND/Open_append matches native on both backends — the
    file offset starts at 0 (so lseek/pos_out report 0 right after opening)
    and every write goes to the end of the file, even after seeking backwards
    (#2306)
  • Runtime: an empty path raises ENOENT on the JavaScript backend like
    native (and the Wasm runtime), so Unix.stat "", Unix.opendir "", etc.
    raise instead of operating on the cwd, and Sys.file_exists "" is false
    (#2354)
  • Runtime: Unix fixes — Unix.localtime computes tm_yday from the date
    (was off by one during DST) and reaches Intl safely; Unix.close frees
    the fd-table slot; Unix.error_message no longer crashes on unknown codes
    or node < 22; chmod raises Unix_error; readdir includes "." and
    "..", and add Unix.getegid / fix the Unix.getgrgid export (#2263,
    #2270, #2303, #2304)
  • Runtime: channel fixes — in_channel_of_descr/out_channel_of_descr
    allocate fresh channels (they used to share a record and loop on reads);
    refill-hook channels grow their buffer and keep pos_in/pos_out
    correct; Sys.command returns the child exit status; Sys.getenv raises
    on prototype names; Sys.isatty consults the channel's file (#2270, #2330)
  • Runtime: Str engine fixes — SIMPLEOPT/STAR/PLUS no longer read past the
    end of the string (a trailing negated class could loop forever),
    instruction arguments are no longer masked to 8 bits (regexps with > 256
    pool entries mis-indexed), and a Str.replace backreference one past the
    last group raises instead of trapping (#2263, #2270)
  • Runtime: ephemeron/weak fixes — blit_key, blit_data, get_data,
    get_copy and get_data_copy corrected (no clobbering, copy bytes and
    float arrays, no traps on JS-valued data); data is weakly keyed on the key
    object so key↔data cycles can be collected; Gc.finalise_last runs under
    --effects=cps; Gc.counters returns a plain tuple (#2263, #2270, #2274,
    #2279)
  • Runtime: numeric fixes — Digest/MD5 correct for inputs ≥ 2 GiB;
    Int64.shift_right for negatives with shift counts 41–47;
    Int64.of_string (#2223); Printf "%#x" 0 prints 0; float16 bigarray
    NaN comparison; comparing an immediate against a custom block no longer
    throws and orders correctly; Float.Array.sub/append/concat return
    tag-254 arrays; caml_bigstring_blit_* treat positions as raw offsets;
    compare_nat reads only the common digit length (#2263, #2270)
  • Runtime: float formatting and parsing — the exact decimal expansion is
    printed beyond toFixed/toExponential's limits (%.150e, %f of values
    ≥ 1e21); hex-float literals parse with correct rounding, saturate huge
    exponents instead of wrapping, and reject non-decimal/JavaScript literals;
    ldexp rounds once into the subnormal range; and float_of_string skips
    all leading whitespace (#2263, #2270)
  • Runtime: caml_float16_of_double rounds through float32 like native, so
    float16 tie values agree across the js, wasm and native backends; and
    Unix.getuid/geteuid/getgid/getegid return the real ids on Node (the
    WASI build keeps 1) (#2280)
  • Runtime: Graphics backend fixes (#2270) — consistent bottom-left pixel
    origin across all primitives, correct draw_arc quadrant, synchronous
    first draw_image, fill_rect paints the far edges, pie-slice fill_arc,
    half-pixel-centred strokes/fills for crisp lines, and round caps/joins,
    matching the native X11 backend
  • Runtime: Domain.spawn of a raising body now succeeds and Domain.join
    re-raises (with the Finished payload layout expected per OCaml version),
    instead of corrupting the domain id and termination mutex (#2263, #2270,
    #2302)
  • Runtime: caml_dynlink_open_lib drops the mode argument on OCaml ≥ 5.1
    and returns the filled library-slot index (#2270)
  • Runtime: misc runtime-review fixes — Runtime_events.User.register
    orders typ/tag correctly and the cursor primitives are renamed
    caml_ml_runtime_events_*; jsoo_effect_not_supported is provided only
    when effects are disabled; Blake2.create truncates an over-long key;
    OCAMLRUNPARAM backtrace parsing is last-wins; fix caml_oo_cache_id
    (#2224) and JS→OCaml string conversion (#2230) (#2263, #2270)
  • Lib: binding fixes (#2350) — CSS.Angle parses integer angles such as
    "45deg"; CSS.Color rejects empty channels ("rgb(,,)");
    IntersectionObserver.takeRecords is wrapped in Js.t; EventSource
    onopen/onerror receive a plain Dom.event; Intl.Collator.compare
    returns Js.number_t; Dom.attr.ownerElement is typed element t opt readonly_prop; Regexp.replace_first preserves all flags except g
    (adds a flags accessor)
  • Lib: fix method-name mangling — Typed_array._BYTES_PER_ELEMENT_,
    WebGL._MAX_RENDERBUFFER_SIZE_ and canvasElement.toDataURL_compression
    resolved to the wrong JavaScript identifiers (#2239)
  • Lib: defer Intl.{Collator,DateTimeFormat,...} member lookups so the
    module no longer throws at load time when globalThis.Intl is undefined
    (#2229)
  • Lib: fix onbeforeunload breaking navigation (#1436) — the
    event_listener return type is now bool t optdef (undefined means "no
    opinion"), with new Dom.listener/full_listener and a typed
    beforeUnloadEvent
  • Lib: fix several Dom_html bindings (#2221)
  • Lib: Deriving_Json now round-trips non-finite floats — the writer emits
    NaN/Infinity/-Infinity (matching the reader) instead of OCaml's
    nan/inf/-inf, which the reader rejected (#2365)
  • Lib: drop a stray console.log fired on every event in
    Lwt_js_events.mousewheel (#2365)
  • Lib: Lwt_file read functions now fail the thread with an exception on a
    read error or abort instead of raising assert false (#2365)
  • Lib: Lwt_xmlHttpRequest frame content_xml returns None for non-default
    response types (text/json/blob/arraybuffer/document) instead of raising
    assert false (#2365)
  • Lib: Lwt_js_events.request_animation_frame is now cancellable — cancelling
    the thread cancels the pending animation-frame callback (#2365)

Don't miss a new js_of_ocaml release

NewReleases is sending notifications on new releases.