@@ -42,7 +42,7 @@ let no_side_effect = Js_analyzer.no_side_effect_expression
4242type t = J .expression
4343
4444let make_expression ?loc ?comment desc =
45- J. { expression_desc = desc; comment; loc }
45+ { J. expression_desc = desc; comment; loc }
4646
4747(*
4848 [remove_pure_sub_exp x]
@@ -85,8 +85,7 @@ let call ?loc ?comment ~info e0 args : t =
8585 make_expression ?loc ?comment (Call { expr = e0; args; info })
8686
8787(* TODO: optimization when es is known at compile time
88- to be an array
89- *)
88+ to be an array *)
9089let flat_call ?loc ?comment e0 es : t =
9190 make_expression ?loc ?comment (FlatCall { expr = e0; args = es })
9291
@@ -172,8 +171,7 @@ let optional_not_nest_block e : J.expression =
172171 make_expression (Optional_block (e, true ))
173172
174173(* used in normal property
175- like [e.length], no dependency introduced
176- *)
174+ like [e.length], no dependency introduced *)
177175let dot ?loc ?comment (e0 : t ) (e1 : string ) : t =
178176 make_expression ?loc ?comment
179177 (Static_index { expr = e0; field = e1; pos = None })
@@ -437,8 +435,50 @@ let string_index ?loc ?comment (e0 : t) (e1 : t) : t =
437435 make_expression ?loc ?comment (String_index { expr = e0; index = e1 })
438436 | _ -> make_expression ?loc ?comment (String_index { expr = e0; index = e1 })
439437
440- let assign ?loc ?comment e0 e1 : t =
441- make_expression ?loc ?comment (Bin { op = Eq ; expr1 = e0; expr2 = e1 })
438+ let rec triple_equal ?loc ?comment (e0 : t ) (e1 : t ) : t =
439+ match (e0.expression_desc, e1.expression_desc) with
440+ | ( (Null | Undefined ),
441+ ( Char_of_int _ | Char_to_int _ | Bool _ | Number _ | Typeof _ | Fun _
442+ | Array _ | Caml_block _ ) )
443+ when no_side_effect e1 ->
444+ false_ (* TODO: rename it as [caml_false] *)
445+ | ( ( Char_of_int _ | Char_to_int _ | Bool _ | Number _ | Typeof _ | Fun _
446+ | Array _ | Caml_block _ ),
447+ (Null | Undefined ) )
448+ when no_side_effect e0 ->
449+ false_
450+ | Char_to_int a , Char_to_int b -> triple_equal ?comment a b
451+ | Char_to_int a, Number (Int { i = _; c = Some v })
452+ | Number (Int { i = _ ; c = Some v } ), Char_to_int a ->
453+ triple_equal ?comment a (str (String. make 1 v))
454+ | Unicode x , Unicode y -> bool (String. equal x y)
455+ | Number (Int { i = i0 ; _ } ), Number (Int { i = i1 ; _ } ) -> bool (i0 = i1)
456+ | Char_of_int a, Char_of_int b | Optional_block (a, _), Optional_block (b, _)
457+ ->
458+ triple_equal ?comment a b
459+ | Undefined , Optional_block _
460+ | Optional_block _, Undefined
461+ | Null , Undefined
462+ | Undefined , Null ->
463+ false_
464+ | Null , Null | Undefined , Undefined -> true_
465+ | _ ->
466+ make_expression ?loc ?comment
467+ (Bin { op = EqEqEq ; expr1 = e0; expr2 = e1 })
468+
469+ let bin ?loc ?comment (op : J.binop ) (e0 : t ) (e1 : t ) : t =
470+ match (op, e0.expression_desc, e1.expression_desc) with
471+ | EqEqEq , _ , _ -> triple_equal ?comment e0 e1
472+ | Ge , Length { expr = e; _ }, Number (Int { i = 0l ; _ }) when no_side_effect e
473+ ->
474+ true_ (* x.length >=0 | [x] is pure -> true*)
475+ | Gt , Length _ , Number (Int { i = 0l ; _ } ) ->
476+ (* [e] is kept so no side effect check needed *)
477+ make_expression ?loc ?comment
478+ (Bin { op = NotEqEq ; expr1 = e0; expr2 = e1 })
479+ | _ -> make_expression ?loc ?comment (Bin { op; expr1 = e0; expr2 = e1 })
480+
481+ let assign ?loc ?comment e0 e1 : t = bin ?loc ?comment Eq e0 e1
442482
443483let assign_by_exp (e : t ) index value : t =
444484 match e.expression_desc with
@@ -593,9 +633,7 @@ let float ?loc ?comment f : t =
593633 make_expression ?loc ?comment (Number (Float { f }))
594634
595635let zero_float_lit : t = make_expression (Number (Float { f = " 0." }))
596-
597- let float_mod ?loc ?comment e1 e2 : J.expression =
598- make_expression ?loc ?comment (Bin { op = Mod ; expr1 = e1; expr2 = e2 })
636+ let float_mod ?loc ?comment e1 e2 : J.expression = bin ?loc ?comment Mod e1 e2
599637
600638let str_equal (str0 : J.expression_desc ) (str1 : J.expression_desc ) =
601639 match (str0, str1) with
@@ -609,49 +647,6 @@ let str_equal (str0 : J.expression_desc) (str1 : J.expression_desc) =
609647 | Str _ , Unicode _ | Unicode _ , Str _ -> None
610648 | _ -> None
611649
612- let rec triple_equal ?loc ?comment (e0 : t ) (e1 : t ) : t =
613- match (e0.expression_desc, e1.expression_desc) with
614- | ( (Null | Undefined ),
615- ( Char_of_int _ | Char_to_int _ | Bool _ | Number _ | Typeof _ | Fun _
616- | Array _ | Caml_block _ ) )
617- when no_side_effect e1 ->
618- false_ (* TODO: rename it as [caml_false] *)
619- | ( ( Char_of_int _ | Char_to_int _ | Bool _ | Number _ | Typeof _ | Fun _
620- | Array _ | Caml_block _ ),
621- (Null | Undefined ) )
622- when no_side_effect e0 ->
623- false_
624- | Char_to_int a , Char_to_int b -> triple_equal ?comment a b
625- | Char_to_int a, Number (Int { i = _; c = Some v })
626- | Number (Int { i = _ ; c = Some v } ), Char_to_int a ->
627- triple_equal ?comment a (str (String. make 1 v))
628- | Unicode x , Unicode y -> bool (String. equal x y)
629- | Number (Int { i = i0 ; _ } ), Number (Int { i = i1 ; _ } ) -> bool (i0 = i1)
630- | Char_of_int a, Char_of_int b | Optional_block (a, _), Optional_block (b, _)
631- ->
632- triple_equal ?comment a b
633- | Undefined , Optional_block _
634- | Optional_block _, Undefined
635- | Null , Undefined
636- | Undefined , Null ->
637- false_
638- | Null , Null | Undefined , Undefined -> true_
639- | _ ->
640- make_expression ?loc ?comment
641- (Bin { op = EqEqEq ; expr1 = e0; expr2 = e1 })
642-
643- let bin ?loc ?comment (op : J.binop ) (e0 : t ) (e1 : t ) : t =
644- match (op, e0.expression_desc, e1.expression_desc) with
645- | EqEqEq , _ , _ -> triple_equal ?comment e0 e1
646- | Ge , Length { expr = e; _ }, Number (Int { i = 0l ; _ }) when no_side_effect e
647- ->
648- true_ (* x.length >=0 | [x] is pure -> true*)
649- | Gt , Length _ , Number (Int { i = 0l ; _ } ) ->
650- (* [e] is kept so no side effect check needed *)
651- make_expression ?loc ?comment
652- (Bin { op = NotEqEq ; expr1 = e0; expr2 = e1 })
653- | _ -> make_expression ?loc ?comment (Bin { op; expr1 = e0; expr2 = e1 })
654-
655650(* TODO: Constant folding, Google Closure will do that?,
656651 Even if Google Clsoure can do that, we will see how it interact with other
657652 optimizations
@@ -699,8 +694,7 @@ let and_ ?loc ?comment (e1 : t) (e2 : t) : t =
699694 } )
700695 when Js_analyzer. same_vident i j ->
701696 e2
702- | _ , _ ->
703- make_expression ?loc ?comment (Bin { op = And ; expr1 = e1; expr2 = e2 })
697+ | _ , _ -> bin ?loc ?comment And e1 e2
704698
705699let or_ ?loc ?comment (e1 : t ) (e2 : t ) =
706700 match (e1.expression_desc, e2.expression_desc) with
@@ -712,8 +706,7 @@ let or_ ?loc ?comment (e1 : t) (e2 : t) =
712706 Bin { op = Or ; expr1 = l; expr2 = { expression_desc = Var j; _ } as r } )
713707 when Js_analyzer. same_vident i j ->
714708 { e2 with expression_desc = Bin { op = Or ; expr1 = r; expr2 = l } }
715- | _ , _ ->
716- make_expression ?loc ?comment (Bin { op = Or ; expr1 = e1; expr2 = e2 })
709+ | _ , _ -> bin ?loc ?comment Or e1 e2
717710
718711(* return a value of type boolean *)
719712(* TODO:
@@ -829,18 +822,14 @@ let rec float_equal ?loc ?comment (e0 : t) (e1 : t) : t =
829822 | Number (Int { i = _ ; c = Some v } ), Char_to_int a ->
830823 float_equal ?comment a (str (String. make 1 v))
831824 | Char_of_int a , Char_of_int b -> float_equal ?comment a b
832- | _ ->
833- make_expression ?loc ?comment
834- (Bin { op = EqEqEq ; expr1 = e0; expr2 = e1 })
825+ | _ -> bin ?loc ?comment EqEqEq e0 e1
835826
836827let int_equal = float_equal
837828
838829let string_equal ?loc ?comment (e0 : t ) (e1 : t ) : t =
839830 match str_equal e0.expression_desc e1.expression_desc with
840831 | Some b -> bool b
841- | None ->
842- make_expression ?loc ?comment
843- (Bin { op = EqEqEq ; expr1 = e0; expr2 = e1 })
832+ | None -> bin ?loc ?comment EqEqEq e0 e1
844833
845834let is_type_number ?loc ?comment (e : t ) : t =
846835 string_equal ?loc ?comment (typeof e) (str " number" )
@@ -926,10 +915,9 @@ let rec int32_bor ?loc ?comment (e1 : J.expression) (e2 : J.expression) :
926915 },
927916 Number (Int { i = 0l ; _ } | Uint 0l ) ) ->
928917 int32_bor e1 e2
929- | _ ->
930- make_expression ?loc ?comment (Bin { op = Bor ; expr1 = e1; expr2 = e2 })
918+ | _ -> bin ?loc ?comment Bor e1 e2
931919
932- (* Arithmatic operations
920+ (* Arithmetic operations
933921 TODO: distinguish between int and float
934922 TODO: Note that we have to use Int64 to avoid integer overflow, this is fine
935923 since Js only have .
@@ -1099,9 +1087,7 @@ let rec int32_lsr ?loc ?comment (e1 : J.expression) (e2 : J.expression) :
10991087 },
11001088 Number (Int { i = 0l ; _ } | Uint 0l ) ) ->
11011089 int32_lsr ?comment e1 e2
1102- | _ , _ ->
1103- make_expression ?loc ?comment
1104- (Bin { op = Lsr ; expr1 = e1; expr2 = e2 } (* uint32 *) )
1090+ | _ , _ -> bin ?loc ?comment Lsr e1 e2 (* uint32 *)
11051091
11061092let to_uint32 ?loc ?comment (e : J.expression ) : J.expression =
11071093 int32_lsr ?loc ?comment e zero_int_literal
@@ -1195,8 +1181,7 @@ let rec float_add ?loc ?comment (e1 : t) (e2 : t) =
11951181 expr2 = { expression_desc = Number (Int { i = k; _ }); _ };
11961182 },
11971183 Number (Int { i = j; _ }) ) ->
1198- make_expression ?loc ?comment
1199- (Bin { op = Plus ; expr1 = a1; expr2 = int (Int32. add k j) })
1184+ bin ?loc ?comment Plus a1 (int (Int32. add k j))
12001185 (* bin ?loc ?comment Plus a1 (int (k + j)) *)
12011186 (* TODO remove commented code ?? *)
12021187 (* | Bin(Plus, a0 , ({expression_desc = Number (Int a1)} )), *)
@@ -1214,17 +1199,15 @@ let rec float_add ?loc ?comment (e1 : t) (e2 : t) =
12141199 (* | Number _, _ *)
12151200 (* -> *)
12161201 (* bin ?loc ?comment Plus e2 e1 *)
1217- | _ ->
1218- make_expression ?loc ?comment (Bin { op = Plus ; expr1 = e1; expr2 = e2 })
1202+ | _ -> bin ?loc ?comment Plus e1 e2
12191203
12201204(* bin ?loc ?comment Plus e1 e2 *)
12211205(* associative is error prone due to overflow *)
12221206and float_minus ?loc ?comment (e1 : t ) (e2 : t ) : t =
12231207 match (e1.expression_desc, e2.expression_desc) with
12241208 | Number (Int { i; _ } ), Number (Int { i = j ; _ } ) ->
12251209 int ?comment (Int32. sub i j)
1226- | _ ->
1227- make_expression ?loc ?comment (Bin { op = Minus ; expr1 = e1; expr2 = e2 })
1210+ | _ -> bin ?loc ?comment Minus e1 e2
12281211(* bin ?loc ?comment Minus e1 e2 *)
12291212
12301213let unchecked_int32_add ?loc ?comment e1 e2 = float_add ?loc ?comment e1 e2
@@ -1241,9 +1224,7 @@ let unchecked_int32_minus ?loc ?comment e1 e2 : J.expression =
12411224
12421225let float_div ?loc ?comment e1 e2 = bin ?loc ?comment Div e1 e2
12431226let float_notequal ?loc ?comment e1 e2 = bin ?loc ?comment NotEqEq e1 e2
1244-
1245- let int32_asr ?loc ?comment e1 e2 : J.expression =
1246- make_expression ?loc ?comment (Bin { op = Asr ; expr1 = e1; expr2 = e2 })
1227+ let int32_asr ?loc ?comment e1 e2 : J.expression = bin ?loc ?comment Asr e1 e2
12471228
12481229(* * Division by zero is undefined behavior*)
12491230let int32_div ~checked ?loc ?comment (e1 : t ) (e2 : t ) : t =
@@ -1262,14 +1243,12 @@ let int32_div ~checked ?loc ?comment (e1 : t) (e2 : t) : t =
12621243
12631244let int32_mod ~checked ?loc ?comment e1 (e2 : t ) : J.expression =
12641245 match e2.expression_desc with
1265- | Number (Int { i; _ } ) when i <> 0l ->
1266- make_expression ?loc ?comment (Bin { op = Mod ; expr1 = e1; expr2 = e2 })
1246+ | Number (Int { i; _ } ) when i <> 0l -> bin ?loc ?comment Mod e1 e2
12671247 | _ ->
12681248 if checked then
12691249 runtime_call ~module_name: Js_runtime_modules. int32 ~fn_name: " mod_"
12701250 [ e1; e2 ]
1271- else
1272- make_expression ?loc ?comment (Bin { op = Mod ; expr1 = e1; expr2 = e2 })
1251+ else bin ?loc ?comment Mod e1 e2
12731252
12741253let float_mul ?loc ?comment e1 e2 = bin ?loc ?comment Mul e1 e2
12751254
@@ -1279,8 +1258,7 @@ let int32_lsl ?loc ?comment (e1 : J.expression) (e2 : J.expression) :
12791258 | ( { expression_desc = Number (Int { i = i0; _ } | Uint i0); _ },
12801259 { expression_desc = Number (Int { i = i1; _ } | Uint i1 ); _ } ) ->
12811260 int ?comment (Int32. shift_left i0 (Int32. to_int i1))
1282- | _ ->
1283- make_expression ?loc ?comment (Bin { op = Lsl ; expr1 = e1; expr2 = e2 })
1261+ | _ -> bin ?loc ?comment Lsl e1 e2
12841262
12851263let is_pos_pow n =
12861264 let module M = struct
@@ -1320,7 +1298,7 @@ let int32_mul ?loc ?comment (e1 : J.expression) (e2 : J.expression) :
13201298 [ e1; e2 ]
13211299
13221300let unchecked_int32_mul ?loc ?comment e1 e2 : J.expression =
1323- make_expression ?loc ?comment ( Bin { op = Mul ; expr1 = e1; expr2 = e2 })
1301+ bin ?loc ?comment Mul e1 e2
13241302
13251303let rec int32_bxor ?loc ?comment (e1 : t ) (e2 : t ) : J.expression =
13261304 match (e1.expression_desc, e2.expression_desc) with
@@ -1342,8 +1320,7 @@ let rec int32_bxor ?loc ?comment (e1 : t) (e2 : t) : J.expression =
13421320 },
13431321 _ ) ->
13441322 int32_bxor e1 e2
1345- | _ ->
1346- make_expression ?loc ?comment (Bin { op = Bxor ; expr1 = e1; expr2 = e2 })
1323+ | _ -> bin ?loc ?comment Bxor e1 e2
13471324
13481325let rec int32_band ?loc ?comment (e1 : J.expression ) (e2 : J.expression ) :
13491326 J. expression =
@@ -1359,8 +1336,7 @@ let rec int32_band ?loc ?comment (e1 : J.expression) (e2 : J.expression) :
13591336 {[ (-1 >>> 0 | 0 ) & 0xffffff ]}
13601337 *)
13611338 int32_band a e2
1362- | _ ->
1363- make_expression ?loc ?comment (Bin { op = Band ; expr1 = e1; expr2 = e2 })
1339+ | _ -> bin ?loc ?comment Band e1 e2
13641340
13651341(* let int32_bin ?loc ?comment op e1 e2 : J.expression = *)
13661342(* make_expression ?loc ?comment (Int32_bin(op,e1, e2)) *)
@@ -1410,8 +1386,7 @@ let eq_null_undefined_boolean ?loc ?comment (a : t) (b : t) =
14101386 false_
14111387 | Null , Undefined | Undefined , Null -> false_
14121388 | Null , Null | Undefined , Undefined -> true_
1413- | _ ->
1414- make_expression ?loc ?comment (Bin { op = EqEqEq ; expr1 = a; expr2 = b })
1389+ | _ -> bin ?loc ?comment EqEqEq a b
14151390
14161391let neq_null_undefined_boolean ?loc ?comment (a : t ) (b : t ) =
14171392 match (a.expression_desc, b.expression_desc) with
@@ -1423,10 +1398,9 @@ let neq_null_undefined_boolean ?loc ?comment (a : t) (b : t) =
14231398 | Array _ | Caml_block _ ),
14241399 (Null | Undefined ) ) ->
14251400 true_
1426- | Null , Null | Undefined , Undefined -> false_
14271401 | Null , Undefined | Undefined , Null -> true_
1428- | _ ->
1429- make_expression ?loc ?comment ( Bin { op = NotEqEq ; expr1 = a; expr2 = b })
1402+ | Null , Null | Undefined , Undefined -> false_
1403+ | _ -> bin ?loc ?comment NotEqEq a b
14301404
14311405(* TODO: in the future add a flag
14321406 to set globalThis
0 commit comments