From f6cb9b6ba674e61431a81d8f801e0a6c021beb92 Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Glondu?= Date: Sat, 11 Jan 2025 13:04:32 +0100 Subject: [PATCH] New upstream version 5.2.1 --- .github/workflows/build.yml | 32 +- .github/workflows/hygiene.yml | 2 +- .github/workflows/stale.yml | 18 - Changes | 457 ++++++++++-------- VERSION | 2 +- appveyor.yml | 2 + asmcomp/power/emit.mlp | 3 +- boot/ocamlc | Bin 3233094 -> 3233124 bytes boot/ocamllex | Bin 402271 -> 402305 bytes build-aux/ocaml_version.m4 | 2 +- configure | 34 +- configure.ac | 2 +- dune | 7 +- manual/src/cmds/intf-c.etex | 5 +- ocaml-variants.opam | 50 +- .../runtime_events/runtime_events_consumer.c | 13 +- otherlibs/systhreads/Makefile | 1 + otherlibs/unix/chmod.c | 7 +- otherlibs/unix/mkdir.c | 7 +- otherlibs/unix/mkfifo.c | 14 +- otherlibs/unix/open_unix.c | 7 +- otherlibs/unix/read_unix.c | 7 +- otherlibs/unix/socketpair_win32.c | 15 +- otherlibs/unix/truncate_unix.c | 7 +- otherlibs/unix/truncate_win32.c | 7 +- otherlibs/unix/write_unix.c | 7 +- runtime/arm64.S | 6 +- runtime/callback.c | 49 +- runtime/caml/interp.h | 12 +- runtime/finalise.c | 2 +- runtime/gc_ctrl.c | 14 +- runtime/interp.c | 11 +- runtime/power.S | 12 +- runtime/riscv.S | 6 +- runtime/s390x.S | 5 +- runtime/sys.c | 7 +- stdlib/gc.ml | 10 +- testsuite/tests/callback/test1.ml | 13 + testsuite/tests/callback/test1.reference | 1 + testsuite/tests/callback/test1_.c | 5 + testsuite/tests/callback/test_gc_alarm.ml | 14 + tools/ci/actions/canonicalize-dumpbin.awk | 87 ++++ tools/ci/actions/check-typo.sh | 4 +- tools/ci/actions/runner.sh | 62 ++- tools/ci/appveyor/appveyor_build.cmd | 8 +- tools/ci/appveyor/appveyor_build.sh | 9 +- 46 files changed, 673 insertions(+), 372 deletions(-) delete mode 100644 .github/workflows/stale.yml create mode 100644 testsuite/tests/callback/test_gc_alarm.ml create mode 100644 tools/ci/actions/canonicalize-dumpbin.awk diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 03d95cc5..fbc58f89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,11 +11,13 @@ on: # Restrict the GITHUB_TOKEN permissions: {} -# List of test directories for the debug-s4096 and linux-O0 jobs. -# These directories are selected because of their tendencies to reach corner -# cases in the runtime system. env: + # List of test directories for the debug-s4096 and linux-O0 jobs. These + # directories are selected because of their tendencies to reach corner cases + # in the runtime system. PARALLEL_TESTS: parallel callback gc-roots weak-ephe-final + # Fully print commands executed by Make + # MAKEFLAGS: V=1 # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency # Concurrent workflows are grouped by the PR or branch that triggered them @@ -37,7 +39,7 @@ jobs: manual_changed: ${{ steps.manual.outputs.manual_changed }} steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false - name: Check for manual changes @@ -64,7 +66,7 @@ jobs: - name: Prepare Artifact run: tar --zstd -cf /tmp/sources.tar.zstd . - name: Upload Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: compiler path: /tmp/sources.tar.zstd @@ -92,7 +94,7 @@ jobs: name: extra (debug-s4096) steps: - name: Download Artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: compiler - name: Unpack Artifact @@ -150,15 +152,17 @@ jobs: - name: linux-O0 os: ubuntu-latest config_arg: CFLAGS='-O0' - - name: macos - os: macos-latest + - name: macos-x86_64 + os: macos-13 + - name: macos-arm64 + os: macos-14 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false - name: OS Dependencies - if: runner.os == 'MacOS' + if: runner.os == 'macOS' run: brew install parallel - name: configure tree run: | @@ -190,15 +194,17 @@ jobs: run: | apt-get update apt-get install -y git gcc make parallel + adduser --disabled-password --gecos '' ocaml - name: Checkout # See https://github.com/actions/checkout/issues/334 uses: actions/checkout@v1 - name: configure tree run: | - MAKE_ARG=-j bash -xe tools/ci/actions/runner.sh configure + chown -R ocaml:ocaml . + MAKE_ARG=-j su ocaml -c "bash -xe tools/ci/actions/runner.sh configure" - name: Build run: | - MAKE_ARG=-j bash -xe tools/ci/actions/runner.sh build + MAKE_ARG=-j su ocaml -c "bash -xe tools/ci/actions/runner.sh build" - name: Run the testsuite run: | - bash -xe tools/ci/actions/runner.sh test + su ocaml -c "bash -xe tools/ci/actions/runner.sh test" diff --git a/.github/workflows/hygiene.yml b/.github/workflows/hygiene.yml index 777a6b4e..db21dd49 100644 --- a/.github/workflows/hygiene.yml +++ b/.github/workflows/hygiene.yml @@ -28,7 +28,7 @@ jobs: # context variable. if: failure() - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 50 persist-credentials: false diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index bed161e3..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: "Close stale issues" -on: - schedule: - - cron: "15 4 * * 1,3,5" - -jobs: - stale: - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - uses: actions/stale@v8 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.' - days-before-stale: 366 - days-before-close: 30 - exempt-issue-labels: 'bug' diff --git a/Changes b/Changes index 208d5e86..5e0282b9 100644 --- a/Changes +++ b/Changes @@ -1,70 +1,70 @@ -OCaml 5.2.0 ------------- +OCaml 5.2.1 (18 November 2024) +------------------------------ -(Changes that can break existing programs are marked with a "*") +- #13207: Be sure to reload the register caching the exception handler in + caml_c_call and caml_c_call_stack_args, as its value may have been changed + if the OCaml stack is expanded during a callback. + (Miod Vallat, report by Vesa Karvonen, review by Gabriel Scherer and + Xavier Leroy) -### Restored and new backends: +- #13252: Rework register assignment in the interpreter code on m68k on Linux, + due to the %a5 register being used by Glibc. + (Miod Vallat, report by Stéphane Glondu, review by Gabriel Scherer and + Xavier Leroy) -- #12276, #12601: native-code compilation for POWER (64 bits, little-endian) - (Xavier Leroy, review by KC Sivaramakrishnan, Anil Madhavapeddy, - and Stephen Dolan) +- #13268: Fix a call to test in configure.ac that was causing errors when + LDFLAGS contains several words. + (Stéphane Glondu, review by Miod Vallat) -- #12667: extend the latter to POWER 64 bits, big-endian, ELFv2 ABI - (A. Wilcox, review by Xavier Leroy) +- #13234, #13267: Open runtime events file in read-write mode on armel + (armv5) systems due to atomic operations limitations on that + platform. + (Stéphane Glondu, review by Miod Vallat and Vincent Laviron) -### Language features: +- #13188: fix races in the FFI code coming from the use of Int_val(...) + on rooted values inside blocking questions / without the runtime lock. + (Calling Int_val(...) on non-rooted immediates is fine, but any + access to rooted values must be done outside blocking sections / + with the runtime lock.) + (Etienne Millon, review by Gabriel Scherer, Jan Midtgaard, Olivier Nicole) -- #12295, #12568: Give `while true' a polymorphic type, similarly to - `assert false' - (Jeremy Yallop, review by Nicolás Ojeda Bär and Gabriel Scherer, - suggestion by Rodolphe Lepigre and John Whitington) +- #13318: Fix regression in GC alarms, and fix them for flambda. + (Guillaume Munch-Maccagnoni, report by Benjamin Monate, review by + Vincent Laviron and Gabriel Scherer) -- #12315: Use type annotations from arguments in let rec - (Stephen Dolan, review by Gabriel Scherer) +- #13140: POWER back-end: fix issue with call to `caml_call_realloc_stack` + from a DLL + (Xavier Leroy, review by Miod Vallat) -- #11252, RFC 27: Support raw identifier syntax \#foo - (Stephen Dolan, review by David Allsopp, Gabriel Scherer and Olivier Nicole) +- #13370: Fix a low-probability crash when calling Gc.counters. + (Demi Marie Obenour, review by Gabriel Scherer) -- #12044: Add local module open syntax for types. - ``` - module A = struct - type t = int - type r = unit - type s = string - end +- #13402, #13512, #13549, #13553: Revise bytecode implementation of callbacks + so that it no longer produces dangling registered bytecode fragments. + (Xavier Leroy, report by Jan Midtgaard, analysis by Stephen Dolan, + review by Miod Vallat) - type example = A.(t * r * s) - ``` - (Alistair O'Brien, review by Gabriel Scherer, Nicolás Ojeda Bär - and Florian Angeletti) +- #13502: Fix misindexing related to `Gc.finalise_last` that could prevent + finalisers from being run. + (Nick Roberts, review by Mark Shinwell) -- #12456: Document the incompatibility between effects on the one - hand, and `caml_callback` and asynchronous callbacks (signal - handlers, finalisers, memprof callbacks...) on the other hand. - (Guillaume Munch-Maccagnoni, review by KC Sivaramakrishnan) +- #13520: Fix compilation of native-code version of systhreads. Bytecode fields + were being included in the thread descriptors. + (David Allsopp, review by Sébastien Hinderer and Miod Vallat) -- #12375: allow use of [@untagged] for all immediate types like char, bool, - and variant with only constant constructors. - (Christophe Raffalli, review by Gabriel Scherer) +OCaml 5.2.0 (13 May 2024) +------------------------- -* #12502: the compiler now normalizes the newline sequence \r\n to - a single \n character during lexing, to guarantee that the semantics - of newlines in string literals is not modified by Windows tools - transforming \n into \r\n in source files. - Warning 29 [eol-in-string] is not emitted anymore, as the normalization - gives a more robust semantics to newlines in string literals. - (Gabriel Scherer and Damien Doligez, review by Daniel Bünzli, David - Allsopp, Andreas Rossberg, Xavier Leroy, report by Andreas Rossberg) +(Changes that can break existing programs are marked with a "*") -- #13130: minor fixes to pprintast for raw identifiers and local module open - syntax for types. - (Chet Murthy, review by Gabriel Scherer) +### Restored and new backends: -### Type system: +- #12276, #12601: native-code compilation for POWER (64 bits, little-endian) + (Xavier Leroy, review by KC Sivaramakrishnan, Anil Madhavapeddy, + and Stephen Dolan) -- #12313, #11799: Do not re-build as-pattern type when a ground type annotation - is given. This allows to work around problems with GADTs in as-patterns. - (Jacques Garrigue, report by Leo White, review by Gabriel Scherer) +- #12667: extend the latter to POWER 64 bits, big-endian, ELFv2 ABI + (A. Wilcox, review by Xavier Leroy) ### Runtime system: @@ -76,6 +76,12 @@ OCaml 5.2.0 David Allsopp, Miod Vallat, Artem Pianykh, Stephen Dolan, Mark Shinwell and KC Sivaramakrishnan) +- #12114: Add ThreadSanitizer support + (Fabrice Buoro and Olivier Nicole, based on an initial work by Anmol Sahoo, + review by Damien Doligez, Sébastien Hinderer, Jacques-Henri Jourdan, Luc + Maranget, Guillaume Munch-Maccagnoni, Gabriel Scherer) + + - #12850: Update Gc.quick_stat data at the end of major cycles and compaction This PR adds an additional caml_collect_gc_stats_sample_stw to the major heap cycling stw. This means that Gc.quick_stat now actually reflects the state of @@ -140,9 +146,6 @@ OCaml 5.2.0 (Guillaume Munch-Maccagnoni, bug reports and suggestion by Mark Shinwell, review by Nick Barnes and Stephen Dolan) -- #12876: Port ThreadSanitizer support to Linux on POWER - (Miod Vallat, review by Tim McGilchrist) - - #12408: `Domain.spawn` no longer leaks its functional argument for the whole duration of the children domain lifetime. (Guillaume Munch-Maccagnoni, review by Gabriel Scherer) @@ -151,13 +154,10 @@ OCaml 5.2.0 arise at specific locations during domain creation and shutdown. (Guillaume Munch-Maccagnoni, review by Gabriel Scherer) -- #12114: Add ThreadSanitizer support - (Fabrice Buoro and Olivier Nicole, based on an initial work by Anmol Sahoo, - review by Damien Doligez, Sébastien Hinderer, Jacques-Henri Jourdan, Luc - Maranget, Guillaume Munch-Maccagnoni, Gabriel Scherer) - -- #11911, #12381: Restore statmemprof functionality in part - (API changes in Gc.Memprof). (Nick Barnes) +- #11911, #12381: Restore statmemprof functionality in part, with + some API changes in Gc.Memprof. + (Nick Barnes, review by Jacques-Henri Jourdan + and Guillaume Munch-Maccagnoni). - #12430: Simplify dynamic bytecode loading in Meta.reify_bytecode (Stephen Dolan, review by Sébastien Hinderer, Vincent Laviron and Xavier @@ -216,9 +216,10 @@ OCaml 5.2.0 Ojeda Bar) - #11911, #12382, #12383: Restore statmemprof functionality in part - (backtrace buffers, per-thread and per-domain data structures). - (Nick Barnes, review by Gabriel Scherer, Fabrice Buoro, Sadiq - Jaffer, and Guillaume Munch-Maccagnoni). + (backtrace buffers, per-thread and per-domain data structures, + GC/allocation interface). (Nick Barnes, review by Gabriel Scherer, + Fabrice Buoro, Sadiq Jaffer, Guillaume Munch-Maccagnoni, and + Jacques-Henri Jourdan). - #12735: Store both ends of the stack chain in continuations (Leo White, review by Miod Vallat and KC Sivaramakrishnan) @@ -248,6 +249,9 @@ OCaml 5.2.0 Hari Hara Naveen S, reviewed by Fabrice Buoro, Gabriel Scherer and Miod Vallat) +- #12876: Port ThreadSanitizer support to Linux on POWER + (Miod Vallat, review by Tim McGilchrist) + - #12886: Reinitialize IO mutexes after fork (Max Slater, review by Guillaume Munch-Maccagnoni and Xavier Leroy) @@ -261,33 +265,47 @@ OCaml 5.2.0 (Olivier Nicole, suggested by Stephen Dolan, review by Gabriel Scherer, Miod Vallat and Damien Doligez) -### Code generation and optimizations: +### Language features: -- #11239: on x86-64 and RISC-V, reduce alignment of OCaml stacks from 16 to 8. - This reduces stack usage. It's only C stacks that require 16-alignment. - (Xavier Leroy, review by Gabriel Scherer and Stephen Dolan) +- #12295, #12568: Give `while true' a polymorphic type, similarly to + `assert false' + (Jeremy Yallop, review by Nicolás Ojeda Bär and Gabriel Scherer, + suggestion by Rodolphe Lepigre and John Whitington) -- #12311: on POWER, 32-bit FP numbers stored in memory (e.g. in bigarrays) - were not correctly rounded sometimes. - (Xavier Leroy, review by Anil Madhavapeddy and Tim McGilchrist) +- #12044: Add local module open syntax for types. + ``` + module A = struct + type t = int + type r = unit + type s = string + end -- #12551, #12608, #12782, #12596: Overhaul of recursive value compilation. - Non-function recursive bindings are now forbidden from Lambda onwards, - and compiled using a new Value_rec_compiler module. - (Vincent Laviron and Lunia Ayanides, review by Gabriel Scherer, - Stefan Muenzel and Nathanaëlle Courant) + type example = A.(t * r * s) + ``` + (Alistair O'Brien, review by Gabriel Scherer, Nicolás Ojeda Bär + and Florian Angeletti) -- #1809, #12181: rewrite `compare x y op 0` to `x op y` when values are integers - (Xavier Clerc, Stefan Muenzel, review by Gabriel Scherer and Vincent Laviron) +- #11252, RFC 27: Support raw identifier syntax \#foo + (Stephen Dolan, review by David Allsopp, Gabriel Scherer and Olivier Nicole) -- #12825: disable common subexpression elimination for atomic loads... again. - (Gabriel Scherer, review by KC Sivaramakrishnan, Xavier Leroy - and Vincent Laviron, report by Vesa Karvonen) -### Standard library: +- #12315: Use type annotations from arguments in let rec + (Stephen Dolan, review by Gabriel Scherer) -- #12716: Add `Format.pp_print_nothing` function. - (Léo Andrès, review by Gabriel Scherer and Nicolás Ojeda Bär) +- #12375: allow use of [@untagged] for all immediate types like char, bool, + and variant with only constant constructors. + (Christophe Raffalli, review by Gabriel Scherer) + +* #12502: the compiler now normalizes the newline sequence \r\n to + a single \n character during lexing, to guarantee that the semantics + of newlines in string literals is not modified by Windows tools + transforming \n into \r\n in source files. + Warning 29 [eol-in-string] is not emitted anymore, as the normalization + gives a more robust semantics to newlines in string literals. + (Gabriel Scherer and Damien Doligez, review by Daniel Bünzli, David + Allsopp, Andreas Rossberg, Xavier Leroy, report by Andreas Rossberg) + +### Standard library: - #11563: Add the Dynarray module to the stdlib. Dynamic arrays are arrays whose length can be changed by adding or removing elements at @@ -296,6 +314,10 @@ OCaml 5.2.0 Daniel Bünzli, Guillaume Munch-Maccagnoni, Clément Allain, Damien Doligez, Wiktor Kuchta and Pieter Goetschalckx) + +- #12716: Add `Format.pp_print_nothing` function. + (Léo Andrès, review by Gabriel Scherer and Nicolás Ojeda Bär) + * #6732, #12423: Make Buffer.add_substitute surjective and fix its documentation. (Damien Doligez, review by Antonin Décimo) @@ -377,6 +399,35 @@ OCaml 5.2.0 C API. (David Allsopp, review by Nicolás Ojeda Bär and Xavier Leroy) +### Type system: + +- #12313, #11799: Do not re-build as-pattern type when a ground type annotation + is given. This allows to work around problems with GADTs in as-patterns. + (Jacques Garrigue, report by Leo White, review by Gabriel Scherer) + +### Code generation and optimizations: + +- #11239: on x86-64 and RISC-V, reduce alignment of OCaml stacks from 16 to 8. + This reduces stack usage. It's only C stacks that require 16-alignment. + (Xavier Leroy, review by Gabriel Scherer and Stephen Dolan) + +- #12311: on POWER, 32-bit FP numbers stored in memory (e.g. in bigarrays) + were not correctly rounded sometimes. + (Xavier Leroy, review by Anil Madhavapeddy and Tim McGilchrist) + +- #12551, #12608, #12782, #12596: Overhaul of recursive value compilation. + Non-function recursive bindings are now forbidden from Lambda onwards, + and compiled using a new Value_rec_compiler module. + (Vincent Laviron and Lunia Ayanides, review by Gabriel Scherer, + Stefan Muenzel and Nathanaëlle Courant) + +- #1809, #12181: rewrite `compare x y op 0` to `x op y` when values are integers + (Xavier Clerc, Stefan Muenzel, review by Gabriel Scherer and Vincent Laviron) + +- #12825: disable common subexpression elimination for atomic loads... again. + (Gabriel Scherer, review by KC Sivaramakrishnan, Xavier Leroy + and Vincent Laviron, report by Vesa Karvonen) + ### Other libraries: - #12213: Dynlink library, improve legibility of error messages @@ -387,57 +438,73 @@ OCaml 5.2.0 instead of `value`. (Xavier Leroy, review by David Allsopp) -### Tools: +### Compiler user-interface and warnings: -- #12340: testsuite: collect known issues with current -short-paths - implementation for existential types - (Florian Angeletti, Samuel Hym, review by Florian Angeletti and Thomas Refis) +- #11989, #12246, RFC 31: New flag, -H, to allow for transitive dependencies + without including them in the initial environment. + (Chris Casinghino, François Bobot, and Gabriel Scherer, review by Leo White + and Stefan Muenzel, RFC by François Bobot) -- #12147: ocamllex: Allow carriage returns at the end of line directives. - (SeungCheol Jung, review by Nicolás Ojeda Bär) -- #12260: Fix invalid_argument on some external or module aliases in ocamlnat - (Fabian Hemmer, review by Vincent Laviron) +* #10613, #12405: Simplify the values used for the system variable (`system:` in + `ocamlopt -config` or the `Config.system` constant). In particular, s390x and + ppc64 now report "linux" instead of "elf"; all variants of 32-bit ARM on Linux + now report "linux"; OpenBSD now reports "openbsd" instead of "bsd" for 32-bit + ARM; FreeBSD, NetBSD and OpenBSD now report the same value for both x86_64 and + x86_32; x86_32 systems matching *bsd but not freebsd*, netbsd* or openbsd* + are no longer identified (as on x86_64); x86_32 Linux now reports "linux" + instead of "linux_elf". + (David Allsopp, request by Kate Deplaix, review by Sébastien Hinderer and + Xavier Leroy) -- #12185: New script language for ocamltest. - (Damien Doligez with Florian Angeletti, Sébastien Hinderer, Gabriel Scherer, - review by Sébastien Hinderer and Gabriel Scherer) +- #12247: configure: --disable-ocamldebug can now be used instead + of --disable-debugger (which remains available for compatibility) + (Gabriel Scherer, review by Damien Doligez and Sébastien Hinderer) -- #12371: ocamltest: fix recursive expansion of variables. - (Antonin Décimo, Damien Doligez, review by Sébastien Hinderer, - Damien Doligez, Gabriel Scherer, and Xavier Leroy) +- #12199: improve the error message for non-overriding `inherit!` + (Florian Angeletti, review by Jules Aguillon) -* #12497, #12613: Make ocamlc/ocamlopt fail with an error when no - input files are specified to build an executable. - (Antonin Décimo, review by Sébastien Hinderer) +- #12210: uniform style for inline code in compiler messages + (Florian Angeletti, review by Gabriel Scherer) -- #12576: ocamldep: various refactors. - (Antonin Décimo, review by Florian Angeletti, Gabriel Scherer, and Léo Andrès) +* #12278, #:12325: Remove the OCAML_FLEXLINK environment variable from the + compiler drivers. This environment variable was previously used as part of the + FlexDLL bootstrap procedure and existed solely for that purpose. Its removal + greatly simplifies both the build system and testsuite machinery. + (David Allsopp, review by Sébastien Hinderer) -- #12615: ocamldoc: get rid of the odoc_literate and odoc_todo generators. - (Sébaistien Hinderer, review by Gabriel Scherer and Florian Angeletti) +- #12347: error messages: always report missing polyvariant tags + (Florian Angeletti, report by Tianbo Hao, review by Gabriel Scherer) -- #12624: Use $XDG_CONFIG_DIRS in addition to $XDG_CONFIG_HOME when searching - for init.ml and use this to extend init.ml support to the toplevel when - running on Windows. - (David Allsopp, report by Jonah Beckford, review by Nicolás Ojeda Bär and - Antonin Décimo) +- #12224, specialized error message when trying to apply non-functor + module (e.g `module M = Int(Int)`) + (Florian Angeletti, review by Gabriel Scherer) -- #12688: Setting the env variable `NO_COLOR` with an empty value no longer - has effects. Previously, setting `NO_COLOR` with any value, including - the empty value, would disable colors (unless `OCAML_COLOR` is also set). - After this change, the user must set `NO_COLOR` with an non-empty value - to disable colors. This reflects a specification clarification/change - from the upstream website at https://no-color.org. - (Favonia, review by Gabriel Scherer) +- #12451: Warning 53 (misplaced attributes) now works for all attributes. + (Chris Casinghino, review by Florian Angeletti) -- #12744: ocamltest: run tests in recursive subdirs more eagerly - (Nick Roberts, review by Nicolás Ojeda Bär) +- #12622: Give hints about existential types appearing in error messages + (Leo White, review by Gabriel Scherer and Florian Angeletti) -- #12901, 12908: ocamllex: add overflow checks to prevent generating incorrect - lexers; use unsigned numbers in the table encoding when possible. - (Vincent Laviron, report by Edwin Török, review by Xavier Leroy) +- #12671: When a class type parameter or class parameter does not match, + identify which parameter in the error message, instead of saying + "A type parameter" or "A parameter". + (Stefan Muenzel, review by Gabriel Scherer) +- #12679: Add more detail to the error message and manual in case of + invalid module type substitutions. + (Stefan Muenzel, review by Gabriel Scherer and Florian Angeletti) + +- #12750: Display the command executed to extract primitives in + `ocamlc -verbose`. + (David Allsopp, review by Nicolás Ojeda Bär) + +- #12777: Add details about the actual and expected method types to the method + mismatch error messages. + (Javier Chávarri, review by Gabriel Scherer and Florian Angeletti) + +* #12942: Fix an line ordering in some module inclusion error messages + (Nick Roberts, review by Florian Angeletti, report by Carl Eastlund) ### Manual and documentation: - #12338: clarification of the documentation of process related function in @@ -450,6 +517,11 @@ OCaml 5.2.0 (Gabriel Scherer and Guillaume Munch-Maccagnoni, review by Olivier Nicole and Xavier Leroy) +- #12456: Document the incompatibility between effects on the one + hand, and `caml_callback` and asynchronous callbacks (signal + handlers, finalisers, memprof callbacks...) on the other hand. + (Guillaume Munch-Maccagnoni, review by KC Sivaramakrishnan) + - #12694: Document in runtime/tsan.c the TSan instrumentation choices and the consequences with regard to the memory model. (Olivier Nicole, review by Miod Vallat, Gabriel Scherer, Guillaume @@ -477,74 +549,80 @@ OCaml 5.2.0 - #13092: document the existence of the `[@@poll error]` built-in attribute (Florian Angeletti, review by Gabriel Scherer) -### Compiler user-interface and warnings: +### Tools: -* #10613, #12405: Simplify the values used for the system variable (`system:` in - `ocamlopt -config` or the `Config.system` constant). In particular, s390x and - ppc64 now report "linux" instead of "elf"; all variants of 32-bit ARM on Linux - now report "linux"; OpenBSD now reports "openbsd" instead of "bsd" for 32-bit - ARM; FreeBSD, NetBSD and OpenBSD now report the same value for both x86_64 and - x86_32; x86_32 systems matching *bsd but not freebsd*, netbsd* or openbsd* - are no longer identified (as on x86_64); x86_32 Linux now reports "linux" - instead of "linux_elf". - (David Allsopp, request by Kate Deplaix, review by Sébastien Hinderer and - Xavier Leroy) +- #12340: testsuite: collect known issues with current -short-paths + implementation for existential types + (Florian Angeletti, Samuel Hym, review by Florian Angeletti and Thomas Refis) -- #11989, #12246, RFC 31: New flag, -H, to allow for transitive dependencies - without including them in the initial environment. - (Chris Casinghino, François Bobot, and Gabriel Scherer, review by Leo White - and Stefan Muenzel, RFC by François Bobot) +- #12147: ocamllex: Allow carriage returns at the end of line directives. + (SeungCheol Jung, review by Nicolás Ojeda Bär) -- #12247: configure: --disable-ocamldebug can now be used instead - of --disable-debugger (which remains available for compatibility) - (Gabriel Scherer, review by Damien Doligez and Sébastien Hinderer) +- #12260: Fix invalid_argument on some external or module aliases in ocamlnat + (Fabian Hemmer, review by Vincent Laviron) -- #12199: improve the error message for non-overriding `inherit!` - (Florian Angeletti, review by Jules Aguillon) +- #12185: New script language for ocamltest. + (Damien Doligez with Florian Angeletti, Sébastien Hinderer, Gabriel Scherer, + review by Sébastien Hinderer and Gabriel Scherer) -- #12210: uniform style for inline code in compiler messages - (Florian Angeletti, review by Gabriel Scherer) +- #12371: ocamltest: fix recursive expansion of variables. + (Antonin Décimo, Damien Doligez, review by Sébastien Hinderer, + Damien Doligez, Gabriel Scherer, and Xavier Leroy) -* #12278, #:12325: Remove the OCAML_FLEXLINK environment variable from the - compiler drivers. This environment variable was previously used as part of the - FlexDLL bootstrap procedure and existed solely for that purpose. Its removal - greatly simplifies both the build system and testsuite machinery. - (David Allsopp, review by Sébastien Hinderer) +* #12497, #12613: Make ocamlc/ocamlopt fail with an error when no + input files are specified to build an executable. + (Antonin Décimo, review by Sébastien Hinderer) -- #12347: error messages: always report missing polyvariant tags - (Florian Angeletti, report by Tianbo Hao, review by Gabriel Scherer) +- #12576: ocamldep: various refactors. + (Antonin Décimo, review by Florian Angeletti, Gabriel Scherer, and Léo Andrès) -- #12224, specialized error message when trying to apply non-functor - module (e.g `module M = Int(Int)`) - (Florian Angeletti, review by Gabriel Scherer) +- #12615: ocamldoc: get rid of the odoc_literate and odoc_todo generators. + (Sébaistien Hinderer, review by Gabriel Scherer and Florian Angeletti) -- #12451: Warning 53 (misplaced attributes) now works for all attributes. - (Chris Casinghino, review by Florian Angeletti) +- #12624: Use $XDG_CONFIG_DIRS in addition to $XDG_CONFIG_HOME when searching + for init.ml and use this to extend init.ml support to the toplevel when + running on Windows. + (David Allsopp, report by Jonah Beckford, review by Nicolás Ojeda Bär and + Antonin Décimo) -- #12622: Give hints about existential types appearing in error messages - (Leo White, review by Gabriel Scherer and Florian Angeletti) +- #12688: Setting the env variable `NO_COLOR` with an empty value no longer + has effects. Previously, setting `NO_COLOR` with any value, including + the empty value, would disable colors (unless `OCAML_COLOR` is also set). + After this change, the user must set `NO_COLOR` with an non-empty value + to disable colors. This reflects a specification clarification/change + from the upstream website at https://no-color.org. + (Favonia, review by Gabriel Scherer) -- #12671: When a class type parameter or class parameter does not match, - identify which parameter in the error message, instead of saying - "A type parameter" or "A parameter". - (Stefan Muenzel, review by Gabriel Scherer) +- #12744: ocamltest: run tests in recursive subdirs more eagerly + (Nick Roberts, review by Nicolás Ojeda Bär) -- #12679: Add more detail to the error message and manual in case of - invalid module type substitutions. - (Stefan Muenzel, review by Gabriel Scherer and Florian Angeletti) +- #12901, 12908: ocamllex: add overflow checks to prevent generating incorrect + lexers; use unsigned numbers in the table encoding when possible. + (Vincent Laviron, report by Edwin Török, review by Xavier Leroy) -- #12750: Display the command executed to extract primitives in - `ocamlc -verbose`. - (David Allsopp, review by Nicolás Ojeda Bär) +### Internal/compiler-libs changes: -- #12777: Add details about the actual and expected method types to the method - mismatch error messages. - (Javier Chávarri, review by Gabriel Scherer and Florian Angeletti) +- #12508 : Add compiler-side support for project-wide occurrences in Merlin, by + generating index tables of all identifier occurrences. This extra data in .cmt + files is only added when the new flag -bin-annot-occurrences is passed. + (Ulysse Gérard, Nathanaëlle Courant, suggestions by Gabriel Scherer and Thomas + Refis, review by Florian Angeletti, Gabriel Scherer and Thomas Refis) -* #12942: Fix an line ordering in some module inclusion error messages - (Nick Roberts, review by Florian Angeletti, report by Carl Eastlund) +- #12236, #12386, #12391, #12496, #12673: Use syntax as sole determiner of arity + This changes function arity to be based solely on the source program's + parsetree. Previously, the heuristic for arity had more subtle heuristics + that involved type information about patterns. Function arity is important + because it determines when a pattern match's effects run and is an input + into the fast path for function application. + + This change affects tooling: it changes the function constructs in parsetree + and typedtree. + + See https://github.com/ocaml/RFCs/pull/32 for the original RFC. + + (Nick Roberts; review by Richard Eisenberg, Leo White, and Gabriel Scherer; + RFC by Stephen Dolan) -### Internal/compiler-libs changes: - #12639: parsing: Attach a location to the RHS of Ptyp_alias and improve the 'alias type mismatch' error message. @@ -580,21 +658,6 @@ OCaml 5.2.0 in Typecore in favor of local mutable state. (Nick Roberts, review by Takafumi Saikawa) -- #12236, #12386, #12391, #12496, #12673: Use syntax as sole determiner of arity - This changes function arity to be based solely on the source program's - parsetree. Previously, the heuristic for arity had more subtle heuristics - that involved type information about patterns. Function arity is important - because it determines when a pattern match's effects run and is an input - into the fast path for function application. - - This change affects tooling: it changes the function constructs in parsetree - and typedtree. - - See https://github.com/ocaml/RFCs/pull/32 for the original RFC. - - (Nick Roberts; review by Richard Eisenberg, Leo White, and Gabriel Scherer; - RFC by Stephen Dolan) - - #12542: Minor bugfix to #12236: restore dropped call to `instance` (Nick Roberts, review by Jacques Garrigue) @@ -647,12 +710,6 @@ OCaml 5.2.0 - #12764: Move all installable headers in `caml/` sub-directories. (Antonin Décimo, review by Gabriel Scherer and David Allsopp) -- #12508 : Add compiler-side support for project-wide occurrences in Merlin, by - generating index tables of all identifier occurrences. This extra data in .cmt - files is only added when the new flag -bin-annot-occurrences is passed. - (Ulysse Gérard, Nathanaëlle Courant, suggestions by Gabriel Scherer and Thomas - Refis, review by Florian Angeletti, Gabriel Scherer and Thomas Refis) - - #12914: Slightly change the s390x assembly dialect in order to build with Clang's integrated assembler. (Miod Vallat, review by Gabriel Scherer) @@ -885,6 +942,10 @@ OCaml 5.2.0 - #13094: Fix undefined behavior of left-shifting a negative number. (Antonin Décimo, review by Miod Vallat and Nicolás Ojeda Bär) +- #13130: minor fixes to pprintast for raw identifiers and local module open + syntax for types. + (Chet Murthy, review by Gabriel Scherer) + OCaml 5.1.1 (8 December 2023) ---------------------------- @@ -990,7 +1051,7 @@ OCaml 5.1.0 (14 September 2023) `Seq.find_mapi`, `Seq.find_index`, `Array.find_mapi`, `Array.find_index`, `Float.Array.find_opt`, `Float.Array.find_index`, `Float.Array.find_map`, `Float.Array.find_mapi`. - (Sima Kinsart, review by Daniel Bünzli and Nicolás Ojeda Bär) + (Tima Kinsart, review by Daniel Bünzli and Nicolás Ojeda Bär) - #11410: Add Set.to_list, Map.to_list, Map.of_list, `Map.add_to_list: key -> 'a -> 'a list t -> 'a list t`. @@ -1771,7 +1832,7 @@ Some of those changes will benefit all OCaml packages. - #11846: Mark rbx as destroyed at C call for Win64 (mingw-w64 and Cygwin64). Reserve the shadow store for the ABI in the c_stack_link struct instead of - explictly when calling C functions. This simultaneously reduces the number of + explicitly when calling C functions. This simultaneously reduces the number of stack pointer manipulations and also fixes a bug when calling noalloc functions where the shadow store was not being reserved. (David Allsopp, report by Vesa Karvonen, review by Xavier Leroy and @@ -2791,7 +2852,7 @@ OCaml 4.14.0 (28 March 2022) - #8516: Change representation of class signatures (Leo White, review by Thomas Refis) -- #9444: -dtypedtree, print more explictly extra nodes in pattern ast. +- #9444: -dtypedtree, print more explicitly extra nodes in pattern ast. (Frédéric Bour, review by Gabriel Scherer) - #10337: Normalize type_expr nodes on access diff --git a/VERSION b/VERSION index e4f27f17..c78236c7 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -5.2.0 +5.2.1 # Starting with OCaml 4.14, although the version string that appears above is # still correct and this file can thus still be used to figure it out, diff --git a/appveyor.yml b/appveyor.yml index 2c351715..10b98472 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,6 +36,8 @@ environment: OCAMLRUNPARAM: v=0,b FORCE_CYGWIN_UPGRADE: 0 BUILD_MODE: world.opt + # Fully print commands executed by Make + # MAKEFLAGS: V=1 matrix: - PORT: mingw64 BOOTSTRAP_FLEXDLL: true diff --git a/asmcomp/power/emit.mlp b/asmcomp/power/emit.mlp index 47f5419a..70a6a0f7 100644 --- a/asmcomp/power/emit.mlp +++ b/asmcomp/power/emit.mlp @@ -996,8 +996,9 @@ let fundecl fundecl = || max_frame_size >= stack_threshold_size then begin let overflow = new_label () and ret = new_label () in (* The return address is saved in a register not used for param passing *) + (* The size is passed in a register normally not used for param passing *) `{emit_label overflow}: mflr 28\n`; - ` li 12, {emit_int (Config.stack_threshold + max_frame_size / 8)}\n`; + ` li 27, {emit_int (Config.stack_threshold + max_frame_size / 8)}\n`; emit_call "caml_call_realloc_stack"; emit_call_nop (); ` mtlr 28\n`; diff --git a/boot/ocamlc b/boot/ocamlc index ee406942e06db62cbc59a8cc88a35c863475176d..b83f73ccd4c84703e06653ce2456332841b55147 100755 GIT binary patch delta 474 zcmZ9^J1j$C90l<2>;2l^TU4t>J?kn(uiN_wk%$3_MPiaBCTXIEPGa#$43d&27)Xcz z7t`LR>N;NCnx9O^q#-Lg>3L_PBHR|!NKJyhO}_Qi_Yqo zw9V-<-B-;sh2m@@-9C8)mF6Uw)=#{GOxr7zTF#i8F{YCG=?#&o`egSk@&;K4u@I$~ zg>cqO(xc$hH1#bR{E%KYMO5tlR4NqM@`MX#Ihp6^>RW2zS=#>yYK8t4nT{*<0lG_h zA~aBzI% zm-sAAev39GZn$R9kLRf*^G(aQ7 zp$VFy1zMr<*MK%iLOYny0iDnV-EOYj^VAbEUm452Fk#1H{CUBhGg4E6-yE>|t@QQ8 jST>t4Bva4}ePDqNX}6GcmK^>?z4K0sV3uim-iiGJ4-2eY diff --git a/boot/ocamllex b/boot/ocamllex index c102ed86f3d38f46eb4fb6998bbce0f86071bde4..68e0649fa50a6433990bef0324f39e4364c80581 100755 GIT binary patch delta 134 zcmcbAOrr6)#0Cz1#>{3;{dP`$Mj&PaVrC#_+0LoYy2*%lDgy(D7z2ZoIs=1F@b(jl ztX@pIrlxvEdWPC5sbxmGMg~SEx`u|j2IdD`og61DaL`8+-Y%QMs<~fsWpJdg69WUw V69xtbHs{3L979V>%LoHw695=OA@cwL delta 100 zcmZoXE^+^u#0Cz1#*Ai8{dP`$Mj&PaVrC#_+0LoYy2*&Qn1O*qn1R7bl7T_TbNh)z zRxc)QRZ~49J%a. # @@ -677,8 +677,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='OCaml' PACKAGE_TARNAME='ocaml' -PACKAGE_VERSION='5.2.0' -PACKAGE_STRING='OCaml 5.2.0' +PACKAGE_VERSION='5.2.1' +PACKAGE_STRING='OCaml 5.2.1' PACKAGE_BUGREPORT='caml-list@inria.fr' PACKAGE_URL='http://www.ocaml.org' @@ -1586,7 +1586,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures OCaml 5.2.0 to adapt to many kinds of systems. +\`configure' configures OCaml 5.2.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1653,7 +1653,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OCaml 5.2.0:";; + short | recursive ) echo "Configuration of OCaml 5.2.1:";; esac cat <<\_ACEOF @@ -1824,7 +1824,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OCaml configure 5.2.0 +OCaml configure 5.2.1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2481,7 +2481,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by OCaml $as_me 5.2.0, which was +It was created by OCaml $as_me 5.2.1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3237,8 +3237,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuring OCaml version 5.2.0" >&5 -printf "%s\n" "$as_me: Configuring OCaml version 5.2.0" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuring OCaml version 5.2.1" >&5 +printf "%s\n" "$as_me: Configuring OCaml version 5.2.1" >&6;} # Configuration variables @@ -3312,7 +3312,7 @@ unix_directory="" -VERSION=5.2.0 +VERSION=5.2.1 OCAML_DEVELOPMENT_VERSION=false @@ -3322,7 +3322,7 @@ OCAML_VERSION_MAJOR=5 OCAML_VERSION_MINOR=2 -OCAML_VERSION_PATCHLEVEL=0 +OCAML_VERSION_PATCHLEVEL=1 OCAML_VERSION_EXTRA= @@ -3527,15 +3527,15 @@ printf "%s\n" "#define OCAML_VERSION_MAJOR 5" >>confdefs.h printf "%s\n" "#define OCAML_VERSION_MINOR 2" >>confdefs.h -printf "%s\n" "#define OCAML_VERSION_PATCHLEVEL 0" >>confdefs.h +printf "%s\n" "#define OCAML_VERSION_PATCHLEVEL 1" >>confdefs.h printf "%s\n" "#define OCAML_VERSION_ADDITIONAL \"\"" >>confdefs.h printf "%s\n" "#define OCAML_VERSION_EXTRA \"\"" >>confdefs.h -printf "%s\n" "#define OCAML_VERSION 50200" >>confdefs.h +printf "%s\n" "#define OCAML_VERSION 50201" >>confdefs.h -printf "%s\n" "#define OCAML_VERSION_STRING \"5.2.0\"" >>confdefs.h +printf "%s\n" "#define OCAML_VERSION_STRING \"5.2.1\"" >>confdefs.h # Works out how many "o"s are needed in quoted strings @@ -20684,7 +20684,7 @@ else $as_nop mkdll_ldflags='$(OC_DLL_LDFLAGS) $(LDFLAGS)' mkdll_ldflags_exp="${oc_dll_ldflags}" - if test -n ${LDFLAGS} + if test -n "${LDFLAGS}" then : mkdll_ldflags_exp="$mkdll_ldflags_exp $LDFLAGS" fi @@ -21115,7 +21115,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by OCaml $as_me 5.2.0, which was +This file was extended by OCaml $as_me 5.2.1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21188,7 +21188,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -OCaml config.status 5.2.0 +OCaml config.status 5.2.1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 0c9d6385..dff57a27 100644 --- a/configure.ac +++ b/configure.ac @@ -2676,7 +2676,7 @@ ${mkdll_ldflags}" ],[ mkdll_ldflags='$(OC_DLL_LDFLAGS) $(LDFLAGS)' mkdll_ldflags_exp="${oc_dll_ldflags}" - AS_IF([test -n ${LDFLAGS}], + AS_IF([test -n "${LDFLAGS}"], [mkdll_ldflags_exp="$mkdll_ldflags_exp $LDFLAGS"]) mkexe_ldflags="\$(OC_LDFLAGS) \$(LDFLAGS)" mkexe_ldflags_exp="${oc_ldflags} ${LDFLAGS}" diff --git a/dune b/dune index 46b8c9ec..fd719c52 100644 --- a/dune +++ b/dune @@ -45,7 +45,7 @@ config build_path_prefix_map misc identifiable numbers arg_helper clflags profile terminfo ccomp warnings consistbl strongly_connected_components targetint load_path int_replace_polymorphic_compare binutils local_store - lazy_backtrack diffing diffing_with_keys unit_info + lazy_backtrack diffing diffing_with_keys unit_info compression ;; PARSING location longident docstrings syntaxerr ast_helper camlinternalMenhirLib @@ -55,8 +55,8 @@ asttypes parsetree ;; TYPING - ident path primitive shape types btype oprint subst predef datarepr - cmi_format persistent_env env type_immediacy errortrace + ident path primitive shape shape_reduce types btype oprint subst predef + datarepr cmi_format persistent_env env type_immediacy errortrace typedtree printtyped ctype printtyp includeclass mtype envaux includecore tast_iterator tast_mapper signature_group cmt_format untypeast includemod includemod_errorprinter @@ -70,6 +70,7 @@ ;; lambda/ debuginfo lambda matching printlambda runtimedef tmc simplif switch translattribute translclass translcore translmod translobj translprim + value_rec_compiler ;; bytecomp/ meta opcodes bytesections dll symtable diff --git a/manual/src/cmds/intf-c.etex b/manual/src/cmds/intf-c.etex index b3d63dc1..8b126152 100644 --- a/manual/src/cmds/intf-c.etex +++ b/manual/src/cmds/intf-c.etex @@ -990,7 +990,10 @@ Primitives (C functions that can be called from OCaml) should never return void. Local variables of type "value" must be declared with one of the "CAMLlocal" macros. Arrays of "value"s are declared with "CAMLlocalN". These macros must be used at the beginning of the -function, not in a nested block. +function, not in a nested block. Temporaries are equivalent to +local variables, but they cannot be registered with the garbage +collector, so a temporary of type "value" must not be live when +a garbage collection may occur. \end{gcrule} The macros "CAMLlocal1" to "CAMLlocal5" declare and initialize one to diff --git a/ocaml-variants.opam b/ocaml-variants.opam index aef6c090..120ef124 100644 --- a/ocaml-variants.opam +++ b/ocaml-variants.opam @@ -1,7 +1,7 @@ opam-version: "2.0" -version: "5.2.0" +version: "5.2.1" license: "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception" -synopsis: "Official release of OCaml 5.2.0" +synopsis: "Official release of OCaml 5.2.1" maintainer: "caml-list@inria.fr" authors: [ "Xavier Leroy" @@ -14,33 +14,73 @@ authors: [ homepage: "https://github.com/ocaml/ocaml/" bug-reports: "https://github.com/ocaml/ocaml/issues" depends: [ - "ocaml" {= "5.2.0" & post} + # This is OCaml 5.2.1 + "ocaml" {= "5.2.1" & post} + + # General base- packages "base-unix" {post} "base-bigarray" {post} "base-threads" {post} "base-domains" {post} "base-nnp" {post} + + # Architecture (non-Windows) + # opam-repository at present requires that ocaml-base-compiler is installed + # using an architecture which matches the machine's, since arch is used in + # available fields. Cross-compilation at this stage is an unstable accident. + "host-arch-arm32" {arch = "arm32" & post} + "host-arch-arm64" {arch = "arm64" & post} + "host-arch-ppc64" {arch = "ppc64" & post} + "host-arch-riscv64" {arch = "riscv64" & post} + "host-arch-s390x" {arch = "s390x" & post} + # The Windows ports explicitly select the architecture (see below) this + # facility is not yet available for other platforms. + "host-arch-x86_32" {os != "win32" & arch = "x86_32" & post} + ("host-arch-x86_64" {os != "win32" & arch = "x86_64" & post} | + ("host-arch-x86_32" {os != "win32" & arch = "x86_64" & post} & "ocaml-option-32bit" {os != "win32" & arch = "x86_64"})) + "host-arch-unknown" {os != "win32" & arch != "arm32" & arch != "arm64" & arch != "ppc64" & arch != "riscv64" & arch != "s390x" & arch != "x86_32" & arch != "x86_64" & post} + + # Port selection (Windows) + # amd64 mingw-w64 only + (("arch-x86_64" {os = "win32" & arch = "x86_64"} & + "system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & build}) | + # i686 mingw-w64 only + ("arch-x86_32" {os = "win32"} & "ocaml-option-bytecode-only" {os = "win32"} & + "system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & build}) | + # Non-Windows systems + "host-system-other" {os != "win32" & post}) + + # All the 32-bit architectures are bytecode-only "ocaml-option-bytecode-only" {arch != "arm64" & arch != "x86_64" & arch != "s390x" & arch != "riscv64" & arch != "ppc64"} + + # Support Packages + "flexdll" {>= "0.42" & os = "win32"} ] conflict-class: "ocaml-core-compiler" flags: compiler build-env: [ + [MSYS2_ARG_CONV_EXCL = "*"] [LSAN_OPTIONS = "detect_leaks=0,exitcode=0"] [ASAN_OPTIONS = "detect_leaks=0,exitcode=0"] ] build: [ [ "./configure" + "--host=x86_64-w64-mingw32" {os-distribution = "cygwin" & system-mingw:installed & arch-x86_64:installed} + "--host=i686-w64-mingw32" {os-distribution = "cygwin" & system-mingw:installed & arch-x86_32:installed} "--prefix=%{prefix}%" "--docdir=%{doc}%/ocaml" + "--with-flexdll=%{flexdll:share}%" {os = "win32" & flexdll:installed} "-C" "--with-afl" {ocaml-option-afl:installed} "--disable-native-compiler" {ocaml-option-bytecode-only:installed} "--disable-flat-float-array" {ocaml-option-no-flat-float-array:installed} "--enable-flambda" {ocaml-option-flambda:installed} "--enable-frame-pointers" {ocaml-option-fp:installed} + "--without-zstd" {ocaml-option-no-compression:installed} "--enable-tsan" {ocaml-option-tsan:installed} "CC=cc" {!ocaml-option-32bit:installed & !ocaml-option-musl:installed & (os="openbsd"|os="macos")} + "CC=clang" {ocaml-option-tsan:installed & (os="macos")} "CC=musl-gcc" {ocaml-option-musl:installed & os-distribution!="alpine"} "CFLAGS=-Os" {ocaml-option-musl:installed} "LDFLAGS=-Wl,--no-as-needed,-ldl" {ocaml-option-leak-sanitizer:installed | (ocaml-option-address-sanitizer:installed & os!="macos")} @@ -58,6 +98,9 @@ build: [ [make "-j%{jobs}%"] ] install: [make "install"] +conflicts: [ + "system-msvc" +] depopts: [ "ocaml-option-32bit" "ocaml-option-afl" @@ -65,6 +108,7 @@ depopts: [ "ocaml-option-no-flat-float-array" "ocaml-option-flambda" "ocaml-option-fp" + "ocaml-option-no-compression" "ocaml-option-musl" "ocaml-option-leak-sanitizer" "ocaml-option-address-sanitizer" diff --git a/otherlibs/runtime_events/runtime_events_consumer.c b/otherlibs/runtime_events/runtime_events_consumer.c index 9df4eb5a..1771df70 100644 --- a/otherlibs/runtime_events/runtime_events_consumer.c +++ b/otherlibs/runtime_events/runtime_events_consumer.c @@ -189,7 +189,16 @@ caml_runtime_events_create_cursor(const char_os* runtime_events_path, int pid, cursor->ring_file_size_bytes = GetFileSize(cursor->ring_file_handle, NULL); #else - ring_fd = open(runtime_events_loc, O_RDONLY, 0); +#if defined(__ARM_ARCH) && __ARM_ARCH <= 5 + /* Atomic 64-bit load requires RW memory on Debian armel. See: + https://github.com/ocaml/ocaml/issues/13234 */ + const int open_flags = O_RDWR; + const int mmap_prot = PROT_READ | PROT_WRITE; +#else + const int open_flags = O_RDONLY; + const int mmap_prot = PROT_READ; +#endif + ring_fd = open(runtime_events_loc, open_flags, 0); if( ring_fd == -1 ) { caml_stat_free(cursor); @@ -210,7 +219,7 @@ caml_runtime_events_create_cursor(const char_os* runtime_events_path, int pid, /* This cast is necessary for compatibility with Illumos' non-POSIX mmap/munmap */ cursor->metadata = (struct runtime_events_metadata_header *) - mmap(NULL, cursor->ring_file_size_bytes, PROT_READ, + mmap(NULL, cursor->ring_file_size_bytes, mmap_prot, MAP_SHARED, ring_fd, 0); if( cursor->metadata == MAP_FAILED ) { diff --git a/otherlibs/systhreads/Makefile b/otherlibs/systhreads/Makefile index b7ad389a..c77bf56f 100644 --- a/otherlibs/systhreads/Makefile +++ b/otherlibs/systhreads/Makefile @@ -141,6 +141,7 @@ ifeq "$(COMPUTE_DEPS)" "true" include $(addprefix $(DEPDIR)/, $(DEP_FILES)) endif +%.n.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) %.n.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) define GEN_RULE diff --git a/otherlibs/unix/chmod.c b/otherlibs/unix/chmod.c index 8baf7f4f..ebcc28b4 100644 --- a/otherlibs/unix/chmod.c +++ b/otherlibs/unix/chmod.c @@ -23,15 +23,16 @@ #include #include "caml/unixsupport.h" -CAMLprim value caml_unix_chmod(value path, value perm) +CAMLprim value caml_unix_chmod(value path, value vperm) { - CAMLparam2(path, perm); + CAMLparam2(path, vperm); char_os * p; int ret; + int perm = Int_val(vperm); caml_unix_check_path(path, "chmod"); p = caml_stat_strdup_to_os(String_val(path)); caml_enter_blocking_section(); - ret = chmod_os(p, Int_val(perm)); + ret = chmod_os(p, perm); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) caml_uerror("chmod", path); diff --git a/otherlibs/unix/mkdir.c b/otherlibs/unix/mkdir.c index 14dd1964..32c69569 100644 --- a/otherlibs/unix/mkdir.c +++ b/otherlibs/unix/mkdir.c @@ -26,15 +26,16 @@ #include #include "caml/unixsupport.h" -CAMLprim value caml_unix_mkdir(value path, value perm) +CAMLprim value caml_unix_mkdir(value path, value vperm) { - CAMLparam2(path, perm); + CAMLparam2(path, vperm); char_os * p; int ret; + int perm = Int_val(vperm); caml_unix_check_path(path, "mkdir"); p = caml_stat_strdup_to_os(String_val(path)); caml_enter_blocking_section(); - ret = mkdir_os(p, Int_val(perm)); + ret = mkdir_os(p, perm); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) caml_uerror("mkdir", path); diff --git a/otherlibs/unix/mkfifo.c b/otherlibs/unix/mkfifo.c index a924ea60..a446932d 100644 --- a/otherlibs/unix/mkfifo.c +++ b/otherlibs/unix/mkfifo.c @@ -23,15 +23,16 @@ #ifdef HAS_MKFIFO -CAMLprim value caml_unix_mkfifo(value path, value mode) +CAMLprim value caml_unix_mkfifo(value path, value vmode) { - CAMLparam2(path, mode); + CAMLparam2(path, vmode); char * p; int ret; + int mode = Int_val(vmode); caml_unix_check_path(path, "mkfifo"); p = caml_stat_strdup(String_val(path)); caml_enter_blocking_section(); - ret = mkfifo(p, Int_val(mode)); + ret = mkfifo(p, mode); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) @@ -46,15 +47,16 @@ CAMLprim value caml_unix_mkfifo(value path, value mode) #ifdef S_IFIFO -CAMLprim value caml_unix_mkfifo(value path, value mode) +CAMLprim value caml_unix_mkfifo(value path, value vmode) { - CAMLparam2(path, mode); + CAMLparam2(path, vmode); char * p; int ret; + int mode = Int_val(vmode); caml_unix_check_path(path, "mkfifo"); p = caml_stat_strdup(String_val(path)); caml_enter_blocking_section(); - ret = mknod(p, (Int_val(mode) & 07777) | S_IFIFO, 0); + ret = mknod(p, (mode & 07777) | S_IFIFO, 0); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) diff --git a/otherlibs/unix/open_unix.c b/otherlibs/unix/open_unix.c index 18559bda..4eeffb22 100644 --- a/otherlibs/unix/open_unix.c +++ b/otherlibs/unix/open_unix.c @@ -55,11 +55,12 @@ static const int open_cloexec_table[15] = { CLOEXEC, KEEPEXEC }; -CAMLprim value caml_unix_open(value path, value flags, value perm) +CAMLprim value caml_unix_open(value path, value flags, value vperm) { - CAMLparam3(path, flags, perm); + CAMLparam3(path, flags, vperm); int fd, cv_flags, clo_flags, cloexec; char * p; + int perm = Int_val(vperm); caml_unix_check_path(path, "open"); cv_flags = caml_convert_flag_list(flags, open_flag_table); @@ -76,7 +77,7 @@ CAMLprim value caml_unix_open(value path, value flags, value perm) p = caml_stat_strdup(String_val(path)); /* open on a named FIFO can block (PR#8005) */ caml_enter_blocking_section(); - fd = open(p, cv_flags, Int_val(perm)); + fd = open(p, cv_flags, perm); caml_leave_blocking_section(); caml_stat_free(p); if (fd == -1) caml_uerror("open", path); diff --git a/otherlibs/unix/read_unix.c b/otherlibs/unix/read_unix.c index 42ab727b..58fbae7a 100644 --- a/otherlibs/unix/read_unix.c +++ b/otherlibs/unix/read_unix.c @@ -37,18 +37,19 @@ CAMLprim value caml_unix_read(value fd, value buf, value ofs, value len) CAMLreturn(Val_int(ret)); } -CAMLprim value caml_unix_read_bigarray(value fd, value vbuf, +CAMLprim value caml_unix_read_bigarray(value vfd, value vbuf, value vofs, value vlen) { - CAMLparam4(fd, vbuf, vofs, vlen); + CAMLparam4(vfd, vbuf, vofs, vlen); intnat ofs, len, ret; void *buf; buf = Caml_ba_data_val(vbuf); ofs = Long_val(vofs); len = Long_val(vlen); + int fd = Int_val(vfd); caml_enter_blocking_section(); - ret = read(Int_val(fd), (char *) buf + ofs, len); + ret = read(fd, (char *) buf + ofs, len); caml_leave_blocking_section(); if (ret == -1) caml_uerror("read_bigarray", Nothing); CAMLreturn(Val_long(ret)); diff --git a/otherlibs/unix/socketpair_win32.c b/otherlibs/unix/socketpair_win32.c index 7c9d9a9d..a6595b48 100644 --- a/otherlibs/unix/socketpair_win32.c +++ b/otherlibs/unix/socketpair_win32.c @@ -170,18 +170,21 @@ fail: return SOCKET_ERROR; } -CAMLprim value caml_unix_socketpair(value cloexec, value domain, value type, - value protocol) +CAMLprim value caml_unix_socketpair(value cloexec, value vdomain, value vtype, + value vprotocol) { - CAMLparam4(cloexec, domain, type, protocol); + CAMLparam4(cloexec, vdomain, vtype, vprotocol); CAMLlocal1(result); SOCKET sv[2]; int rc; + int domain = Int_val(vdomain); + int type = Int_val(vtype); + int protocol = Int_val(vprotocol); caml_enter_blocking_section(); - rc = socketpair(caml_unix_socket_domain_table[Int_val(domain)], - caml_unix_socket_type_table[Int_val(type)], - Int_val(protocol), + rc = socketpair(caml_unix_socket_domain_table[domain], + caml_unix_socket_type_table[type], + protocol, sv, ! caml_unix_cloexec_p(cloexec)); caml_leave_blocking_section(); diff --git a/otherlibs/unix/truncate_unix.c b/otherlibs/unix/truncate_unix.c index f3863c70..6afdfc8e 100644 --- a/otherlibs/unix/truncate_unix.c +++ b/otherlibs/unix/truncate_unix.c @@ -28,15 +28,16 @@ #ifdef HAS_TRUNCATE -CAMLprim value caml_unix_truncate(value path, value len) +CAMLprim value caml_unix_truncate(value path, value vlen) { - CAMLparam2(path, len); + CAMLparam2(path, vlen); char * p; int ret; + file_offset len = Long_val(vlen); caml_unix_check_path(path, "truncate"); p = caml_stat_strdup(String_val(path)); caml_enter_blocking_section(); - ret = truncate(p, Long_val(len)); + ret = truncate(p, len); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) diff --git a/otherlibs/unix/truncate_win32.c b/otherlibs/unix/truncate_win32.c index de16a4b1..0844469b 100644 --- a/otherlibs/unix/truncate_win32.c +++ b/otherlibs/unix/truncate_win32.c @@ -69,15 +69,16 @@ static int truncate(WCHAR * path, __int64 len) return ret; } -CAMLprim value caml_unix_truncate(value path, value len) +CAMLprim value caml_unix_truncate(value path, value vlen) { - CAMLparam2(path, len); + CAMLparam2(path, vlen); WCHAR * p; int ret; + file_offset len = Long_val(vlen); caml_unix_check_path(path, "truncate"); p = caml_stat_strdup_to_utf16(String_val(path)); caml_enter_blocking_section(); - ret = truncate(p, Long_val(len)); + ret = truncate(p, len); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) diff --git a/otherlibs/unix/write_unix.c b/otherlibs/unix/write_unix.c index 81347f86..172ffd05 100644 --- a/otherlibs/unix/write_unix.c +++ b/otherlibs/unix/write_unix.c @@ -55,20 +55,21 @@ CAMLprim value caml_unix_write(value fd, value buf, value vofs, value vlen) CAMLreturn(Val_long(written)); } -CAMLprim value caml_unix_write_bigarray(value fd, value vbuf, +CAMLprim value caml_unix_write_bigarray(value vfd, value vbuf, value vofs, value vlen, value vsingle) { - CAMLparam5(fd, vbuf, vofs, vlen, vsingle); + CAMLparam5(vfd, vbuf, vofs, vlen, vsingle); intnat ofs, len, written, ret; void *buf; buf = Caml_ba_data_val(vbuf); ofs = Long_val(vofs); len = Long_val(vlen); + int fd = Int_val(vfd); written = 0; caml_enter_blocking_section(); while (len > 0) { - ret = write(Int_val(fd), (char *) buf + ofs, len); + ret = write(fd, (char *) buf + ofs, len); if (ret == -1) { if ((errno == EAGAIN || errno == EWOULDBLOCK) && written > 0) break; caml_leave_blocking_section(); diff --git a/runtime/arm64.S b/runtime/arm64.S index e71f25eb..6c6495a0 100644 --- a/runtime/arm64.S +++ b/runtime/arm64.S @@ -569,8 +569,9 @@ FUNCTION(caml_c_call) str TRAP_PTR, Caml_state(exn_handler) /* Call the function */ blr ADDITIONAL_ARG - /* Reload alloc ptr */ + /* Reload new allocation pointer & exn handler */ ldr ALLOC_PTR, Caml_state(young_ptr) + ldr TRAP_PTR, Caml_state(exn_handler) /* Load ocaml stack */ SWITCH_C_TO_OCAML #if defined(WITH_THREAD_SANITIZER) @@ -625,8 +626,9 @@ FUNCTION(caml_c_call_stack_args) blr ADDITIONAL_ARG /* Restore stack */ mov sp, x19 - /* Reload alloc ptr */ + /* Reload new allocation pointer & exn handler */ ldr ALLOC_PTR, Caml_state(young_ptr) + ldr TRAP_PTR, Caml_state(exn_handler) /* Switch from C to OCaml */ SWITCH_C_TO_OCAML /* Return */ diff --git a/runtime/callback.c b/runtime/callback.c index b96831a7..4db417a1 100644 --- a/runtime/callback.c +++ b/runtime/callback.c @@ -78,12 +78,9 @@ Caml_inline void restore_stack_parent(caml_domain_state* domain_state, #include "caml/fix_code.h" #include "caml/fiber.h" -static CAMLthread_local opcode_t callback_code[] = - { ACC, 0, APPLY, 0, POP, 1, STOP }; +static opcode_t callback_code[] = { STOP }; -static CAMLthread_local int callback_code_inited = 0; - -static void init_callback_code(void) +void caml_init_callbacks(void) { caml_register_code_fragment((char *) callback_code, (char *) callback_code + sizeof(callback_code), @@ -91,42 +88,44 @@ static void init_callback_code(void) #ifdef THREADED_CODE caml_thread_code(callback_code, sizeof(callback_code)); #endif - callback_code_inited = 1; } CAMLexport value caml_callbackN_exn(value closure, int narg, value args[]) { - CAMLparam0(); /* no need to register closure and args as roots, see below */ + CAMLparam1(closure); /* no need to register args as roots, see below */ CAMLlocal1(cont); value res; - int i; caml_domain_state* domain_state = Caml_state; - CAMLassert(narg + 4 <= 256); - domain_state->current_stack->sp -= narg + 4; - for (i = 0; i < narg; i++) - domain_state->current_stack->sp[i] = args[i]; /* arguments */ - - if (!callback_code_inited) init_callback_code(); + /* Ensure there's enough stack space */ + intnat req = narg + 3 + Stack_threshold_words; + if (domain_state->current_stack->sp - req < + Stack_base(domain_state->current_stack)) + if (!caml_try_realloc_stack(req)) + caml_raise_stack_overflow(); - callback_code[1] = narg + 3; - callback_code[3] = narg; + /* Push the arguments on the stack */ + domain_state->current_stack->sp -= narg + 3; + for (int i = 0; i < narg; i++) + domain_state->current_stack->sp[i] = args[i]; /* arguments */ + /* Push a return frame */ domain_state->current_stack->sp[narg] = - (value)(callback_code + 4); /* return address */ + (value)callback_code; /* return address */ domain_state->current_stack->sp[narg + 1] = Val_unit; /* environment */ domain_state->current_stack->sp[narg + 2] = Val_long(0); /* extra args */ - domain_state->current_stack->sp[narg + 3] = closure; cont = alloc_and_clear_stack_parent(domain_state); - /* This can call the GC and invalidate the values [closure] and [args]. + /* This can call the GC and invalidate the values [args]. However, they are never used afterwards, as they were copied into the root [domain_state->current_stack]. */ caml_update_young_limit_after_c_call(domain_state); - res = caml_interprete(callback_code, sizeof(callback_code)); + res = caml_bytecode_interpreter(Code_val(closure), 0 /* unknown size */, + closure, /* environment */ + narg - 1 /* extra args beyond the 1st */); if (Is_exception_result(res)) - domain_state->current_stack->sp += narg + 4; /* PR#3419 */ + domain_state->current_stack->sp += narg + 3; /* PR#3419 */ restore_stack_parent(domain_state, cont); @@ -162,8 +161,9 @@ CAMLexport value caml_callback3_exn(value closure, /* Native-code callbacks. caml_callback[123]_asm are implemented in asm. */ -static void init_callback_code(void) +void caml_init_callbacks(void) { + /* Nothing to do */ } typedef value (callback_stub)(caml_domain_state* state, @@ -330,11 +330,6 @@ struct named_value { static struct named_value * named_value_table[Named_value_size] = { NULL, }; static caml_plat_mutex named_value_lock = CAML_PLAT_MUTEX_INITIALIZER; -void caml_init_callbacks(void) -{ - init_callback_code(); -} - static unsigned int hash_value_name(char const *name) { unsigned int h; diff --git a/runtime/caml/interp.h b/runtime/caml/interp.h index 00d2de87..fcbc0f56 100644 --- a/runtime/caml/interp.h +++ b/runtime/caml/interp.h @@ -23,8 +23,16 @@ #include "misc.h" #include "mlvalues.h" -/* interpret a bytecode */ -value caml_interprete (code_t prog, asize_t prog_size); +CAMLextern +value caml_bytecode_interpreter (code_t prog, asize_t prog_size, + value initial_env, intnat initial_extra_args); + +/* For backward compatibility */ + +Caml_inline value caml_interprete (code_t prog, asize_t prog_size) +{ + return caml_bytecode_interpreter(prog, prog_size, Atom(0), 0); +} #endif /* CAML_INTERNALS */ diff --git a/runtime/finalise.c b/runtime/finalise.c index 80119050..67cb75b9 100644 --- a/runtime/finalise.c +++ b/runtime/finalise.c @@ -262,7 +262,7 @@ static void generic_final_minor_update for (i = final->old; i < final->young; i++) { CAMLassert (Is_block (final->table[i].val)); CAMLassert (Tag_val (final->table[i].val) != Forward_tag); - if (Is_young(final->table[j].val) && + if (Is_young(final->table[i].val) && caml_get_header_val(final->table[i].val) != 0) { /** dead */ fi->todo_tail->item[k] = final->table[i]; diff --git a/runtime/gc_ctrl.c b/runtime/gc_ctrl.c index 4f21c239..99c499b1 100644 --- a/runtime/gc_ctrl.c +++ b/runtime/gc_ctrl.c @@ -105,8 +105,8 @@ CAMLprim value caml_gc_minor_words(value v) CAMLprim value caml_gc_counters(value v) { - CAMLparam0 (); /* v is ignored */ - CAMLlocal1 (res); + CAMLparam0 (); /* v is ignored */ + CAMLlocal4 (minwords_, prowords_, majwords_, res); /* get a copy of these before allocating anything... */ double minwords = caml_gc_minor_words_unboxed(); @@ -114,11 +114,11 @@ CAMLprim value caml_gc_counters(value v) double majwords = Caml_state->stat_major_words + (double) Caml_state->allocated_words; - res = caml_alloc_3(0, - caml_copy_double (minwords), - caml_copy_double (prowords), - caml_copy_double (majwords)); - CAMLreturn (res); + minwords_ = caml_copy_double(minwords); + prowords_ = caml_copy_double(prowords); + majwords_ = caml_copy_double(majwords); + res = caml_alloc_3(0, minwords_, prowords_, majwords_); + CAMLreturn(res); } CAMLprim value caml_gc_get(value v) diff --git a/runtime/interp.c b/runtime/interp.c index 66f01234..479cd66a 100644 --- a/runtime/interp.c +++ b/runtime/interp.c @@ -209,7 +209,7 @@ Caml_inline void check_trap_barrier_for_effect #define ACCU_REG asm("%r16") #endif #ifdef __mc68000__ -#define PC_REG asm("a5") +#define PC_REG asm("a3") #define SP_REG asm("a4") #define ACCU_REG asm("d7") #endif @@ -248,7 +248,8 @@ static value raise_unhandled_effect; CAMLno_tsan /* No need to TSan-instrument this (and pay a slowdown) function as TSan is not supported for bytecode. */ -value caml_interprete(code_t prog, asize_t prog_size) +value caml_bytecode_interpreter(code_t prog, asize_t prog_size, + value initial_env, intnat initial_extra_args) { #ifdef PC_REG register code_t pc PC_REG; @@ -342,8 +343,8 @@ value caml_interprete(code_t prog, asize_t prog_size) sp = domain_state->current_stack->sp; pc = prog; - extra_args = 0; - env = Atom(0); + extra_args = initial_extra_args; + env = initial_env; accu = Val_int(0); #ifdef THREADED_CODE @@ -1016,7 +1017,7 @@ value caml_interprete(code_t prog, asize_t prog_size) check_stacks: if (sp < Stack_threshold_ptr(domain_state->current_stack)) { domain_state->current_stack->sp = sp; - if (!caml_try_realloc_stack(Stack_threshold / sizeof(value))) { + if (!caml_try_realloc_stack(Stack_threshold_words)) { Setup_for_c_call; caml_raise_stack_overflow(); } sp = domain_state->current_stack->sp; diff --git a/runtime/power.S b/runtime/power.S index bfb37fa9..dcd8444b 100644 --- a/runtime/power.S +++ b/runtime/power.S @@ -358,16 +358,16 @@ caml_system__code_begin: /* Reallocate the stack when it is too small. */ -/* Desired size is passed in register TMP2. */ +/* Desired size is passed in register r27. */ FUNCTION caml_call_realloc_stack /* Save return address in caller's frame. */ mflr 0 std 0, LR_SAVE(SP) /* Save all registers, as well as ALLOC_PTR and TRAP_PTR */ - SAVE_ALL_REGS /* TMP2 is preserved */ + SAVE_ALL_REGS /* r27 is preserved */ /* Recover desired size, to be passed in r3 */ - mr 3, TMP2 + mr 3, 27 /* Switch stacks and call caml_try_realloc_stack */ SWITCH_OCAML_TO_C Far_call(caml_try_realloc_stack) @@ -445,8 +445,9 @@ FUNCTION caml_c_call mr 2, C_CALL_TOC /* restore current TOC */ /* Restore return address (in register C_CALL_RET_ADDR, preserved by C) */ mtlr C_CALL_RET_ADDR - /* Reload allocation pointer*/ + /* Reload new allocation pointer and exception pointer */ ld ALLOC_PTR, Caml_state(young_ptr) + ld TRAP_PTR, Caml_state(exn_handler) #if defined(WITH_THREAD_SANITIZER) TSAN_SETUP_C_CALL 16 /* Save return value registers. Since the called function could be anything, @@ -497,8 +498,9 @@ FUNCTION caml_c_call_stack_args add SP, SP, STACK_ARG_BYTES /* Restore return address (in register C_CALL_RET_ADDR, preserved by C) */ mtlr C_CALL_RET_ADDR - /* Reload allocation pointer*/ + /* Reload new allocation pointer and exception pointer */ ld ALLOC_PTR, Caml_state(young_ptr) + ld TRAP_PTR, Caml_state(exn_handler) /* Switch from C to OCaml */ SWITCH_C_TO_OCAML /* Return to caller */ diff --git a/runtime/riscv.S b/runtime/riscv.S index a2eca7a3..8934db0b 100644 --- a/runtime/riscv.S +++ b/runtime/riscv.S @@ -516,8 +516,9 @@ L(caml_c_call): sd TRAP_PTR, Caml_state(exn_handler) /* Call the function */ jalr ADDITIONAL_ARG - /* Reload alloc ptr */ + /* Reload new allocation pointer & exn handler */ ld ALLOC_PTR, Caml_state(young_ptr) + ld TRAP_PTR, Caml_state(exn_handler) /* Load ocaml stack */ SWITCH_C_TO_OCAML #if defined(WITH_THREAD_SANITIZER) @@ -575,8 +576,9 @@ FUNCTION(caml_c_call_stack_args) jalr ADDITIONAL_ARG /* Restore stack */ mv sp, s2 - /* Reload alloc ptr */ + /* Reload new allocation pointer & exn handler */ ld ALLOC_PTR, Caml_state(young_ptr) + ld TRAP_PTR, Caml_state(exn_handler) /* Switch from C to OCaml */ SWITCH_C_TO_OCAML /* Return */ diff --git a/runtime/s390x.S b/runtime/s390x.S index b59822ce..113831a3 100644 --- a/runtime/s390x.S +++ b/runtime/s390x.S @@ -515,7 +515,7 @@ LBL(caml_c_call): #endif basr %r14, ADDITIONAL_ARG CLEANUP_AFTER_C_CALL - /* Reload alloc ptr */ + /* Reload new allocation pointer & exn handler */ lg ALLOC_PTR, Caml_state(young_ptr) lg TRAP_PTR, Caml_state(exn_handler) /* Load ocaml stack and restore global variables */ @@ -584,8 +584,9 @@ LBL(106): CLEANUP_AFTER_C_CALL /* Restore stack */ lgr %r15, %r12 - /* Reload alloc ptr */ + /* Reload new allocation pointer & exn handler */ lg ALLOC_PTR, Caml_state(young_ptr) + lg TRAP_PTR, Caml_state(exn_handler) /* Switch from C to OCaml */ SWITCH_C_TO_OCAML /* Return */ diff --git a/runtime/sys.c b/runtime/sys.c index 0b548ae4..f3ef0ef1 100644 --- a/runtime/sys.c +++ b/runtime/sys.c @@ -364,15 +364,16 @@ CAMLprim value caml_sys_chdir(value dirname) CAMLreturn(Val_unit); } -CAMLprim value caml_sys_mkdir(value path, value perm) +CAMLprim value caml_sys_mkdir(value path, value vperm) { - CAMLparam2(path, perm); + CAMLparam2(path, vperm); char_os * p; int ret; + int perm = Int_val(vperm); caml_sys_check_path(path); p = caml_stat_strdup_to_os(String_val(path)); caml_enter_blocking_section(); - ret = mkdir_os(p, Int_val(perm)); + ret = mkdir_os(p, perm); caml_leave_blocking_section(); caml_stat_free(p); if (ret == -1) caml_sys_error(path); diff --git a/stdlib/gc.ml b/stdlib/gc.ml index a6de55c8..dfb4261d 100644 --- a/stdlib/gc.ml +++ b/stdlib/gc.ml @@ -114,11 +114,13 @@ let rec call_alarm arec = let delete_alarm a = Atomic.set a false -let create_alarm f = - let arec = { active = Atomic.make true; f = f } in - Domain.at_exit (fun () -> delete_alarm arec.active); +(* never inline, to prevent [arec] from being allocated statically *) +let[@inline never] create_alarm f = + let alarm = Atomic.make true in + Domain.at_exit (fun () -> delete_alarm alarm); + let arec = { active = alarm; f = f } in finalise call_alarm arec; - arec.active + alarm module Memprof = diff --git a/testsuite/tests/callback/test1.ml b/testsuite/tests/callback/test1.ml index c39be0c5..bc110f98 100644 --- a/testsuite/tests/callback/test1.ml +++ b/testsuite/tests/callback/test1.ml @@ -10,6 +10,10 @@ external mycallback3 : ('a -> 'b -> 'c -> 'd) -> 'a -> 'b -> 'c -> 'd = "mycallback3" external mycallback4 : ('a -> 'b -> 'c -> 'd -> 'e) -> 'a -> 'b -> 'c -> 'd -> 'e = "mycallback4" +external mycallbackN : Obj.t -> int array -> int = "mycallbackN" + +let rec growstack n = + if n <= 0 then 0 else 1 + growstack (n - 1) let rec tak (x, y, z as _tuple) = if x > y then tak(tak (x-1, y, z), tak (y-1, z, x), tak (z-1, x, y)) @@ -21,6 +25,11 @@ let tak3 x y z = tak (x, y, z) let tak4 x y z u = tak (x, y, z + u) +let rec sum_args nargs accu = + if nargs <= 0 + then Obj.repr accu + else Obj.repr (fun n -> sum_args (nargs - 1) (accu + n)) + let raise_exit () = (raise Exit : unit) let trapexit () = @@ -43,6 +52,10 @@ let _ = print_int(mycallback2 tak2 18 (12, 6)); print_newline(); print_int(mycallback3 tak3 18 12 6); print_newline(); print_int(mycallback4 tak4 18 12 3 3); print_newline(); + print_int(mycallbackN (sum_args 10000 0) (Array.init 10000 (fun i -> i))); + print_newline(); print_int(trapexit ()); print_newline(); print_string(tripwire mypushroot); print_newline(); print_string(tripwire mycamlparam); print_newline(); + begin try ignore (mycallback1 growstack 1_000); raise Exit + with Exit -> () end diff --git a/testsuite/tests/callback/test1.reference b/testsuite/tests/callback/test1.reference index 8b2262dc..f0bfbeae 100644 --- a/testsuite/tests/callback/test1.reference +++ b/testsuite/tests/callback/test1.reference @@ -2,6 +2,7 @@ 7 7 7 +49995000 7 aaaaa aaaaa diff --git a/testsuite/tests/callback/test1_.c b/testsuite/tests/callback/test1_.c index bdce0b17..04d5d96b 100644 --- a/testsuite/tests/callback/test1_.c +++ b/testsuite/tests/callback/test1_.c @@ -50,6 +50,11 @@ value mycallback4(value fun, value arg1, value arg2, value arg3, value arg4) return res; } +value mycallbackN(value fun, value args) +{ + return caml_callbackN(fun, Wosize_val(args), (value *) &Field(args, 0)); +} + value mypushroot(value v, value fun, value arg) { CAMLparam1(v); diff --git a/testsuite/tests/callback/test_gc_alarm.ml b/testsuite/tests/callback/test_gc_alarm.ml new file mode 100644 index 00000000..9452470c --- /dev/null +++ b/testsuite/tests/callback/test_gc_alarm.ml @@ -0,0 +1,14 @@ +(* TEST *) + +let success () = exit 0 +let failure () = failwith "The end was reached without triggering the GC alarm" + +let () = + let _ = Gc.create_alarm success in + let g = Array.init 120000 (fun i -> Array.init 1 (fun i -> i)) in + for i = 0 to 10000 do + let a = Array.init 12000 (fun i -> i) in + g.(i) <- a; + a.(0) <- 42; + done; + failure () diff --git a/tools/ci/actions/canonicalize-dumpbin.awk b/tools/ci/actions/canonicalize-dumpbin.awk new file mode 100644 index 00000000..67f11aa6 --- /dev/null +++ b/tools/ci/actions/canonicalize-dumpbin.awk @@ -0,0 +1,87 @@ +#************************************************************************** +#* * +#* OCaml * +#* * +#* Samuel Hym, Tarides * +#* * +#* Copyright 2023 Tarides * +#* * +#* All rights reserved. This file is distributed under the terms of * +#* the GNU Lesser General Public License version 2.1, with the * +#* special exception on linking described in the file LICENSE. * +#* * +#************************************************************************** + +# Awk script to remove the differences between the disassembly of amd64.o as +# assembled by MinGW GCC and amd64nt.obj as assembled by MASM +# +# The main differences are: +# - the encoding of some instructions is not the same even when they have the +# same mnemonic, so we process the result of `dumpbin /disasm:nobytes` +# - some internal labels are exposed as such on one output, not on the other: so +# we process the file twice, the first pass to record the position of all +# internal labels (labels that don't start with `caml`), the second to replace +# them by their offset in `lea` instructions +# - the final padding is different, with some `nop`s at the +# `caml_system__code_end` label in one output, not the other, so we drop +# everything after that label +# +# This script expects the input to be given twice: +# awk -f me input.dump input.dump +# where the first input.dump is used for the first pass (recording label +# positions) and printing nothing, the second input.dump is for the second pass +# that actually prints the canonicalized assembly, with only the exported labels + +BEGIN { + # first pass (or second pass) + first=1 + # to skip the final padding + skip=0 + # the label that appeared on the previous line when we want to record it + label="" +} +ENDFILE { + # start the second pass + first=0 +} + +# On label lines +/^[a-zA-Z0-9_]*:\s*$/ { + # In that an internal label? + if ($0 !~ /^caml/) { + if (first) { + sub(/:.*$/, "") + label=$0 + } + } else { + if (!first) { + if($0 ~ /^caml_system__code_end/) { + # Drop everything after caml_system__code_end + skip=1 + } else + print + } + } +} + +# On mnemonic lines +/^ [0-9A-F]*:/ { + # if we are on the first instruction after an internal label, we associate the + # label to the current position + if (label != "") { + sub(/^0*/,"",$1) + sub(/:$/,"",$1) + labels[label] = $1 + label="" + } else { + if(!first) { + if ($2 == "lea") { + for(g in labels) { + sub(g,labels[g] "h") + } + } + if(!skip) + print + } + } +} diff --git a/tools/ci/actions/check-typo.sh b/tools/ci/actions/check-typo.sh index 17fc1905..2b837950 100755 --- a/tools/ci/actions/check-typo.sh +++ b/tools/ci/actions/check-typo.sh @@ -50,8 +50,8 @@ CheckTypoTree () { COMMIT="$1" COMMITS_TO_SEARCH="$2" export OCAML_CT_HEAD="$COMMIT" - export OCAML_CT_LS_FILES="git diff-tree --no-commit-id --name-only -r \ -$COMMITS_TO_SEARCH --" + export OCAML_CT_LS_FILES="git -c core.quotePath=false diff-tree \ + --no-commit-id --name-only -r $COMMITS_TO_SEARCH --" export OCAML_CT_CAT='git cat-file --textconv' export OCAML_CT_PREFIX="$COMMIT:" GIT_INDEX_FILE=tmp-index git read-tree --reset -i "$COMMIT" diff --git a/tools/ci/actions/runner.sh b/tools/ci/actions/runner.sh index 060b0c75..10f593ef 100755 --- a/tools/ci/actions/runner.sh +++ b/tools/ci/actions/runner.sh @@ -44,16 +44,27 @@ EOF --disable-dependency-generation \ $CONFIG_ARG" - ./configure $configure_flags + local failed + ./configure $configure_flags || failed=$? + if ((failed)) ; then cat config.log ; exit $failed ; fi } Build () { + local failed + export TERM=ansi if [ "$(uname)" = 'Darwin' ]; then - script -q build.log $MAKE_WARN + script -q build.log $MAKE_WARN || failed=$? + if ((failed)); then + script -q build.log $MAKE_WARN make -j1 V=1 + exit $failed + fi else - script --return --command "$MAKE_WARN" build.log + script --return --command "$MAKE_WARN" build.log || failed=$? + if ((failed)); then + script --return --command "$MAKE_WARN -j1 V=1" build.log + exit $failed + fi fi - failed=0 if grep -Fq ' warning: undefined variable ' build.log; then echo Undefined Makefile variables detected: grep -F ' warning: undefined variable ' build.log @@ -65,14 +76,24 @@ Build () { failed=1 fi if ((failed)); then - exit 1 + exit $failed fi } Test () { - echo Running the testsuite - $MAKE -C testsuite parallel - cd .. + if [ "$1" = "sequential" ]; then + echo Running the testsuite sequentially + $MAKE -C testsuite all + cd .. + elif [ "$1" = "parallel" ]; then + echo Running the testsuite in parallel + $MAKE -C testsuite parallel + cd .. + else + echo "Error: unexpected argument '$1' to function Test(). " \ + "It should be 'sequential' or 'parallel'." + exit 1 + fi } # By default, TestPrefix will attempt to run the tests @@ -125,7 +146,9 @@ This test checks the global structure of the reference manual -------------------------------------------------------------------------- EOF # we need some of the configuration data provided by configure - ./configure + local failed + ./configure || failed=$? + if ((failed)) ; then cat config.log ; exit $failed ; fi $MAKE check-stdlib check-case-collision -C manual/tests } @@ -151,16 +174,28 @@ ReportBuildStatus () { } BasicCompiler () { + local failed trap ReportBuildStatus ERR + local failed ./configure --disable-dependency-generation \ --disable-debug-runtime \ - --disable-instrumented-runtime + --disable-instrumented-runtime \ + || failed=$? + if ((failed)) ; then cat config.log ; exit $failed ; fi # Need a runtime - make -j coldstart + make -j coldstart || failed=$? + if ((failed)) ; then + make -j1 V=1 coldstart + exit $failed + fi # And generated files (ocamllex compiles ocamlyacc) - make -j ocamllex + make -j ocamllex || failed=$? + if ((failed)) ; then + make -j1 V=1 ocamllex + exit $failed + fi ReportBuildStatus 0 } @@ -168,7 +203,8 @@ BasicCompiler () { case $1 in configure) Configure;; build) Build;; -test) Test;; +test) Test parallel;; +test_sequential) Test sequential;; test_prefix) TestPrefix $2;; api-docs) API_Docs;; install) Install;; diff --git a/tools/ci/appveyor/appveyor_build.cmd b/tools/ci/appveyor/appveyor_build.cmd index f2368890..2738742c 100644 --- a/tools/ci/appveyor/appveyor_build.cmd +++ b/tools/ci/appveyor/appveyor_build.cmd @@ -61,7 +61,13 @@ if %ERRORLEVEL% equ 1 ( goto :EOF :UpgradeCygwin -if "%CYGWIN_INSTALL_PACKAGES%" neq "" "%CYG_ROOT%\setup-x86_64.exe" --quiet-mode --no-shortcuts --no-startmenu --no-desktop --only-site --root "%CYG_ROOT%" --site "%CYG_MIRROR%" --local-package-dir "%CYG_CACHE%" --packages %CYGWIN_INSTALL_PACKAGES:~1% > nul +if %CYGWIN_UPGRADE_REQUIRED% equ 1 ( + set CYGWIN_FLAGS=--upgrade-also + set CYGWIN_UPGRADE_REQUIRED=0 +) else ( + set CYGWIN_FLAGS= +) +if "%CYGWIN_INSTALL_PACKAGES%" neq "" "%CYG_ROOT%\setup-x86_64.exe" --quiet-mode --no-shortcuts --no-startmenu --no-desktop --only-site --root "%CYG_ROOT%" --site "%CYG_MIRROR%" --local-package-dir "%CYG_CACHE%" %CYGWIN_FLAGS% --packages %CYGWIN_INSTALL_PACKAGES:~1% for %%P in (%CYGWIN_COMMANDS%) do "%CYG_ROOT%\bin\%%P.exe" --version 2> nul > nul || set CYGWIN_UPGRADE_REQUIRED=1 "%CYG_ROOT%\bin\bash.exe" -lc "cygcheck -dc %CYGWIN_PACKAGES%" if %CYGWIN_UPGRADE_REQUIRED% equ 1 ( diff --git a/tools/ci/appveyor/appveyor_build.sh b/tools/ci/appveyor/appveyor_build.sh index 6891c169..ea43236b 100755 --- a/tools/ci/appveyor/appveyor_build.sh +++ b/tools/ci/appveyor/appveyor_build.sh @@ -83,7 +83,7 @@ function set_configuration { mkdir -p "$CACHE_DIRECTORY" local CACHE_KEY CACHE_FILE_PREFIX CACHE_FILE - CACHE_KEY=$({ cat configure; uname; } | shasum | cut -c 1-7) + CACHE_KEY=$({ cat configure; uname; } | sha1sum | cut -c 1-7) CACHE_FILE_PREFIX="$CACHE_DIRECTORY/config.cache-$1" CACHE_FILE="$CACHE_FILE_PREFIX-$CACHE_KEY" @@ -97,8 +97,11 @@ function set_configuration { if ! ./configure --cache-file="$CACHE_FILE" $dep $build $man $host \ --prefix="$2" --enable-ocamltest ; then rm -f -- "$CACHE_FILE" + local failed ./configure --cache-file="$CACHE_FILE" $dep $build $man $host \ - --prefix="$2" --enable-ocamltest + --prefix="$2" --enable-ocamltest \ + || failed=$? + if ((failed)) ; then cat config.log ; exit $failed ; fi fi # FILE=$(pwd | cygpath -f - -m)/Makefile.config @@ -217,7 +220,7 @@ case "$1" in # For an explanation of the sed command, see # https://github.com/appveyor/ci/issues/1824 script --quiet --return --command \ - "$MAKE -C ../$BUILD_PREFIX-$PORT world.opt" \ + "$MAKE -C ../$BUILD_PREFIX-$PORT" \ "../$BUILD_PREFIX-$PORT/build.log" | sed -e 's/\d027\[K//g' \ -e 's/\d027\[m/\d027[0m/g' \ -- 2.30.2