Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Recursive Modules on ocaml < 4.13 #1485

Merged
merged 6 commits into from
Jul 5, 2023

Conversation

mlasson
Copy link
Contributor

@mlasson mlasson commented Jul 5, 2023

Description

The CI of gen_js_api is failing for version of ocaml < 4.13 on some tests involving recursive module.

This can basically be reproduced by running on ocaml 4.12.1:

module rec Even : sig val is: int -> bool end = struct
  let is n =
    match n with
    | 0 -> true
    | 1 -> false
    | n -> Odd.is (n - 1)

end and Odd : sig val is: int -> bool end = struct
      let is n =
        match n with
        | 0 -> false
        | 1 -> true
        | n -> Even.is (n - 1)
    end

let () =
  Jsoo_runtime.Js.debugger ();
  assert (not (Even.is 1))

The "Even.is" is not even a function (as shown by a debugger); it is an object with a single fun property and it is not callable.
Since PR #1389, caml_call_gen is no longer checking for the presence of ".fun".

Fix Proposal

We could use caml_alloc_dummy_infix to allocate the dummy function.

@mlasson mlasson changed the title Fix Compilation of Recursive Module on ocaml < 4.13 Fix Recursive Modules on ocaml < 4.13 Jul 5, 2023
@@ -66,3 +66,25 @@ end
let () =
List.iter (fun x -> x#go)
[new Foo.cls; Foo.M.foo(); Lazy.force Foo.M.bar]

module rec Even : sig val is: int -> bool end =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to keep the directory tests-ocaml as close as possible to the testsuite/tests directory from ocaml repo.

Can you move the test in compiler/tests-jsoo/test_rec_mod.ml ?

I'll try to document that the purpose of the various test directories

@hhugo
Copy link
Member

hhugo commented Jul 5, 2023

Running the test in compiler/tests-jsoo/test_rec_mod.ml
We might want this additional fix

 //Provides: caml_update_dummy
 function caml_update_dummy (x, y) {
-  if( typeof y==="function" ) { x.fun = y; return 0; }
   if( y.fun ) { x.fun = y.fun; return 0; }
+  if( typeof y==="function" ) { x.fun = y; return 0; }
   var i = y.length; while (i--) x[i] = y[i]; return 0;
 }

@hhugo
Copy link
Member

hhugo commented Jul 5, 2023

LGMT, I left small comments.
Thanks you very much for your contribution

@hhugo
Copy link
Member

hhugo commented Jul 5, 2023

Here is a commit allowing to run some test with ocaml 4.12.
7dc2ae6

There are already showing the issue you're fixing. Fill tree to include this commit in your branch.

 |let%expect_test _ =
 |  (try print_int (M1.f 3) with e -> print_endline @@ Printexc.to_string e);
-|  [%expect {| 2 |}];
+|  [%expect {|
+|    function(){
+|                var
+|                 extra_args = arguments.length == 0 ? 1 : arguments.length,
+|                 nargs = new Array(args.length + extra_args);
+|                for(var i = 0; i < args.length; i++) nargs[i] = args[i];
+|                for(var i = 0; i < arguments.length; i++)
+|                 nargs[args.length + i] = arguments[i];
+|                return caml_call_gen(f, nargs);
+|               } |}];
-|  (try print_int (M1.g 3) with e -> print_endline @@ Printexc.to_string e);
-|  [%expect {| 2 |}];
+|  (try print_int (M1.g 3) with e -> print_endline @@ Printexc.to_string e);
+|  [%expect {|
+|    function(){
+|                var
+|                 extra_args = arguments.length == 0 ? 1 : arguments.length,
+|                 nargs = new Array(args.length + extra_args);
+|                for(var i = 0; i < args.length; i++) nargs[i] = args[i];
+|                for(var i = 0; i < arguments.length; i++)
+|                 nargs[args.length + i] = arguments[i];
+|                return caml_call_gen(f, nargs);
+|               } |}];
-|  (try print_int (M1.h 3) with e -> print_endline @@ Printexc.to_string e);
-|  [%expect {| 2 |}]
+|  (try print_int (M1.h 3) with e -> print_endline @@ Printexc.to_string e);
+|  [%expect {|
+|    function(){
+|                var
+|                 extra_args = arguments.length == 0 ? 1 : arguments.length,
+|                 nargs = new Array(args.length + extra_args);
+|                for(var i = 0; i < args.length; i++) nargs[i] = args[i];
+|                for(var i = 0; i < arguments.length; i++)
+|                 nargs[args.length + i] = arguments[i];
+|                return caml_call_gen(f, nargs);
+|               } |}]
 |
 |module rec Odd : sig
 |  val odd : int -> bool
 |end = struct
 |  let odd x = if x = 0 then false else Even.even (pred x)
 |end
 |
 |and Even : sig
 |  val even : int -> bool
 |end = struct
 |  let even x = if x = 0 then true else Odd.odd (pred x)
 |end
 |
 |let%expect_test _ =
 |  Printf.printf "%b" (Even.even 1000);
 |  [%expect {| true |}];
 |  Printf.printf "%b" (Odd.odd 1000);
-|  [%expect {| false |}]
+|  [%expect {| true |}]

hhugo and others added 3 commits July 5, 2023 14:25
Co-authored-by: Hugo Heuzard <hugo.heuzard@gmail.com>
@mlasson
Copy link
Contributor Author

mlasson commented Jul 5, 2023

I still have:

--- a/_build/default/compiler/tests-jsoo/test_rec_mod.ml
+++ b/_build/.sandbox/0a6bc1e217d6e38b1adcf391b7816958/default/compiler/tests-jsoo/test_rec_mod.ml.corrected
@@ -59,11 +59,11 @@ end

 let%expect_test _ =
   (try print_int (M1.f 3) with e -> print_endline @@ Printexc.to_string e);
-  [%expect {| 2 |}];
+  [%expect {| File "compiler/tests-jsoo/test_rec_mod.ml", line 52, characters 6-12: Undefined recursive module |}];
   (try print_int (M1.g 3) with e -> print_endline @@ Printexc.to_string e);
-  [%expect {| 2 |}];
+  [%expect {| File "compiler/tests-jsoo/test_rec_mod.ml", line 52, characters 6-12: Undefined recursive module |}];
   (try print_int (M1.h 3) with e -> print_endline @@ Printexc.to_string e);
-  [%expect {| 2 |}]
+  [%expect {| File "compiler/tests-jsoo/test_rec_mod.ml", line 52, characters 6-12: Undefined recursive module |}]

But I guess this is expected on 4.12, right ?

@hhugo
Copy link
Member

hhugo commented Jul 5, 2023

I still have:

--- a/_build/default/compiler/tests-jsoo/test_rec_mod.ml
+++ b/_build/.sandbox/0a6bc1e217d6e38b1adcf391b7816958/default/compiler/tests-jsoo/test_rec_mod.ml.corrected
@@ -59,11 +59,11 @@ end

 let%expect_test _ =
   (try print_int (M1.f 3) with e -> print_endline @@ Printexc.to_string e);
-  [%expect {| 2 |}];
+  [%expect {| File "compiler/tests-jsoo/test_rec_mod.ml", line 52, characters 6-12: Undefined recursive module |}];
   (try print_int (M1.g 3) with e -> print_endline @@ Printexc.to_string e);
-  [%expect {| 2 |}];
+  [%expect {| File "compiler/tests-jsoo/test_rec_mod.ml", line 52, characters 6-12: Undefined recursive module |}];
   (try print_int (M1.h 3) with e -> print_endline @@ Printexc.to_string e);
-  [%expect {| 2 |}]
+  [%expect {| File "compiler/tests-jsoo/test_rec_mod.ml", line 52, characters 6-12: Undefined recursive module |}]

But I guess this is expected on 4.12, right ?

Yes, this is expected.

@hhugo hhugo merged commit db77ca4 into ocsigen:master Jul 5, 2023
@hhugo
Copy link
Member

hhugo commented Jul 5, 2023

Merged, thanks again

@mlasson
Copy link
Contributor Author

mlasson commented Jul 5, 2023

Thank you !

hhugo pushed a commit to hhugo/opam-repository that referenced this pull request Jul 6, 2023
…s_of_ocaml-ppx_deriving_json, js_of_ocaml-ppx, js_of_ocaml-lwt and js_of_ocaml-compiler (5.4.0)

CHANGES:

## Bug fixes
* Runtime: Fix recursive modules on ocaml < 4.13 (ocsigen/js_of_ocaml#1485)
* Runtime: fix hashing of NaN (ocsigen/js_of_ocaml#1475)
* Runtime: float rounding should resolve tie away from zero (ocsigen/js_of_ocaml#1475)
* Runtime: fix Gc.stat, Gc.quick_stat, Gc.get (ocsigen/js_of_ocaml#1475)
* Compiler: fix some miscompilation, probably introduced in jsoo 5.0.0,
  revealed by OCaml 5.0
nberth pushed a commit to nberth/opam-repository that referenced this pull request Jun 18, 2024
…s_of_ocaml-ppx_deriving_json, js_of_ocaml-ppx, js_of_ocaml-lwt and js_of_ocaml-compiler (5.4.0)

CHANGES:

## Bug fixes
* Runtime: Fix recursive modules on ocaml < 4.13 (ocsigen/js_of_ocaml#1485)
* Runtime: fix hashing of NaN (ocsigen/js_of_ocaml#1475)
* Runtime: float rounding should resolve tie away from zero (ocsigen/js_of_ocaml#1475)
* Runtime: fix Gc.stat, Gc.quick_stat, Gc.get (ocsigen/js_of_ocaml#1475)
* Compiler: fix some miscompilation, probably introduced in jsoo 5.0.0,
  revealed by OCaml 5.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants