Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions jscomp/runtime/caml_module.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@ type shape =
| Module of shape array
| Value of Caml_obj_extern.t
(* ATTENTION: check across versions *)

module Array = Caml_array_extern
(** Note that we have to provide a drop in replacement, since compiler internally will
spit out ("CamlinternalMod".[init_mod|update_mod] unless we intercept it
in the lambda layer
*)
let init_mod (loc : string * int * int) (shape : shape) =
let module Array = Caml_array_extern in
let init_mod (loc : string * int * int) (shape : shape) =
let undef_module _ = raise (Undefined_recursive_module loc) in
let rec loop (shape : shape) (struct_ : Caml_obj_extern.t array) idx =
match shape with
Expand All @@ -67,17 +66,14 @@ let init_mod (loc : string * int * int) (shape : shape) =
loop shape res 0 ;
res.(0)


(* Note the [shape] passed between [init_mod] and [update_mod] is always the same
and we assume [module] is encoded as an array
*)
let update_mod (shape : shape) (o : Caml_obj_extern.t) (n : Caml_obj_extern.t) : unit =
let module Array = Caml_array_extern in
let rec aux (shape : shape) o n parent i =
match shape with
| Function
-> Caml_obj_extern.set_field parent i n

| Lazy
| Class ->
Caml_obj.caml_update_dummy o n
Expand Down
84 changes: 78 additions & 6 deletions jscomp/test/recursive_module.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
'use strict';

var Mt = require("./mt.js");
var Lazy = require("../../lib/js/lazy.js");
var Curry = require("../../lib/js/curry.js");
var Caml_obj = require("../../lib/js/caml_obj.js");
var Caml_module = require("../../lib/js/caml_module.js");
var CamlinternalLazy = require("../../lib/js/camlinternalLazy.js");
var Caml_js_exceptions = require("../../lib/js/caml_js_exceptions.js");
var Caml_builtin_exceptions = require("../../lib/js/caml_builtin_exceptions.js");

Expand Down Expand Up @@ -42,22 +45,88 @@ var Int3 = Caml_module.init_mod([

Caml_module.update_mod([[0]], Int3, Int3);

var Inta = Caml_module.init_mod([
"recursive_module.ml",
23,
6
], [[1]]);

var Intb = Caml_module.init_mod([
"recursive_module.ml",
28,
6
], [[1]]);

var a = Caml_obj.caml_lazy_make((function (param) {
return CamlinternalLazy.force(Intb[/* a */0]);
}));

Caml_module.update_mod([[1]], Inta, /* module */[/* a */a]);

var a$1 = Caml_obj.caml_lazy_make((function (param) {
return CamlinternalLazy.force(Inta[/* a */0]) + 1 | 0;
}));

Caml_module.update_mod([[1]], Intb, /* module */[/* a */a$1]);

var tmp;

try {
tmp = CamlinternalLazy.force(Intb[/* a */0]);
}
catch (exn){
if (exn === Lazy.Undefined) {
tmp = -1;
} else {
throw exn;
}
}

eq("File \"recursive_module.ml\", line 33, characters 3-10", -1, tmp);

var Inta$1 = Caml_module.init_mod([
"recursive_module.ml",
40,
8
], [[1]]);

var Intb$1 = Caml_module.init_mod([
"recursive_module.ml",
45,
8
], [[1]]);

var a$2 = Caml_obj.caml_lazy_make((function (param) {
return CamlinternalLazy.force(Intb$1[/* a */0]) + 1 | 0;
}));

Caml_module.update_mod([[1]], Inta$1, /* module */[/* a */a$2]);

Caml_module.update_mod([[1]], Intb$1, /* module */[/* a */2]);

var A = /* module */[
/* Inta */Inta$1,
/* Intb */Intb$1
];

eq("File \"recursive_module.ml\", line 50, characters 6-13", CamlinternalLazy.force(Inta$1[/* a */0]), 3);

var tmp$1;

try {
Curry._1(Int3[/* u */0], 3);
tmp = 3;
tmp$1 = 3;
}
catch (raw_exn){
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
if (exn[0] === Caml_builtin_exceptions.undefined_recursive_module) {
tmp = 4;
var exn$1 = Caml_js_exceptions.internalToOCamlException(raw_exn);
if (exn$1[0] === Caml_builtin_exceptions.undefined_recursive_module) {
tmp$1 = 4;
} else {
throw exn;
throw exn$1;
}
}

eq("File \"recursive_module.ml\", line 24, characters 6-13", 4, tmp);
eq("File \"recursive_module.ml\", line 52, characters 6-13", 4, tmp$1);

Mt.from_pair_suites("Recursive_module", suites[0]);

Expand All @@ -66,4 +135,7 @@ exports.test_id = test_id;
exports.eq = eq;
exports.Int32 = Int32;
exports.Int3 = Int3;
exports.Inta = Inta;
exports.Intb = Intb;
exports.A = A;
/* Int32 Not a pure module */
32 changes: 30 additions & 2 deletions jscomp/test/recursive_module.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,36 @@ module rec Int3 : sig
val u : int -> int
end = Int3



module rec Inta : sig
val a : int lazy_t
end = struct
let a = lazy (Lazy.force Intb.a)
end
and Intb : sig
val a : int lazy_t
end = struct
let a = lazy (Lazy.force Inta.a + 1)
end

;;
eq __LOC__
(-1)
(try Lazy.force (Intb.a) with Lazy.Undefined -> -1)

module A = struct
module rec Inta : sig
val a : int lazy_t
end = struct
let a = lazy (Lazy.force Intb.a + 1)
end
and Intb : sig
val a : int lazy_t
end = struct
let a = lazy 2
end
end

;; eq __LOC__ (Lazy.force A.Inta.a) 3
(* expect raise Undefined_recursive_module *)
;; eq __LOC__ 4
(try ignore (Int3.u 3); 3
Expand Down
4 changes: 2 additions & 2 deletions lib/js/caml_module.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function update_mod(shape, o, n) {
Caml_builtin_exceptions.assert_failure,
/* tuple */[
"caml_module.ml",
95,
91,
10
]
];
Expand All @@ -82,7 +82,7 @@ function update_mod(shape, o, n) {
Caml_builtin_exceptions.assert_failure,
/* tuple */[
"caml_module.ml",
95,
91,
10
]
];
Expand Down