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

Compiler: modernize js parser #1391

Merged
merged 7 commits into from
Feb 1, 2023
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
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Compiler: Cache function arity (the length prop of a function is slow with v8)
* Compiler: The js lexer is now utf8 aware, recognize and emit utf8 ident
* Compiler: Update the js lexer with new number literal syntax
* Compiler: update js parser to support most es6 feature (#1391)

## Bug fixes
- Effects: fix Js.export and Js.export_all to work with functions
Expand Down
9 changes: 6 additions & 3 deletions compiler/bin-jsoo_minify/jsoo_minify.ml
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,13 @@ let f { Cmd_arg.common; output_file; use_stdin; files } =
let free = new Js_traverse.free in
let (_ : Javascript.program) = free#program p in
let toplevel_def_and_use =
Utf8_string_set.union free#get_def_name free#get_use_name
let state = free#state in
Javascript.IdentSet.union state.def_var state.use
in
Utf8_string_set.iter
(fun (Utf8_string.Utf8 x) -> Var_printer.add_reserved x)
Javascript.IdentSet.iter
(function
| V _ -> ()
| S { name = Utf8_string.Utf8 x; _ } -> Var_printer.add_reserved x)
toplevel_def_and_use;
let true_ () = true in
let open Config in
Expand Down
126 changes: 66 additions & 60 deletions compiler/lib/driver.ml
Original file line number Diff line number Diff line change
Expand Up @@ -208,33 +208,30 @@ let gen_missing js missing =
let prim = Utf8_string.of_string_exn prim in
let p = ident prim in
( p
, Some
( ECond
( EBin
( NotEqEq
, EDot (EVar (ident Constant.global_object_), prim)
, EVar (ident_s "undefined") )
, EDot (EVar (ident Constant.global_object_), prim)
, EFun
( None
, []
, [ ( Statement
(Expression_statement
(ECall
( EVar (ident_s "caml_failwith")
, [ ( EBin
( Plus
, EStr prim
, EStr
(Utf8_string.of_string_exn
" not implemented") )
, `Not_spread )
]
, N )))
, ( ECond
( EBin
( NotEqEq
, dot (EVar (ident Constant.global_object_)) prim
, EVar (ident_s "undefined") )
, dot (EVar (ident Constant.global_object_)) prim
, EFun
( None
, fun_
[]
[ ( Expression_statement
(call
(EVar (ident_s "caml_failwith"))
[ EBin
( Plus
, EStr prim
, EStr (Utf8_string.of_string_exn " not implemented")
)
]
N)
, N )
]
, N ) )
, N ) )
N ) )
, N ) )
:: acc)
missing
[]
Expand All @@ -247,11 +244,11 @@ let gen_missing js missing =
warn "You can prevent the generation of dummy implementations with ";
warn "the commandline option '--disable genprim'@.";
report_missing_primitives missing);
(Statement (Variable_statement miss), N) :: js
(variable_declaration miss, N) :: js

let mark_start_of_generated_code = Debug.find ~even_if_quiet:true "mark-runtime-gen"

let link ~standalone ~linkall (js : Javascript.source_elements) : Linker.output =
let link ~standalone ~linkall (js : Javascript.statement_list) : Linker.output =
if not standalone
then { runtime_code = js; always_required_codes = [] }
else
Expand All @@ -263,18 +260,22 @@ let link ~standalone ~linkall (js : Javascript.source_elements) : Linker.output
if mark_start_of_generated_code ()
then
let open Javascript in
( Statement
(Expression_statement
(EStr
(Utf8_string.of_string_exn
("--MARK--" ^ "start-of-jsoo-gen" ^ "--MARK--"))))
( Expression_statement
(EStr
(Utf8_string.of_string_exn ("--MARK--" ^ "start-of-jsoo-gen" ^ "--MARK--")))
, N )
:: js
else js
in
let free = traverse#get_free_name in
let free = traverse#get_free in
let free : StringSet.t =
Utf8_string_set.fold (fun (Utf8 x) acc -> StringSet.add x acc) free StringSet.empty
Javascript.IdentSet.fold
(fun x acc ->
match x with
| V _ -> assert false
| S { name = Utf8 x; _ } -> StringSet.add x acc)
free
StringSet.empty
in
let prim = Primitive.get_external () in
let prov = Linker.get_provided () in
Expand Down Expand Up @@ -302,16 +303,15 @@ let link ~standalone ~linkall (js : Javascript.source_elements) : Linker.output
let all =
List.map all ~f:(fun name ->
let name = Utf8_string.of_string_exn name in
PNI name, EVar (ident name))
Property (PNI name, EVar (ident name)))
in
( Statement
(Expression_statement
(EBin
( Eq
, EDot
( EVar (ident Constant.global_object_)
, Utf8_string.of_string_exn "jsoo_runtime" )
, EObj all )))
( Expression_statement
(EBin
( Eq
, dot
(EVar (ident Constant.global_object_))
(Utf8_string.of_string_exn "jsoo_runtime")
, EObj all ))
, N )
:: js
else js
Expand All @@ -323,9 +323,15 @@ let check_js js =
if times () then Format.eprintf "Start Checks...@.";
let traverse = new Js_traverse.free in
let js = traverse#program js in
let free = traverse#get_free_name in
let free = traverse#get_free in
let free : StringSet.t =
Utf8_string_set.fold (fun (Utf8 x) acc -> StringSet.add x acc) free StringSet.empty
Javascript.IdentSet.fold
(fun x acc ->
match x with
| V _ -> assert false
| S { name = Utf8 x; _ } -> StringSet.add x acc)
free
StringSet.empty
in
let prim = Primitive.get_external () in
let prov = Linker.get_provided () in
Expand Down Expand Up @@ -354,8 +360,13 @@ let coloring js =
if times () then Format.eprintf "Start Coloring...@.";
let traverse = new Js_traverse.free in
let js = traverse#program js in
let free = traverse#get_free_name in
Utf8_string_set.iter (fun (Utf8 x) -> Var_printer.add_reserved x) free;
let free = traverse#get_free in
Javascript.IdentSet.iter
(fun x ->
match x with
| V _ -> assert false
| S { name = Utf8 x; _ } -> Var_printer.add_reserved x)
free;
let js = Js_assign.program js in
if times () then Format.eprintf " coloring: %a@." Timer.print t;
js
Expand Down Expand Up @@ -393,17 +404,15 @@ let pack ~wrap_with_fun ~standalone { Linker.runtime_code = js; always_required_
in
(* pack *)
let wrap_in_iife ~use_strict js =
let var ident e =
J.Statement (J.Variable_statement [ J.ident ident, Some (e, J.N) ]), J.N
in
let expr e = J.Statement (J.Expression_statement e), J.N in
let var ident e = J.variable_declaration [ J.ident ident, (e, J.N) ], J.N in
let expr e = J.Expression_statement e, J.N in
let freenames =
let o = new Js_traverse.free in
let (_ : J.program) = o#program js in
o#get_free_name
o#get_free
in
let export_shim js =
if Utf8_string_set.mem Constant.exports_ freenames
if J.IdentSet.mem (J.ident Constant.exports_) freenames
then
if should_export wrap_with_fun
then var Constant.exports_ (J.EObj []) :: js
Expand All @@ -421,14 +430,14 @@ let pack ~wrap_with_fun ~standalone { Linker.runtime_code = js; always_required_
else js
in
let old_global_object_shim js =
if Utf8_string_set.mem Constant.old_global_object_ freenames
if J.IdentSet.mem (J.ident Constant.old_global_object_) freenames
then
var Constant.old_global_object_ (J.EVar (J.ident Constant.global_object_)) :: js
else js
in

let efun args body = J.EFun (None, args, body, J.U) in
let sfun name args body = J.Function_declaration (name, args, body, J.U), J.U in
let efun args body = J.EFun (None, J.fun_ args body J.U) in
let sfun name args body = J.Function_declaration (name, J.fun_ args body J.U), J.U in
let mk f =
let js = export_shim js in
let js = old_global_object_shim js in
Expand All @@ -444,10 +453,7 @@ let pack ~wrap_with_fun ~standalone { Linker.runtime_code = js; always_required_
| `Named name ->
let name = Utf8_string.of_string_exn name in
mk (sfun (J.ident name))
| `Iife ->
expr
(J.ECall
(mk efun, [ J.EVar (J.ident Constant.global_object_), `Not_spread ], J.N))
| `Iife -> expr (J.call (mk efun) [ J.EVar (J.ident Constant.global_object_) ] J.N)
in
let always_required_js =
(* consider adding a comments in the generated file with original
Expand Down
24 changes: 1 addition & 23 deletions compiler/lib/dune
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,7 @@
--unused-token
T_ERROR
--unused-token
T_AT
--unused-token
T_POUND
--unused-token
T_PLING_PERIOD
--unused-token
T_PLING_PLING
--unused-token
T_OR_ASSIGN
--unused-token
T_AND_ASSIGN
--unused-token
T_NULLISH_ASSIGN
--unused-token
T_EXP
--unused-token
T_EXP_ASSIGN
--unused-token
T_ARROW
--unused-token
T_BIGINT
--unused-token
T_TEMPLATE_PART))
T_AT))

(menhir
(modules annot_parser)
Expand Down
Loading