Skip to content

Commit 8da6979

Browse files
authored
Merge pull request #3790 from BuckleScript/local_modules_to_objects
Compile local modules to objects, single commit.
2 parents 93a7a35 + 1115604 commit 8da6979

File tree

127 files changed

+4300
-4001
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

127 files changed

+4300
-4001
lines changed

jscomp/core/j.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ and expression_desc =
140140
This can be constructed either in a static way [E.array_index_by_int] or a dynamic way
141141
[E.array_index]
142142
*)
143-
| Static_index of expression * string
143+
| Static_index of expression * string * int32 option
144144
(* The third argument bool indicates whether we should
145145
print it as
146146
a["idd"] -- false

jscomp/core/js_analyzer.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,11 @@ let rec eq_expression
231231
opts0 = opts1
232232
| _ -> false
233233
end
234-
| Static_index (e0,p0) ->
234+
| Static_index (e0,p0,off0) ->
235235
begin match y0 with
236-
| Static_index(e1,p1) ->
236+
| Static_index(e1,p1,off1) ->
237237
p0 = p1 && eq_expression e0 e1
238+
&& off0 = off1 (* could be relaxed *)
238239
| _ -> false
239240
end
240241
| Seq (a0,b0) ->
@@ -368,5 +369,5 @@ let rec is_okay_to_duplicate (e : J.expression) =
368369
| Bool _
369370
| Str _
370371
| Number _ -> true
371-
| Static_index (e, _s) -> is_okay_to_duplicate e
372+
| Static_index (e, _s,_off) -> is_okay_to_duplicate e
372373
| _ -> false

jscomp/core/js_dump.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,8 @@ and expression_desc cxt (level:int) f x : cxt =
855855
(if identity then e
856856
else
857857
E.runtime_call Js_runtime_modules.option "some" [e])
858+
| Caml_block(el,_, _, Blk_module fields) ->
859+
expression_desc cxt (level:int) f (Object (List.combine fields el))
858860
| Caml_block( el, mutable_flag, tag, tag_info)
859861
->
860862
(* Note that, if we ignore more than tag [0] we loose some information
@@ -949,7 +951,7 @@ and expression_desc cxt (level:int) f x : cxt =
949951
let cxt = expression 15 cxt f e in
950952
P.bracket_group f 1 @@ fun _ ->
951953
expression 0 cxt f p )
952-
| Static_index (e, s) ->
954+
| Static_index (e, s,_) ->
953955
P.cond_paren_group f (level > 15) 1 (fun _ ->
954956
let cxt = expression 15 cxt f e in
955957
Js_dump_property.property_access f s ;

jscomp/core/js_exp_make.ml

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,34 @@ let optional_not_nest_block e : J.expression =
155155
comment = None
156156
}
157157

158+
(** used in normal property
159+
like [e.length], no dependency introduced
160+
*)
161+
let dot ?comment (e0 : t) (e1 : string) : t =
162+
{ expression_desc = Static_index (e0, e1,None); comment}
163+
164+
165+
let module_access (e : t) (name : string) (pos : int32) =
166+
match e.expression_desc with
167+
| Caml_block (l, _, _,_) when no_side_effect e ->
168+
(match Ext_list.nth_opt l (Int32.to_int pos) with
169+
| Some x -> x
170+
| None ->
171+
{ expression_desc = Static_index (e, name,Some pos); comment=None}
172+
)
173+
| _ ->
174+
{ expression_desc = Static_index (e, name,Some pos); comment=None}
175+
176+
158177
let make_block ?comment
159178
(tag : t)
160179
(tag_info : J.tag_info)
161180
(es : t list)
162181
(mutable_flag : J.mutable_flag) : t =
182+
match tag_info with
183+
| Blk_module _ ->
184+
{expression_desc = Caml_block(es,mutable_flag, tag,tag_info); comment}
185+
| _ ->
163186
let comment =
164187
match comment with
165188
| None -> Lam_compile_util.comment_of_tag_info tag_info
@@ -393,12 +416,6 @@ let assign_by_int
393416
assign_by_exp ?comment e0 (int ?comment index) value
394417

395418

396-
(** used in normal property
397-
like [e.length], no dependency introduced
398-
*)
399-
let dot ?comment (e0 : t) (e1 : string) : t =
400-
{ expression_desc = Static_index (e0, e1); comment}
401-
402419

403420

404421

@@ -436,7 +453,7 @@ let function_length ?comment (e : t) : t =
436453

437454
(** no dependency introduced *)
438455
let js_global_dot ?comment (x : string) (e1 : string) : t =
439-
{ expression_desc = Static_index (js_global x, e1); comment}
456+
{ expression_desc = Static_index (js_global x, e1,None); comment}
440457

441458
let char_of_int ?comment (v : t) : t =
442459
match v.expression_desc with

jscomp/core/js_exp_make.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ val is_out : ?comment:string -> t -> t -> t
128128

129129
val dot : ?comment:string -> t -> string -> t
130130

131+
val module_access :
132+
t ->
133+
string ->
134+
int32 ->
135+
t
136+
131137
val array_length : ?comment:string -> t -> t
132138

133139
val string_length : ?comment:string -> t -> t

jscomp/core/js_fold.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class virtual fold =
3131
function
3232
| [] -> o
3333
| _x :: _x_i1 -> let o = _f_a o _x in let o = o#list _f_a _x_i1 in o
34+
method int32 : int32 -> 'self_type = o#unknown
3435
method int : int -> 'self_type = o#unknown
3536
method bool : bool -> 'self_type = function | false -> o | true -> o
3637
method vident : vident -> 'self_type =
@@ -340,8 +341,10 @@ class virtual fold =
340341
let o = o#expression _x in let o = o#expression _x_i1 in o
341342
| Array_index (_x, _x_i1) ->
342343
let o = o#expression _x in let o = o#expression _x_i1 in o
343-
| Static_index (_x, _x_i1) ->
344-
let o = o#expression _x in let o = o#string _x_i1 in o
344+
| Static_index (_x, _x_i1, _x_i2) ->
345+
let o = o#expression _x in
346+
let o = o#string _x_i1 in
347+
let o = o#option (fun o -> o#int32) _x_i2 in o
345348
| New (_x, _x_i1) ->
346349
let o = o#expression _x in
347350
let o = o#option (fun o -> o#list (fun o -> o#expression)) _x_i1

jscomp/core/js_map.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class virtual map =
3434
| _x :: _x_i1 ->
3535
let _x = _f_a o _x in
3636
let _x_i1 = o#list _f_a _x_i1 in _x :: _x_i1
37+
method int32 : int32 -> int32 = o#unknown
3738
method int : int -> int = o#unknown
3839
method bool : bool -> bool = function | false -> false | true -> true
3940
method vident : vident -> vident =
@@ -372,9 +373,11 @@ class virtual map =
372373
| Array_index (_x, _x_i1) ->
373374
let _x = o#expression _x in
374375
let _x_i1 = o#expression _x_i1 in Array_index (_x, _x_i1)
375-
| Static_index (_x, _x_i1) ->
376+
| Static_index (_x, _x_i1, _x_i2) ->
376377
let _x = o#expression _x in
377-
let _x_i1 = o#string _x_i1 in Static_index (_x, _x_i1)
378+
let _x_i1 = o#string _x_i1 in
379+
let _x_i2 = o#option (fun o -> o#int32) _x_i2
380+
in Static_index (_x, _x_i1, _x_i2)
378381
| New (_x, _x_i1) ->
379382
let _x = o#expression _x in
380383
let _x_i1 =

jscomp/core/js_of_lam_block.ml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,17 @@ let make_block mutable_flag (tag_info : Lam_tag_info.t) tag args =
5050

5151
let field (field_info : Lam_compat.field_dbg_info) e i =
5252
match field_info with
53-
| Fld_na ->
54-
E.array_index_by_int e i
53+
| Fld_na ->
54+
(* let comment = "NA" in *)
55+
E.array_index_by_int (* ~comment *) e i
5556
#if OCAML_VERSION =~ ">4.03.0" then
5657
| Fld_record_inline comment
5758
| Fld_record_extension comment
5859
#end
5960
| Fld_record comment
60-
| Fld_module comment
6161
-> E.array_index_by_int ~comment e i
62-
62+
| Fld_module name
63+
-> E.module_access e name i
6364
let field_by_exp e i =
6465
E.array_index e i
6566

jscomp/core/js_pass_flatten_and_mark_dead.ml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,14 @@ let subst_map () = object (self)
238238
let v' = self#expression x in
239239
let match_id =
240240
Ext_ident.create
241-
(Printf.sprintf "%s_%03d"
242-
ident.name i) in
241+
(ident.name ^ "_" ^
242+
(match tag_info with
243+
| Blk_module fields ->
244+
(match Ext_list.nth_opt fields i with
245+
| None -> Printf.sprintf "%03d" i
246+
| Some x -> x )
247+
| _ -> Printf.sprintf "%03d" i
248+
)) in
243249
(i + 1, E.var match_id :: e, (match_id, v') :: acc)) in
244250
let e =
245251
{block with
@@ -267,7 +273,9 @@ let subst_map () = object (self)
267273
method! expression x =
268274
match x.expression_desc with
269275
| Array_index ({expression_desc = Var (Id (id))},
270-
{expression_desc = Number (Int {i; _})}) ->
276+
{expression_desc = Number (Int {i; _})})
277+
| Static_index ({expression_desc = Var (Id (id))}, _, Some i)
278+
->
271279
(match Ident_hashtbl.find_opt self#get_substitution id with
272280
| Some {expression_desc = Caml_block (ls, Immutable, _, _) }
273281
->

jscomp/runtime/caml_module.ml

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,48 @@ type shape =
3636
| Value of Caml_obj_extern.t
3737
(* ATTENTION: check across versions *)
3838
module Array = Caml_array_extern
39+
40+
external set_field : Caml_obj_extern.t -> string -> Caml_obj_extern.t -> unit = ""
41+
[@@bs.set_index]
42+
43+
external get_field : Caml_obj_extern.t -> string -> Caml_obj_extern.t = ""
44+
[@@bs.get_index]
45+
46+
module type Empty = sig end
47+
3948
(** Note that we have to provide a drop in replacement, since compiler internally will
4049
spit out ("CamlinternalMod".[init_mod|update_mod] unless we intercept it
4150
in the lambda layer
4251
*)
4352
let init_mod (loc : string * int * int) (shape : shape) =
4453
let undef_module _ = raise (Undefined_recursive_module loc) in
45-
let rec loop (shape : shape) (struct_ : Caml_obj_extern.t array) idx =
54+
let rec loop (shape : shape) (struct_ : Caml_obj_extern.t) idx =
4655
match shape with
47-
| Function -> struct_.(idx)<-(Obj.magic undef_module)
48-
| Lazy -> struct_.(idx)<- (Obj.magic (lazy undef_module))
49-
| Class ->
50-
struct_.(idx)<-
56+
| Function ->
57+
set_field struct_ idx (Obj.magic undef_module)
58+
| Lazy ->
59+
set_field struct_ idx (Obj.magic (lazy undef_module))
60+
| Class ->
61+
set_field struct_ idx
5162
(Obj.magic (*ref {!CamlinternalOO.dummy_class loc} *)
5263
(undef_module, undef_module, undef_module, 0)
5364
(* depends on dummy class representation *)
54-
)
65+
)
5566
| Module comps
5667
->
57-
let v = (Obj.magic [||]) in
58-
struct_.(idx)<- v ;
68+
let v = Caml_obj_extern.repr (module struct end : Empty) in
69+
set_field struct_ idx v ;
5970
let len = Array.length comps in
60-
for i = 0 to len - 1 do
61-
loop (fst comps.(i)) v i
71+
for i = 0 to len - 1 do
72+
let shape, name = comps.(i) in
73+
loop shape v name
6274
done
6375
| Value v ->
64-
struct_.(idx) <- v in
65-
let res = (Obj.magic [||] : Caml_obj_extern.t array) in
66-
loop shape res 0 ;
67-
res.(0)
76+
set_field struct_ idx v in
77+
let res = Caml_obj_extern.repr (module struct end : Empty) in
78+
let dummy_name = "dummy" in
79+
loop shape res dummy_name;
80+
get_field res dummy_name
6881

6982
(* Note the [shape] passed between [init_mod] and [update_mod] is always the same
7083
and we assume [module] is encoded as an array
@@ -73,19 +86,22 @@ let update_mod (shape : shape) (o : Caml_obj_extern.t) (n : Caml_obj_extern.t)
7386
let rec aux (shape : shape) o n parent i =
7487
match shape with
7588
| Function
76-
-> Caml_obj_extern.set_field parent i n
89+
-> set_field parent i n
90+
7791
| Lazy
7892
| Class ->
7993
Caml_obj.caml_update_dummy o n
8094
| Module comps
8195
->
8296
for i = 0 to Array.length comps - 1 do
83-
aux (fst comps.(i)) (Caml_obj_extern.field o i) (Caml_obj_extern.field n i) o i
97+
let shape, name = comps.(i) in
98+
aux shape (get_field o name ) (get_field n name) o name
8499
done
85100
| Value _ -> () in
86101
match shape with
87102
| Module comps ->
88-
for i = 0 to Array.length comps - 1 do
89-
aux (fst comps.(i)) (Caml_obj_extern.field o i) (Caml_obj_extern.field n i) o i
103+
for i = 0 to Array.length comps - 1 do
104+
let shape, name = comps.(i) in
105+
aux shape (get_field o name) (get_field n name) o name
90106
done
91107
| _ -> assert false

0 commit comments

Comments
 (0)