[new release] js_of_ocaml (8 packages) (6.4.0)#30088
Merged
Merged
Conversation
CHANGES: ## Features/Changes * Compiler: initial support for OCaml 5.5.0 (ocsigen/js_of_ocaml#2197, ocsigen/js_of_ocaml#2220) * Compiler: OxCaml support (ocsigen/js_of_ocaml#2105, ocsigen/js_of_ocaml#2225) * Compiler: new variable coalescing pass, plus faster variable-naming, free-variable and shape-computation passes (ocsigen/js_of_ocaml#2166, ocsigen/js_of_ocaml#2321, ocsigen/js_of_ocaml#2198) * Compiler: add the `--build-config` and `--apply-build-config` flags (ocsigen/js_of_ocaml#2177) * Compiler: put more values into global variables (ocsigen/js_of_ocaml#2211) * Compiler: cosmetic minification in compact mode — `!0`/`!1` booleans, drop the leading `0` in `0.x` fractions, normalise exponents (`1e+05` → `1e5`), and pick backtick strings when they reduce escapes; `--pretty` output is unchanged (ocsigen/js_of_ocaml#1117) * Wasm: dynlink and toplevel support (ocsigen/js_of_ocaml#2186) * Compiler/wasm: WASI 0.1 support (ocsigen/js_of_ocaml#1831) * Wasm_of_ocaml: alternative effect implementation based on the Stack Switching proposal (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263) * Runtime/wasm: faster string↔ArrayBuffer copies, faster small-string conversions, and optimized bigstring primitives (ocsigen/js_of_ocaml#2124, ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2249) * Runtime: initial support for quickjs-ng (ocsigen/js_of_ocaml#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` (ocsigen/js_of_ocaml#2031) * Lib: add `Fetch` and `Abort` — Fetch API binding with a typed `AbortController`/`AbortSignal` primitive for cancellation (ocsigen/js_of_ocaml#596) * Lib: many additional `Dom_html` bindings and a new `Performance` module (ocsigen/js_of_ocaml#2221, ocsigen/js_of_ocaml#2248) * Lib: add `Console` bindings for `table`, `count`, `countReset` and `timeLog` (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#1734) * Lib: add `Intl.RelativeTimeFormat` (ocsigen/js_of_ocaml#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` (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2228) * Compiler: fix the dead `require()` guard in share_constant (it matched "requires"), which could replace `require` string arguments and confuse bundlers (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2282) * Compiler: emit a flat dispatch loop instead of deeply nested labelled blocks for many sibling merge targets, avoiding parser "too much recursion" overflows (ocsigen/js_of_ocaml#2122) * Compiler: avoid JS stack overflow on deep mutually-recursive direct-style calls under `--effects=double-translation` (ocsigen/js_of_ocaml#2243) * Compiler: fix reference unboxing (ocsigen/js_of_ocaml#2210), a missing conditional simplification (ocsigen/js_of_ocaml#2217), `Js_assign.simpl` (ocsigen/js_of_ocaml#2218), and UGEINT lowering * Compiler/wasm: fix the int-division return type (ocsigen/js_of_ocaml#2197), preserve the physical identity of empty closures (ocsigen/js_of_ocaml#2207), and fix a crash on some function calls (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#2270, ocsigen/js_of_ocaml#2332) * Runtime/wasm: bring many primitives in line with the JavaScript runtime — `caml_wrap_exception` only wraps real `Error`s, `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 (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#2270) * Runtime: filesystem fixes (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#2270, ocsigen/js_of_ocaml#2303, ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2270, ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#2270, ocsigen/js_of_ocaml#2274, ocsigen/js_of_ocaml#2279) * Runtime: numeric fixes — `Digest`/MD5 correct for inputs ≥ 2 GiB; `Int64.shift_right` for negatives with shift counts 41–47; `Int64.of_string` (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#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`) (ocsigen/js_of_ocaml#2280) * Runtime: Graphics backend fixes (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#2270, ocsigen/js_of_ocaml#2302) * Runtime: `caml_dynlink_open_lib` drops the `mode` argument on OCaml ≥ 5.1 and returns the filled library-slot index (ocsigen/js_of_ocaml#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` (ocsigen/js_of_ocaml#2224) and JS→OCaml string conversion (ocsigen/js_of_ocaml#2230) (ocsigen/js_of_ocaml#2263, ocsigen/js_of_ocaml#2270) * Lib: binding fixes (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2239) * Lib: defer `Intl.{Collator,DateTimeFormat,...}` member lookups so the module no longer throws at load time when `globalThis.Intl` is undefined (ocsigen/js_of_ocaml#2229) * Lib: fix `onbeforeunload` breaking navigation (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#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 (ocsigen/js_of_ocaml#2365) * Lib: drop a stray `console.log` fired on every event in `Lwt_js_events.mousewheel` (ocsigen/js_of_ocaml#2365) * Lib: `Lwt_file` read functions now fail the thread with an exception on a read error or abort instead of raising `assert false` (ocsigen/js_of_ocaml#2365) * Lib: `Lwt_xmlHttpRequest` frame `content_xml` returns `None` for non-default response types (text/json/blob/arraybuffer/document) instead of raising `assert false` (ocsigen/js_of_ocaml#2365) * Lib: `Lwt_js_events.request_animation_frame` is now cancellable — cancelling the thread cancels the pending animation-frame callback (ocsigen/js_of_ocaml#2365)
hhugo
force-pushed
the
release-js_of_ocaml-6.4.0
branch
from
June 21, 2026 14:58
a707459 to
b2374ac
Compare
eliom 12.0.0/12.0.1 do not build against js_of_ocaml 6.4.0: the DOM bindings changed (getElementsByTagName now returns a Dom.collection, and Dom_html gained a `listener` value that shadows a local binding). Fixed in eliom master (ocsigen/eliom#873); cap the existing releases until a compatible eliom is published.
These releases do not build against js_of_ocaml 6.4.0 with their test suite enabled: the tests open Js_of_ocaml and use the unqualified module name Promise, which now resolves to the new Js_of_ocaml.Promise module (added in 6.4.0) instead of promise_jsoo's own, causing a type error in Promise.then_. The library itself still installs, but opam install --with-test (as run by the revdep CI) fails. Fixed since promise_jsoo 0.4.0, which dropped js_of_ocaml-ppx and no longer opens Js_of_ocaml (0.4.2/0.4.3 build fine); cap the older releases until they are no longer needed.
smorimoto
force-pushed
the
release-js_of_ocaml-6.4.0
branch
from
June 22, 2026 08:05
6ba0d21 to
0da0436
Compare
hhugo
force-pushed
the
release-js_of_ocaml-6.4.0
branch
from
June 22, 2026 08:11
d7a0d76 to
6ba0d21
Compare
6.0.1 declared a continuous "ocaml" {>= "4.08" & < "5.4"} range, dropping
the "< 4.14.3" cutout that 5.9.1 and every earlier version carry. js_of_ocaml
< 6.1 does not build on the OCaml 4.14.3+ patch line (Instruct.compilation_env
lost its ce_rec field, breaking parse_bytecode.ml). Restore the cutout so the
metadata matches 5.9.0; this also fixes the promise_jsoo lower-bounds revdep,
which was selecting 6.0.1 with OCaml 4.14.3.
promise_jsoo_lwt 0.4.x uses Promise.error as a public Ojs.t alias (introduced in promise_jsoo 0.4.0; in 0.3.x it is `private Js_of_ocaml.Js.Unsafe.any`). Without a lower bound, opam-repo-ci pairs promise_jsoo_lwt.0.4.x with promise_jsoo.0.3.1 and the test fails to compile ([%js.to: int] on a value of type Promise.error). Add the bound so the revdep test selects a compatible promise_jsoo. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Member
|
Is the failure with the data-encoding revdeps new? |
Contributor
Author
|
no, they appear at every jsoo release |
Member
|
Thanks |
Contributor
Author
|
Contributor
Author
|
Member
|
Yes, working on it |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Compiler from OCaml bytecode to JavaScript
CHANGES:
Features/Changes
free-variable and shape-computation passes (Variable coalescing ocsigen/js_of_ocaml#2166, Compiler: speed up variable naming and free-variable passes (byte-identical) ocsigen/js_of_ocaml#2321, Improved shape computation ocsigen/js_of_ocaml#2198)
--build-configand--apply-build-configflags (--build-config / --apply-build-config ocsigen/js_of_ocaml#2177)!0/!1booleans,drop the leading
0in0.xfractions, normalise exponents(
1e+05→1e5), and pick backtick strings when they reduce escapes;--prettyoutput is unchanged (Improve JS minifier ocsigen/js_of_ocaml#1117)Switching proposal (Wasm native effects (Stack Switching proposal) ocsigen/js_of_ocaml#2189)
numlibrarynatprimitives(previously no-op stubs), so arbitrary-precision integers and rationals
now work as on the JavaScript runtime (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263)
conversions, and optimized bigstring primitives (Optimizations: string conversion and copy to and from arraybuffer ocsigen/js_of_ocaml#2124, Bigstring optimizations ocsigen/js_of_ocaml#2144)
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 (Wasm implementations of zstd / blake2 ocsigen/js_of_ocaml#2249)
Promise— type-safe bindings to JavaScript promises (even for'a Promise.t Promise.t), with Lwt interop inJs_of_ocaml_lwt.Promise(
to_lwt/of_lwt) and Promise-typedDom_htmlbindings(
requestFullscreen,requestPointerLock,exitFullscreen,mediaElement.play,imageElement.decode,Animation.{finished,ready}).Breaking:
mediaElement.playnow returnsunit Promise.t([FEATURE REQUEST] Integrate a Promise API ocsigen/js_of_ocaml#2031)FetchandAbort— Fetch API binding with a typedAbortController/AbortSignalprimitive for cancellation (Provide bindings to the Fetch API ocsigen/js_of_ocaml#596)Dom_htmlbindings and a newPerformancemodule(Dom updates ocsigen/js_of_ocaml#2221, Lib: introduce breaking changes in Dom and Dom_html modules ocsigen/js_of_ocaml#2248)
Consolebindings fortable,count,countResetandtimeLog(Review-driven fixes and cleanups in lib/js_of_ocaml ocsigen/js_of_ocaml#2350)Dom_svgwith SVG 2 — newgraphicsElement/geometryElementparents,
style/className/datasetmerged intoelement, SVG 2members,
markerElementand the fullSVGFE*filter-primitive family,every SVG element is now an event target ([FEATURE REQUEST] Svg elements or not compatible with eventTarget ocsigen/js_of_ocaml#519), and
prop/readonly_propfixes. Breaking: drops the SVG 1.1-only
getTransformToElement;nearestViewportElement/farthestViewportElementare now typedoptdefpopoverAPI. ocsigen/js_of_ocaml#1734)Intl.RelativeTimeFormat(Add Intl.RelativeTimeFormat ocsigen/js_of_ocaml#2070)attachEvent/createElement/cancelBubblefallbacks, prefixedrequestAnimationFrame, the Firefox 3.xFile.fileNameproperty).Breaking: drops the obsolete Gecko
MouseScrollEvent/_DOMMouseScrollbindings — the
mouseScrollEventtype, theMouseScrollEventtaggedEventvariant,CoerceTo.mouseScrollEventandEvent._DOMMouseScroll(Review-driven fixes and cleanups in lib/js_of_ocaml ocsigen/js_of_ocaml#2350)Bug fixes
x = e + xintox += efor+(notcommutative on strings), which reversed
Filename.concatoperands andbroke
Filename.temp_filein whole-program builds (Compiler: don't rewrite [x = e + x] as [x += e] for Plus ocsigen/js_of_ocaml#2228)require()guard in share_constant (it matched"requires"), which could replace
requirestring arguments and confusebundlers (Compiler: fix dead require() guard in share_constant ocsigen/js_of_ocaml#2284)
inin conditional else-branches, arrow concisebodies and
for-initializer yields when re-printing parsed JavaScript,which previously emitted output that did not parse (js_output: the
in-operator check misses conditional branches and arrow bodies (invalid output in for-init) ocsigen/js_of_ocaml#2282)blocks for many sibling merge targets, avoiding parser "too much
recursion" overflows ([BUG] Stack overflow in some web browsers for an ocaml program that uses menhir to generate its parser ocsigen/js_of_ocaml#2122)
calls under
--effects=double-translation(Avoid stack overflow on deep mutual recursion under --effects=double-translation ocsigen/js_of_ocaml#2243)simplification (Deadcode elimination: fix missing conditional simplification ocsigen/js_of_ocaml#2217),
Js_assign.simpl(Js_traverse.simpl: fix optimization ordering ocsigen/js_of_ocaml#2218), and UGEINT loweringphysical identity of empty closures (Preserve physical identity of empty closures ocsigen/js_of_ocaml#2207), and fix a crash on some
function calls (Wasm: guard direct calls against stale global data flow data ocsigen/js_of_ocaml#2208)
points above U+00FF mix two 16-bit units per word,
Hashtbl.hashof floatarrays, bigarray tail zero-extension and
float32_hashnormalize likenative; ASCII/Latin-1 strings are unchanged (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270, Runtime/wasm: normalize -0.0 and NaN in float32_hash ocsigen/js_of_ocaml#2332)
caml_wrap_exceptiononly wraps realErrors,caml_js_meth_calldecodes method names as UTF-8, the exception formatter grows its buffer,
Sys.is_directory/file_existsfollow symlinks,isattyreturns falsein browsers,
caml_seek_invalidates the destination,Array.make/Obj.new_blockbuild proper float arrays,caml_unregister_named_valuehandles non-head bucket entries, the lexer only moves position memory on
memory-action transitions, the bytecode-section accessors raise without
--toplevel, format-string#/%+f/% fcorner cases, andCondition.waitis a no-op with each condition variable having a distinctidentity (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263)
Marshal.to_bufferreturnsthe byte count; float arrays use
CODE_DOUBLE_ARRAY(readable by nativeand 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_valueon a bad object raisesFailure; bigarraydeserialization rejects bad dimensions; big-endian double arrays are
registered in the object table (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270)
directory renamed into its own subtree, refuses to unlink directories,
honors
Open_append(which now implies write access), reports proper Unixerror codes/syscalls/paths, no longer matches mount points as regexes,
raises
Sys_erroron cross-device renames, keeps file sizes 64-bit on thenode backend, and no longer deletes a file renamed onto itself;
flushona closed channel no longer raises
O_APPEND/Open_appendmatches native on both backends — thefile offset starts at 0 (so
lseek/pos_outreport 0 right after opening)and every write goes to the end of the file, even after seeking backwards
(Runtime: make Unix.openfile O_APPEND offset match native (JS and Wasm) ocsigen/js_of_ocaml#2306)
ENOENTon the JavaScript backend likenative (and the Wasm runtime), so
Unix.stat "",Unix.opendir "", etc.raise instead of operating on the cwd, and
Sys.file_exists ""is false(Runtime: empty path raises ENOENT on the JS backend + fix lint-fmt ocsigen/js_of_ocaml#2354)
Unix.localtimecomputestm_ydayfrom the date(was off by one during DST) and reaches
Intlsafely;Unix.closefreesthe fd-table slot;
Unix.error_messageno longer crashes on unknown codesor node < 22;
chmodraisesUnix_error;readdirincludes "." and"..", and add
Unix.getegid/ fix theUnix.getgrgidexport (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263,JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270, Runtime: Unix.close removes the descriptor from the fd table ocsigen/js_of_ocaml#2303, Runtime: fix Unix.localtime tm_yday during DST and tm_isdst for Europe/Dublin ocsigen/js_of_ocaml#2304)
in_channel_of_descr/out_channel_of_descrallocate fresh channels (they used to share a record and loop on reads);
refill-hook channels grow their buffer and keep
pos_in/pos_outcorrect;
Sys.commandreturns the child exit status;Sys.getenvraiseson prototype names;
Sys.isattyconsults the channel's file (JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270, Runtime/wasm: grow buffer and advance offset on hook refill ocsigen/js_of_ocaml#2330)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.replacebackreference one past thelast group raises instead of trapping (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270)
blit_key,blit_data,get_data,get_copyandget_data_copycorrected (no clobbering, copy bytes andfloat arrays, no traps on JS-valued data); data is weakly keyed on the key
object so key↔data cycles can be collected;
Gc.finalise_lastruns under--effects=cps;Gc.countersreturns a plain tuple (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270, Runtime: key ephemeron data WeakMaps on the key object ocsigen/js_of_ocaml#2274,Runtime: fix Gc.finalise_last under effects and Gc.counters representation ocsigen/js_of_ocaml#2279)
Digest/MD5 correct for inputs ≥ 2 GiB;Int64.shift_rightfor negatives with shift counts 41–47;Int64.of_string(Fix Int64.of_string ocsigen/js_of_ocaml#2223);Printf "%#x" 0prints0; float16 bigarrayNaN comparison; comparing an immediate against a custom block no longer
throws and orders correctly;
Float.Array.sub/append/concatreturntag-254 arrays;
caml_bigstring_blit_*treat positions as raw offsets;compare_natreads only the common digit length (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270)printed beyond
toFixed/toExponential's limits (%.150e,%fof values≥ 1e21); hex-float literals parse with correct rounding, saturate huge
exponents instead of wrapping, and reject non-decimal/JavaScript literals;
ldexprounds once into the subnormal range; andfloat_of_stringskipsall leading whitespace (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270)
caml_float16_of_doublerounds throughfloat32like native, sofloat16tie values agree across the js, wasm and native backends; andUnix.getuid/geteuid/getgid/getegidreturn the real ids on Node (theWASI build keeps
1) (Runtime: float correctness fixes across the JS and Wasm runtimes (#2263, #2270) ocsigen/js_of_ocaml#2280)origin across all primitives, correct
draw_arcquadrant, synchronousfirst
draw_image,fill_rectpaints the far edges, pie-slicefill_arc,half-pixel-centred strokes/fills for crisp lines, and round caps/joins,
matching the native X11 backend
Domain.spawnof a raising body now succeeds andDomain.joinre-raises (with the
Finishedpayload layout expected per OCaml version),instead of corrupting the domain id and termination mutex (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270,
Runtime: store Domain.spawn error using the version's state layout ocsigen/js_of_ocaml#2302)
caml_dynlink_open_libdrops themodeargument on OCaml ≥ 5.1and returns the filled library-slot index (JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270)
Runtime_events.User.registerorders
typ/tagcorrectly and the cursor primitives are renamedcaml_ml_runtime_events_*;jsoo_effect_not_supportedis provided onlywhen effects are disabled;
Blake2.createtruncates an over-long key;OCAMLRUNPARAMbacktrace parsing is last-wins; fixcaml_oo_cache_id(Fix caml_oo_cache_id ocsigen/js_of_ocaml#2224) and JS→OCaml string conversion (String conversion fix ocsigen/js_of_ocaml#2230) (Wasm runtime: correctness bugs found in a review of the .wat files ocsigen/js_of_ocaml#2263, JS runtime: correctness bugs found in a review of runtime/js ocsigen/js_of_ocaml#2270)
CSS.Angleparses integer angles such as"45deg";CSS.Colorrejects empty channels ("rgb(,,)");IntersectionObserver.takeRecordsis wrapped inJs.t;EventSourceonopen/onerrorreceive a plainDom.event;Intl.Collator.comparereturns
Js.number_t;Dom.attr.ownerElementis typedelement t opt readonly_prop;Regexp.replace_firstpreserves all flags exceptg(adds a
flagsaccessor)Typed_array._BYTES_PER_ELEMENT_,WebGL._MAX_RENDERBUFFER_SIZE_andcanvasElement.toDataURL_compressionresolved to the wrong JavaScript identifiers (Lib: add Promise + Fetch bindings (#2031, #596) ocsigen/js_of_ocaml#2239)
Intl.{Collator,DateTimeFormat,...}member lookups so themodule no longer throws at load time when
globalThis.Intlis undefined(Add QuickJS-NG support ocsigen/js_of_ocaml#2229)
onbeforeunloadbreaking navigation ([BUG] semantics of (onbeforeunload, Dom_html.handler) incompatible with major browsers ocsigen/js_of_ocaml#1436) — theevent_listenerreturn type is nowbool t optdef(undefinedmeans "noopinion"), with new
Dom.listener/full_listenerand a typedbeforeUnloadEventDom_htmlbindings (Dom updates ocsigen/js_of_ocaml#2221)Deriving_Jsonnow round-trips non-finite floats — the writer emitsNaN/Infinity/-Infinity(matching the reader) instead of OCaml'snan/inf/-inf, which the reader rejected (Lib/doc/examples: deriving_json + Lwt edge-case fixes, manual corrections, toplevel Wasm fallback ocsigen/js_of_ocaml#2365)console.logfired on every event inLwt_js_events.mousewheel(Lib/doc/examples: deriving_json + Lwt edge-case fixes, manual corrections, toplevel Wasm fallback ocsigen/js_of_ocaml#2365)Lwt_fileread functions now fail the thread with an exception on aread error or abort instead of raising
assert false(Lib/doc/examples: deriving_json + Lwt edge-case fixes, manual corrections, toplevel Wasm fallback ocsigen/js_of_ocaml#2365)Lwt_xmlHttpRequestframecontent_xmlreturnsNonefor non-defaultresponse types (text/json/blob/arraybuffer/document) instead of raising
assert false(Lib/doc/examples: deriving_json + Lwt edge-case fixes, manual corrections, toplevel Wasm fallback ocsigen/js_of_ocaml#2365)Lwt_js_events.request_animation_frameis now cancellable — cancellingthe thread cancels the pending animation-frame callback (Lib/doc/examples: deriving_json + Lwt edge-case fixes, manual corrections, toplevel Wasm fallback ocsigen/js_of_ocaml#2365)