Skip to content

Commit 535d212

Browse files
author
Hongbo Zhang
committed
use new runtime encoding, support lazy and recursive modules
1 parent 7000eca commit 535d212

File tree

239 files changed

+17488
-16411
lines changed

Some content is hidden

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

239 files changed

+17488
-16411
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,5 @@ jscomp/bench/*.js
5050
.vscode
5151
*.jsx
5252
osc
53-
jscomp/pre_load.js
53+
jscomp/pre_load.js
54+
boot

jscomp/compiler.mllib

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ js_of_lam_tuple
8181
js_of_lam_string
8282
js_of_lam_block
8383
js_of_lam_array
84+
js_of_lam_module
85+
js_of_lam_exception
8486
js_implementation
8587
js_closure
8688
js_op
@@ -93,3 +95,4 @@ js_number
9395
js_helper
9496
js_cmj_datasets
9597
js_main
98+

jscomp/j.ml

+27-2
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ and ident_info = Js_op.ident_info
4747

4848
and exports = Js_op.exports
4949

50+
and tag_info = Js_op.tag_info
51+
5052
and required_modules = Js_op.required_modules
5153

5254
(** object literal, if key is ident, in this case, it might be renamed by
5355
Google Closure optimizer,
5456
currently we always use quote
5557
*)
56-
and property_name = string
58+
and property_name = Js_op.property_name
5759

5860
and ident = Ident.t
5961

@@ -101,8 +103,9 @@ and expression_desc =
101103
*)
102104
| Array_copy of expression (* shallow copy, like [x.slice] *)
103105
| Array_append of expression * expression (* For [caml_array_append]*)
104-
| Tag_ml_obj of expression
106+
(* | Tag_ml_obj of expression *)
105107
| String_append of expression * expression
108+
106109
| Int_of_boolean of expression
107110
(* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
108111
[typeof] is an operator
@@ -201,6 +204,28 @@ and expression_desc =
201204
which is better to leave it alone
202205
*)
203206
| Array of expression list * mutable_flag
207+
| Caml_block of expression list * mutable_flag * expression * tag_info
208+
209+
| Caml_uninitialized_obj of expression * expression
210+
(* [tag] and [size] tailed for [Obj.new_block] *)
211+
212+
(* For setter, it still return the value of expression,
213+
we can not use
214+
{[
215+
type 'a access = Get | Set of 'a
216+
]}
217+
in another module, since it will break our code generator
218+
[Caml_block_tag] can return [undefined],
219+
you have to use [E.tag] in a safe way
220+
*)
221+
| Caml_block_tag of expression
222+
| Caml_block_set_tag of expression * expression
223+
| Caml_block_length of expression
224+
| Caml_block_set_length of expression * expression
225+
(* It will just fetch tag, to make it safe, when creating it,
226+
we need apply "|0", we don't do it in the
227+
last step since "|0" can potentially be optimized
228+
*)
204229
| Number of number
205230
| Object of property_map
206231

jscomp/js_analyzer.ml

+48-1
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,52 @@ let rec no_side_effect (x : J.expression) =
7979
| Fun _ -> true
8080
| Number _ -> true (* Can be refined later *)
8181
| Array (xs,_mutable_flag)
82+
| Caml_block (xs, _mutable_flag, _, _)
8283
->
8384
(** create [immutable] block,
8485
does not really mean that this opreation itself is [pure].
8586
8687
the block is mutable does not mean this operation is non-pure
8788
*)
8889
List.for_all no_side_effect xs
90+
| Array_append (a,b)
91+
| String_append (a,b)
8992
| Seq (a,b) -> no_side_effect a && no_side_effect b
90-
| _ -> false
93+
| Caml_block_length e
94+
| Array_length e
95+
| String_length e
96+
| Bytes_length e
97+
| Function_length e
98+
| Char_of_int e
99+
| Char_to_int e
100+
| Caml_block_tag e
101+
| Typeof e
102+
-> no_side_effect e
103+
| Bin (op, a, b) ->
104+
op != Eq && no_side_effect a && no_side_effect b
105+
| Math _
106+
| Array_of_size _
107+
| Array_copy _
108+
(* | Tag_ml_obj _ *)
109+
| Int_of_boolean _
110+
111+
| Not _
112+
| String_of_small_int_array _
113+
| Json_stringify _
114+
| Anything_to_string _
115+
| Dump _
116+
| Cond _
117+
118+
| FlatCall _
119+
| Call _
120+
| Dot _
121+
| New _
122+
| Caml_uninitialized_obj _
123+
| String_access _
124+
| Object _
125+
| Caml_block_set_tag _
126+
| Caml_block_set_length _ (* actually true? *)
127+
-> false
91128

92129
let no_side_effect_expression (x : J.expression) = no_side_effect x
93130

@@ -181,3 +218,13 @@ let rev_toplevel_flatten block =
181218

182219
| x :: xs -> aux (x :: acc) xs in
183220
aux [] block
221+
222+
let rec is_constant (x : J.expression) =
223+
match x.expression_desc with
224+
| Access (a,b) -> is_constant a && is_constant b
225+
| Str (b,_) -> b
226+
| Number _ -> true (* Can be refined later *)
227+
| Array (xs,_mutable_flag) -> List.for_all is_constant xs
228+
| Caml_block(xs, Immutable, tag, _)
229+
-> List.for_all is_constant xs && is_constant tag
230+
| _ -> false

jscomp/js_analyzer.mli

+2
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,5 @@ val rev_flatten_seq : J.expression -> J.block
6060

6161
val rev_toplevel_flatten : J.block -> J.block
6262
(** return the block in reverse order *)
63+
64+
val is_constant : J.expression -> bool

jscomp/js_config.ml

+6-4
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ let stdlib_set = String_set.of_list [
8585
let runtime_set = String_set.of_list [
8686
"caml_array.js";
8787
"caml_float.js";
88-
"caml_obj_runtime.js";
88+
"caml_obj.js";
8989
"caml_bigarray.js";
9090
"caml_format.js";
9191
"caml_oo.js";
@@ -98,6 +98,7 @@ let runtime_set = String_set.of_list [
9898
"caml_curry.js";
9999
"caml_file.js";
100100
"caml_lexer.js";
101+
"caml_parser.js";
101102
"caml_string.js"
102103
(* "caml_sys.js"; *)
103104
(* "caml_unix.js"; *)
@@ -114,9 +115,9 @@ let io = "Caml_io"
114115

115116
let sys = "Caml_sys"
116117

117-
let lex_parse = "Caml_lexer"
118-
119-
let obj_runtime = "Caml_obj_runtime"
118+
let lexer = "Caml_lexer"
119+
let parser = "Caml_parser"
120+
let obj_runtime = "Caml_obj"
120121

121122
let array = "Caml_array"
122123

@@ -128,3 +129,4 @@ let float = "Caml_float"
128129

129130
let oo = "Caml_oo"
130131
let curry = "Caml_curry"
132+
let internalMod = "Caml_internalMod"

jscomp/js_config.mli

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ val oo : string
4040

4141
val sys : string
4242

43-
val lex_parse : string
44-
43+
val lexer : string
44+
val parser : string
4545
val obj_runtime : string
4646

4747
val array : string
@@ -54,5 +54,5 @@ val float : string
5454

5555
val curry : string
5656

57-
57+
val internalMod : string
5858

jscomp/js_dump.ml

+86-26
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ module L = struct
8989
let strict_directive = "'use strict';"
9090

9191
let curry = "curry" (* curry arbitrary args *)
92+
let tag = "tag"
9293
end
9394
let return_indent = (String.length L.return / Ext_pp.indent_length)
9495

@@ -420,17 +421,17 @@ and
420421
if l > 15 then P.paren_group f 1 action
421422
else action ()
422423

423-
| Tag_ml_obj e ->
424-
P.group f 1 (fun _ ->
425-
P.string f "Object.defineProperty";
426-
P.paren_group f 1 (fun _ ->
427-
let cxt = expression 1 cxt f e in
428-
P.string f L.comma;
429-
P.space f ;
430-
P.string f {|"##ml"|};
431-
P.string f L.comma;
432-
P.string f {|{"value" : true, "writable" : false}|} ;
433-
cxt ))
424+
(* | Tag_ml_obj e -> *)
425+
(* P.group f 1 (fun _ -> *)
426+
(* P.string f "Object.defineProperty"; *)
427+
(* P.paren_group f 1 (fun _ -> *)
428+
(* let cxt = expression 1 cxt f e in *)
429+
(* P.string f L.comma; *)
430+
(* P.space f ; *)
431+
(* P.string f {|"##ml"|}; *)
432+
(* P.string f L.comma; *)
433+
(* P.string f {|{"value" : true, "writable" : false}|} ; *)
434+
(* cxt )) *)
434435

435436
| FlatCall(e,el) ->
436437
P.group f 1 (fun _ ->
@@ -580,6 +581,18 @@ and
580581
P.string f "typeof";
581582
P.space f;
582583
expression 13 cxt f e
584+
| Caml_block_set_tag(a,b) ->
585+
expression_desc cxt l f
586+
(Bin(Eq,
587+
{expression_desc = Caml_block_tag a; comment = None},
588+
b
589+
))
590+
| Caml_block_set_length(a,b) ->
591+
expression_desc cxt l f
592+
(Bin(Eq,
593+
{expression_desc = Caml_block_length a; comment = None},
594+
b
595+
))
583596
| Bin (Eq, {expression_desc = Var i },
584597
{expression_desc =
585598
(
@@ -744,7 +757,45 @@ and
744757
| []| [ _ ] -> P.bracket_group f 1 @@ fun _ -> array_element_list cxt f el
745758
| _ -> P.bracket_vgroup f 1 @@ fun _ -> array_element_list cxt f el
746759
end
760+
| Caml_uninitialized_obj (tag, size)
761+
->
762+
expression_desc cxt l f (Object [Length, size ; Tag, tag])
763+
| Caml_block( el, mutable_flag, tag, tag_info)
764+
->
765+
(* Note that, if we ignore more than tag [0] we loose some information
766+
with regard tag *)
767+
begin match tag.expression_desc, tag_info with
768+
769+
| Number (Int { i = 0 ; _}) ,
770+
(Tuple | Array | Variant _ | Record | NA
771+
| Constructor ("Some" | "::"))
772+
(* Hack to optimize option which is really pervasive in ocaml,
773+
we need concrete benchmark to support this
774+
*)
775+
-> expression_desc cxt l f (Array (el, mutable_flag))
776+
(* TODO: for numbers like 248, 255 we can reverse engineer to make it
777+
[Obj.xx_flag], but we can not do this in runtime libraries
778+
*)
747779

780+
| _, _
781+
->
782+
expression_desc cxt l f
783+
(J.Object (
784+
let length, rev_list =
785+
List.fold_left (fun (i,acc) v ->
786+
(i+1, (Js_op.Int_key i, v) :: acc)
787+
) (0, []) el in
788+
List.rev_append rev_list
789+
[(Js_op.Length, E.int length) ; (Js_op.Tag, tag)]
790+
)
791+
)
792+
end
793+
| Caml_block_tag e ->
794+
P.group f 1 (fun _ ->
795+
let cxt = expression 15 cxt f e in
796+
P.string f L.dot ;
797+
P.string f L.tag ;
798+
cxt)
748799
| Access (e, e')
749800

750801
| String_access (e,e')
@@ -757,7 +808,8 @@ and
757808
in
758809
if l > 15 then P.paren_group f 1 action else action ()
759810

760-
| Array_length e | String_length e | Bytes_length e | Function_length e ->
811+
| Array_length e | String_length e | Bytes_length e
812+
| Function_length e | Caml_block_length e ->
761813
let action () = (** Todo: check parens *)
762814
let cxt = expression 15 cxt f e in
763815
P.string f L.dot;
@@ -840,24 +892,27 @@ and
840892
P.brace_vgroup f 1 @@ fun _ ->
841893
property_name_and_value_list cxt f lst
842894

843-
and property_name cxt f (s : J.property_name) : Ext_pp_scope.t =
844-
pp_string f ~utf:true ~quote:(best_string_quote s) s; cxt
895+
and property_name cxt f (s : J.property_name) : unit =
896+
match s with
897+
| Tag -> P.string f L.tag
898+
| Length -> P.string f L.length
899+
| Key s ->
900+
pp_string f ~utf:true ~quote:(best_string_quote s) s
901+
| Int_key i -> P.string f (string_of_int i)
845902

846903
and property_name_and_value_list cxt f l : Ext_pp_scope.t =
847904
match l with
848905
| [] -> cxt
849906
| [(pn, e)] ->
850-
P.group f 0 @@ fun _ ->
851-
let cxt = property_name cxt f pn in
852-
P.string f L.colon;
853-
P.space f;
854-
expression 1 cxt f e
907+
property_name cxt f pn ;
908+
P.string f L.colon;
909+
P.space f;
910+
expression 1 cxt f e
855911
| (pn, e) :: r ->
856-
let cxt = P.group f 0 @@ fun _ ->
857-
let cxt = property_name cxt f pn in
858-
P.string f L.colon;
859-
P.space f;
860-
expression 1 cxt f e in
912+
property_name cxt f pn ;
913+
P.string f L.colon;
914+
P.space f;
915+
let cxt = expression 1 cxt f e in
861916
P.string f L.comma;
862917
P.newline f;
863918
property_name_and_value_list cxt f r
@@ -973,14 +1028,18 @@ and statement_desc top cxt f (s : J.statement_desc) : Ext_pp_scope.t =
9731028
let rec need_paren (e : J.expression) =
9741029
match e.expression_desc with
9751030
| Call ({expression_desc = Fun _; },_,_) -> true
976-
1031+
| Caml_uninitialized_obj _
9771032
| Fun _ | Object _ -> true
1033+
| Caml_block_set_tag _
1034+
| Caml_block_length _
1035+
| Caml_block_set_length _
9781036
| Anything_to_string _
9791037
| String_of_small_int_array _
9801038
| Call _
9811039
| Array_append _
9821040
| Array_copy _
983-
| Tag_ml_obj _
1041+
(* | Tag_ml_obj _ *)
1042+
| Caml_block_tag _
9841043
| Seq _
9851044
| Dot _
9861045
| Cond _
@@ -1000,6 +1059,7 @@ and statement_desc top cxt f (s : J.statement_desc) : Ext_pp_scope.t =
10001059
| Var _
10011060
| Str _
10021061
| Array _
1062+
| Caml_block _
10031063
| FlatCall _
10041064
| Typeof _
10051065
| Function_length _

0 commit comments

Comments
 (0)