Skip to content

Commit

Permalink
Thread more locations through primitive nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
anmonteiro committed Nov 16, 2022
1 parent 96b7e9d commit c5c8d47
Show file tree
Hide file tree
Showing 17 changed files with 417 additions and 315 deletions.
4 changes: 2 additions & 2 deletions jscomp/core/js_dump.ml
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ and array_element_list cxt (el : E.t list) : cxt =
and arguments cxt (l : E.t list) : cxt =
iter_lst cxt l (expression ~level:1) comma_sp

and variable_declaration top cxt (variable : J.variable_declaration) : cxt =
and variable_declaration ~top cxt (variable : J.variable_declaration) : cxt =
(* TODO: print [const/var] for different backends *)
match variable with
| { ident = i; value = None; ident_info; _ } ->
Expand Down Expand Up @@ -997,7 +997,7 @@ and statement_desc top cxt (s : J.statement_desc) : cxt =
let cxt = statements top cxt b in
ipp_comment cxt L.end_block;
cxt
| Variable l -> variable_declaration top cxt l
| Variable l -> variable_declaration ~top cxt l
| If (e, s1, s2) -> (
(* TODO: always brace those statements *)
string cxt L.if_;
Expand Down
52 changes: 27 additions & 25 deletions jscomp/core/js_exp_make.ml
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ let ml_module_as_var ?loc ?comment (id : Ident.t) : t =
make_expression ?loc ?comment (Var (Qualified ({ id; kind = Ml }, None)))

(* Static_index .....................*)
let runtime_call module_name fn_name args =
call ~info:Js_call_info.builtin_runtime_call
let runtime_call ?loc module_name fn_name args =
call ?loc ~info:Js_call_info.builtin_runtime_call
(runtime_var_dot module_name fn_name)
args

Expand All @@ -117,7 +117,8 @@ let pure_runtime_call ?loc module_name fn_name args =
(runtime_var_dot module_name fn_name)
args

let runtime_ref module_name fn_name = runtime_var_dot module_name fn_name
let runtime_ref ?loc module_name fn_name =
runtime_var_dot ?loc module_name fn_name

let str ?(pure = true) ?loc ?comment s : t =
make_expression ?loc ?comment (Str (pure, s))
Expand All @@ -133,11 +134,11 @@ let array ?loc ?comment mt es : t =

let some_comment = None

let optional_block e : J.expression =
make_expression ?comment:some_comment (Optional_block (e, false))
let optional_block ?loc e : J.expression =
make_expression ?loc ?comment:some_comment (Optional_block (e, false))

let optional_not_nest_block e : J.expression =
make_expression (Optional_block (e, true))
let optional_not_nest_block ?loc e : J.expression =
make_expression ?loc (Optional_block (e, true))

(* used in normal property
like [e.length], no dependency introduced
Expand Down Expand Up @@ -592,7 +593,7 @@ let or_ ?loc ?comment (e1 : t) (e2 : t) =
(* TODO:
when comparison with Int
it is right that !(x > 3 ) -> x <= 3 *)
let not (e : t) : t =
let not ?loc (e : t) : t =
match e.expression_desc with
| Number (Int { i; _ }) -> bool (i = 0l)
| Js_not e -> e
Expand All @@ -603,7 +604,7 @@ let not (e : t) : t =
| Bin (Ge, a, b) -> { e with expression_desc = Bin (Lt, a, b) }
| Bin (Le, a, b) -> { e with expression_desc = Bin (Gt, a, b) }
| Bin (Gt, a, b) -> { e with expression_desc = Bin (Le, a, b) }
| _ -> make_expression (Js_not e)
| _ -> make_expression ?loc (Js_not e)

let not_empty_branch (x : t) =
match x.expression_desc with
Expand Down Expand Up @@ -720,15 +721,15 @@ let tag ?loc ?comment e : t =
it's reduced to 31 bits for hash
*)
(* FIXME: unused meth_name *)
let public_method_call _meth_name obj label cache args =
let public_method_call ?loc _meth_name obj label cache args =
let len = List.length args in
(* econd (int_equal (tag obj ) obj_int_tag_literal) *)
if len <= 7 then
runtime_call Js_runtime_modules.caml_oo_curry
runtime_call ?loc Js_runtime_modules.caml_oo_curry
("js" ^ string_of_int (len + 1))
(label :: int cache :: obj :: args)
else
runtime_call Js_runtime_modules.caml_oo_curry "js"
runtime_call ?loc Js_runtime_modules.caml_oo_curry "js"
[ label; int cache; obj; array NA (obj :: args) ]

(* TODO: handle arbitrary length of args ..
Expand Down Expand Up @@ -926,10 +927,10 @@ let to_uint32 ?loc ?comment (e : J.expression) : J.expression =
we can apply a more general optimization here,
do some algebraic rewerite rules to rewrite [triple_equal]
*)
let rec is_out ?comment (e : t) (range : t) : t =
let rec is_out ?loc ?comment (e : t) (range : t) : t =
match (range.expression_desc, e.expression_desc) with
| Number (Int { i = 1l }), Var _ ->
not
not ?loc
(or_ (triple_equal e zero_int_literal) (triple_equal e one_int_literal))
| ( Number (Int { i = 1l }),
( Bin
Expand All @@ -940,7 +941,7 @@ let rec is_out ?comment (e : t) (range : t) : t =
( Plus,
({ expression_desc = Var _; _ } as x),
{ expression_desc = Number (Int { i; _ }) } ) ) ) ->
not
not ?loc
(or_
(triple_equal x (int (Int32.neg i)))
(triple_equal x (int (Int32.sub Int32.one i))))
Expand All @@ -949,19 +950,20 @@ let rec is_out ?comment (e : t) (range : t) : t =
( Minus,
({ expression_desc = Var _; _ } as x),
{ expression_desc = Number (Int { i; _ }) } ) ) ->
not (or_ (triple_equal x (int (Int32.add i 1l))) (triple_equal x (int i)))
not ?loc
(or_ (triple_equal x (int (Int32.add i 1l))) (triple_equal x (int i)))
(* (x - i >>> 0 ) > k *)
| ( Number (Int { i = k }),
Bin
( Minus,
({ expression_desc = Var _; _ } as x),
{ expression_desc = Number (Int { i; _ }) } ) ) ->
or_ (int_comp Cgt x (int (Int32.add i k))) (int_comp Clt x (int i))
or_ ?loc (int_comp Cgt x (int (Int32.add i k))) (int_comp Clt x (int i))
| Number (Int { i = k }), Var _ ->
(* Note that js support [ 1 < x < 3],
we can optimize it into [ not ( 0<= x <= k)]
*)
or_ (int_comp Cgt e (int k)) (int_comp Clt e zero_int_literal)
or_ ?loc (int_comp Cgt e (int k)) (int_comp Clt e zero_int_literal)
| ( _,
Bin
( Bor,
Expand All @@ -978,8 +980,8 @@ let rec is_out ?comment (e : t) (range : t) : t =
} as e),
{ expression_desc = Number (Int { i = 0l } | Uint 0l); _ } ) ) ->
(* TODO: check correctness *)
is_out ?comment e range
| _, _ -> int_comp ?comment Cgt (to_uint32 e) range
is_out ?loc ?comment e range
| _, _ -> int_comp ?loc ?comment Cgt (to_uint32 e) range

let rec float_add ?loc ?comment (e1 : t) (e2 : t) =
match (e1.expression_desc, e2.expression_desc) with
Expand Down Expand Up @@ -1022,8 +1024,8 @@ and float_minus ?loc ?comment (e1 : t) (e2 : t) : t =
let unchecked_int32_add ?loc ?comment e1 e2 = float_add ?loc ?comment e1 e2
let int32_add ?loc ?comment e1 e2 = to_int32 ?loc (float_add ?comment e1 e2)

let offset e1 (offset : int) =
if offset = 0 then e1 else int32_add e1 (small_int offset)
let offset ?loc e1 (offset : int) =
if offset = 0 then e1 else int32_add ?loc e1 (small_int offset)

let int32_minus ?loc ?comment e1 e2 : J.expression =
to_int32 ?loc (float_minus ?comment e1 e2)
Expand Down Expand Up @@ -1196,9 +1198,9 @@ let neq_null_undefined_boolean ?loc ?comment (a : t) (b : t) =
(* TODO: in the future add a flag
to set globalThis
*)
let resolve_and_apply (s : string) (args : t list) : t =
call ~info:Js_call_info.builtin_runtime_call
(runtime_call Js_runtime_modules.external_polyfill "resolve" [ str s ])
let resolve_and_apply ?loc (s : string) (args : t list) : t =
call ?loc ~info:Js_call_info.builtin_runtime_call
(runtime_call ?loc Js_runtime_modules.external_polyfill "resolve" [ str s ])
args

let make_exception ~loc (s : string) =
Expand Down
31 changes: 19 additions & 12 deletions jscomp/core/js_exp_make.mli
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,14 @@ val external_var :
val ml_module_as_var : ?loc:Location.t -> ?comment:string -> Ident.t -> t

val runtime_call :
string -> (* module_name *)
string -> (* fn_name *)
t list -> (* args *)
t
?loc:Location.t ->
string ->
(* module_name *)
string ->
(* fn_name *)
t list ->
(* args *)
t

val pure_runtime_call :
?loc:Location.t ->
Expand All @@ -85,8 +89,11 @@ val pure_runtime_call :
(* args *)
t

val runtime_ref : string -> string -> t
val public_method_call : string -> t -> t -> Int32.t -> t list -> t
val runtime_ref : ?loc:Location.t -> string -> string -> t

val public_method_call :
?loc:Location.t -> string -> t -> t -> Int32.t -> t list -> t

val str : ?pure:bool -> ?loc:Location.t -> ?comment:string -> string -> t
val unicode : ?loc:Location.t -> ?comment:string -> string -> t

Expand Down Expand Up @@ -122,7 +129,7 @@ val zero_int_literal : t
val zero_float_lit : t
(* val obj_int_tag_literal : t *)

val is_out : ?comment:string -> t -> t -> t
val is_out : ?loc:Location.t -> ?comment:string -> t -> t -> t
(** [is_out e range] is equivalent to [e > range or e <0]
*)
Expand Down Expand Up @@ -194,7 +201,7 @@ val to_int32 : ?loc:Location.t -> ?comment:string -> t -> t
val to_uint32 : ?loc:Location.t -> ?comment:string -> t -> t
val unchecked_int32_add : ?loc:Location.t -> ?comment:string -> t -> t -> t
val int32_add : ?loc:Location.t -> ?comment:string -> t -> t -> t
val offset : t -> int -> t
val offset : ?loc:Location.t -> t -> int -> t
val unchecked_int32_minus : ?loc:Location.t -> ?comment:string -> t -> t -> t
val int32_minus : ?loc:Location.t -> ?comment:string -> t -> t -> t
val int32_mul : ?loc:Location.t -> ?comment:string -> t -> t -> t
Expand Down Expand Up @@ -254,7 +261,7 @@ val js_comp :
t ->
t

val not : t -> t
val not : ?loc:Location.t -> t -> t

val call :
?loc:Location.t -> ?comment:string -> info:Js_call_info.t -> t -> t list -> t
Expand All @@ -267,8 +274,8 @@ val new_ :
val array :
?loc:Location.t -> ?comment:string -> J.mutable_flag -> J.expression list -> t

val optional_block : J.expression -> J.expression
val optional_not_nest_block : J.expression -> J.expression
val optional_block : ?loc:Location.t -> J.expression -> J.expression
val optional_not_nest_block : ?loc:Location.t -> J.expression -> J.expression

val make_block :
?loc:Location.t ->
Expand Down Expand Up @@ -320,5 +327,5 @@ val is_null : ?loc:Location.t -> ?comment:string -> t -> t
val is_undef : ?loc:Location.t -> ?comment:string -> t -> t
val for_sure_js_null_undefined : J.expression -> bool
val is_null_undefined : ?loc:Location.t -> ?comment:string -> t -> t
val resolve_and_apply : string -> t list -> t
val resolve_and_apply : ?loc:Location.t -> string -> t list -> t
val make_exception : loc:Location.t -> string -> t
89 changes: 47 additions & 42 deletions jscomp/core/js_long.ml
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,40 @@

module E = Js_exp_make

type int64_call = J.expression list -> J.expression
type int64_call = ?loc:Location.t -> J.expression list -> J.expression

let int64_call (fn : string) args =
E.runtime_call Js_runtime_modules.int64 fn args
let int64_call ?loc (fn : string) args =
E.runtime_call ?loc Js_runtime_modules.int64 fn args

(* below should not depend on layout *)

let of_const (v : Int64.t) =
let of_const ?loc (v : Int64.t) =
match v with
| 0L -> E.runtime_var_dot Js_runtime_modules.int64 "zero"
| 1L -> E.runtime_var_dot Js_runtime_modules.int64 "one"
| -1L -> E.runtime_var_dot Js_runtime_modules.int64 "neg_one"
| 9223372036854775807L -> E.runtime_var_dot Js_runtime_modules.int64 "max_int"
| 0L -> E.runtime_var_dot ?loc Js_runtime_modules.int64 "zero"
| 1L -> E.runtime_var_dot ?loc Js_runtime_modules.int64 "one"
| -1L -> E.runtime_var_dot ?loc Js_runtime_modules.int64 "neg_one"
| 9223372036854775807L ->
E.runtime_var_dot ?loc Js_runtime_modules.int64 "max_int"
| -9223372036854775808L ->
E.runtime_var_dot Js_runtime_modules.int64 "min_int"
E.runtime_var_dot ?loc Js_runtime_modules.int64 "min_int"
| _ ->
let unsigned_lo = E.uint32 (Int64.to_int32 v) in
let hi = E.int (Int64.to_int32 (Int64.shift_right v 32)) in
E.array Immutable [ hi; unsigned_lo ]
E.array ?loc Immutable [ hi; unsigned_lo ]
(* Assume the encoding of Int64 *)

let to_int32 args = int64_call "to_int32" args
let to_int32 ?loc args = int64_call ?loc "to_int32" args
(* let get_lo x = E.array_index_by_int x 1l *)
(* E.to_int32 @@ get_lo (Ext_list.singleton_exn args) *)

let of_int32 (args : J.expression list) =
let of_int32 ?loc (args : J.expression list) =
match args with
| [ { expression_desc = Number (Int { i }); _ } ] ->
of_const (Int64.of_int32 i)
| _ -> int64_call "of_int32" args
of_const ?loc (Int64.of_int32 i)
| _ -> int64_call ?loc "of_int32" args

let comp (cmp : Lam_compat.integer_comparison) args =
E.runtime_call Js_runtime_modules.caml_primitive
let comp (cmp : Lam_compat.integer_comparison) ?loc args =
E.runtime_call ?loc Js_runtime_modules.caml_primitive
(match cmp with
| Ceq -> "i64_eq"
| Cne -> "i64_neq"
Expand All @@ -66,20 +67,24 @@ let comp (cmp : Lam_compat.integer_comparison) args =
| Cge -> "i64_ge")
args

let min args = E.runtime_call Js_runtime_modules.caml_primitive "i64_min" args
let max args = E.runtime_call Js_runtime_modules.caml_primitive "i64_max" args
let neg args = int64_call "neg" args
let add args = int64_call "add" args
let sub args = int64_call "sub" args
let mul args = int64_call "mul" args
let div args = int64_call "div" args
let min ?loc args =
E.runtime_call ?loc Js_runtime_modules.caml_primitive "i64_min" args

let max ?loc args =
E.runtime_call ?loc Js_runtime_modules.caml_primitive "i64_max" args

let neg ?loc args = int64_call ?loc "neg" args
let add ?loc args = int64_call ?loc "add" args
let sub ?loc args = int64_call ?loc "sub" args
let mul ?loc args = int64_call ?loc "mul" args
let div ?loc args = int64_call ?loc "div" args

(** Note if operands are not pure, we need hold shared value,
which is a statement [var x = ... ; x ], it does not fit
current pipe-line fall back to a function call
*)
let bit_op (* op : E.t -> E.t -> E.t*) runtime_call args =
int64_call runtime_call args
let bit_op ?loc (* op : E.t -> E.t -> E.t*) runtime_call args =
int64_call ?loc runtime_call args
(*disable optimizations relying on int64 representations
this maybe outdated when we switch to bigint
*)
Expand All @@ -93,14 +98,14 @@ let bit_op (* op : E.t -> E.t -> E.t*) runtime_call args =
else
| _ -> assert false *)

let xor = bit_op "xor"
let or_ = bit_op "or_"
let and_ = bit_op "and_"
let lsl_ args = int64_call "lsl_" args
let lsr_ args = int64_call "lsr_" args
let asr_ args = int64_call "asr_" args
let mod_ args = int64_call "mod_" args
let swap args = int64_call "swap" args
let xor ?loc args = bit_op ?loc "xor" args
let or_ ?loc args = bit_op ?loc "or_" args
let and_ ?loc args = bit_op ?loc "and_" args
let lsl_ ?loc args = int64_call ?loc "lsl_" args
let lsr_ ?loc args = int64_call ?loc "lsr_" args
let asr_ ?loc args = int64_call ?loc "asr_" args
let mod_ ?loc args = int64_call ?loc "mod_" args
let swap ?loc args = int64_call ?loc "swap" args

(* Safe constant propgation
{[
Expand All @@ -114,19 +119,19 @@ let swap args = int64_call "swap" args
Note that [Number._SAFE_INTEGER] is in ES6,
we can hard code this number without bringing browser issue.
*)
let of_float (args : J.expression list) = int64_call "of_float" args
let compare (args : J.expression list) = int64_call "compare" args
let of_float ?loc (args : J.expression list) = int64_call ?loc "of_float" args
let compare ?loc (args : J.expression list) = int64_call ?loc "compare" args

(* let of_string (args : J.expression list) =
int64_call "of_string" args *)
(* let get64 = int64_call "get64" *)
let float_of_bits = int64_call "float_of_bits"
let bits_of_float = int64_call "bits_of_float"
let equal_null args = int64_call "equal_null" args
let equal_undefined args = int64_call "equal_undefined" args
let equal_nullable args = int64_call "equal_nullable" args
let float_of_bits ?loc args = int64_call ?loc "float_of_bits" args
let bits_of_float ?loc args = int64_call ?loc "bits_of_float" args
let equal_null ?loc args = int64_call ?loc "equal_null" args
let equal_undefined ?loc args = int64_call ?loc "equal_undefined" args
let equal_nullable ?loc args = int64_call ?loc "equal_nullable" args

let to_float (args : J.expression list) =
let to_float ?loc (args : J.expression list) =
match args with
(* | [ {expression_desc *)
(* = Caml_block ( *)
Expand All @@ -136,5 +141,5 @@ let to_float (args : J.expression list) =
(* {expression_desc = Number (Int {i = hi; _}) }; *)
(* ], _, _, _); _ }] *)
(* -> *)
| [ _ ] -> int64_call "to_float" args
| [ _ ] -> int64_call ?loc "to_float" args
| _ -> assert false
Loading

0 comments on commit c5c8d47

Please sign in to comment.