@@ -70661,13 +70661,13 @@ module Js_analyzer : sig
70661
70661
(** Analyzing utilities for [J] module *)
70662
70662
70663
70663
(** for example, whether it has side effect or not.
70664
- *)
70664
+ *)
70665
70665
70666
70666
val free_variables_of_statement :
70667
- Ident_set.t -> Ident_set.t -> J.statement -> Ident_set.t
70667
+ Ident_set.t -> Ident_set.t -> J.statement -> Ident_set.t
70668
70668
70669
70669
val free_variables_of_expression :
70670
- Ident_set.t -> Ident_set.t -> J.finish_ident_expression -> Ident_set.t
70670
+ Ident_set.t -> Ident_set.t -> J.finish_ident_expression -> Ident_set.t
70671
70671
70672
70672
val no_side_effect_expression_desc :
70673
70673
J.expression_desc -> bool
@@ -70680,21 +70680,23 @@ val no_side_effect_expression :
70680
70680
when you want to do a deep copy, the expression passed to you is pure
70681
70681
but you still have to call the function to make a copy,
70682
70682
since it maybe changed later
70683
- *)
70683
+ *)
70684
70684
70685
70685
val no_side_effect_statement :
70686
- J.statement -> bool
70686
+ J.statement -> bool
70687
70687
(**
70688
70688
here we say
70689
- {[ var x = no_side_effect_expression ]}
70689
+ {[ var x = no_side_effect_expression ]}
70690
70690
is [no side effect], but it is actually side effect,
70691
70691
since we are defining a variable, however, if it is not exported or used,
70692
70692
then it's fine, so we delay this check later
70693
- *)
70693
+ *)
70694
70694
70695
- val eq_expression : J.expression -> J.expression -> bool
70695
+ val eq_expression :
70696
+ J.expression -> J.expression -> bool
70696
70697
70697
- val eq_statement : J.statement -> J.statement -> bool
70698
+ val eq_statement :
70699
+ J.statement -> J.statement -> bool
70698
70700
70699
70701
val rev_flatten_seq : J.expression -> J.block
70700
70702
@@ -70709,7 +70711,7 @@ val is_constant : J.expression -> bool
70709
70711
*)
70710
70712
70711
70713
val is_simple_no_side_effect_expression
70712
- : J.expression -> bool
70714
+ : J.expression -> bool
70713
70715
end = struct
70714
70716
#1 "js_analyzer.ml"
70715
70717
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
@@ -70751,7 +70753,7 @@ end = struct
70751
70753
70752
70754
Note such shaking is done in the toplevel, so that it requires us to
70753
70755
flatten the statement first
70754
- *)
70756
+ *)
70755
70757
let free_variables used_idents defined_idents =
70756
70758
object (self)
70757
70759
inherit Js_fold.fold as super
@@ -70772,9 +70774,9 @@ let free_variables used_idents defined_idents =
70772
70774
70773
70775
match exp.expression_desc with
70774
70776
| Fun(_, _,_, env)
70775
- (** a optimization to avoid walking into funciton again
70776
- if it's already comuted
70777
- *)
70777
+ (** a optimization to avoid walking into funciton again
70778
+ if it's already comuted
70779
+ *)
70778
70780
->
70779
70781
{< used_idents =
70780
70782
Ident_set.union (Js_fun_env.get_unbounded env) used_idents >}
@@ -70808,12 +70810,12 @@ let rec no_side_effect_expression_desc (x : J.expression_desc) =
70808
70810
| Array (xs,_mutable_flag)
70809
70811
| Caml_block (xs, _mutable_flag, _, _)
70810
70812
->
70811
- (** create [immutable] block,
70812
- does not really mean that this opreation itself is [pure].
70813
-
70814
- the block is mutable does not mean this operation is non-pure
70815
- *)
70816
- List.for_all no_side_effect xs
70813
+ (** create [immutable] block,
70814
+ does not really mean that this opreation itself is [pure].
70815
+
70816
+ the block is mutable does not mean this operation is non-pure
70817
+ *)
70818
+ List.for_all no_side_effect xs
70817
70819
| Bind(fn, obj) -> no_side_effect fn && no_side_effect obj
70818
70820
| Object kvs ->
70819
70821
List.for_all (fun (_property_name, y) -> no_side_effect y ) kvs
@@ -70865,53 +70867,157 @@ let no_side_effect init =
70865
70867
70866
70868
method! statement s =
70867
70869
if not no_side_effect then self else
70868
- match s.statement_desc with
70869
- | Throw _
70870
- | Debugger
70871
- | Break
70872
- | Variable _
70873
- | Continue _ ->
70874
- {< no_side_effect = false>}
70875
- | Exp e -> self#expression e
70876
- | Int_switch _ | String_switch _ | ForRange _
70877
- | If _ | While _ | Block _ | Return _ | Try _ -> super#statement s
70870
+ match s.statement_desc with
70871
+ | Throw _
70872
+ | Debugger
70873
+ | Break
70874
+ | Variable _
70875
+ | Continue _ ->
70876
+ {< no_side_effect = false>}
70877
+ | Exp e -> self#expression e
70878
+ | Int_switch _ | String_switch _ | ForRange _
70879
+ | If _ | While _ | Block _ | Return _ | Try _ -> super#statement s
70878
70880
method! list f x =
70879
70881
if not self#get_no_side_effect then self else super#list f x
70880
70882
method! expression s =
70881
70883
if not no_side_effect then self
70882
70884
else {< no_side_effect = no_side_effect_expression s >}
70883
70885
70884
- (** only expression would cause side effec *)
70886
+ (** only expression would cause side effec *)
70885
70887
end
70886
70888
let no_side_effect_statement st = ((no_side_effect true)#statement st)#get_no_side_effect
70887
70889
70888
70890
(* TODO: generate [fold2]
70889
70891
This make sense, for example:
70890
70892
{[
70891
- let string_of_formatting_gen : type a b c d e f .
70892
- (a, b, c, d, e, f) formatting_gen -> string =
70893
- fun formatting_gen -> match formatting_gen with
70894
- | Open_tag (Format (_, str)) -> str
70895
- | Open_box (Format (_, str)) -> str
70893
+ let string_of_formatting_gen : type a b c d e f .
70894
+ (a, b, c, d, e, f) formatting_gen -> string =
70895
+ fun formatting_gen -> match formatting_gen with
70896
+ | Open_tag (Format (_, str)) -> str
70897
+ | Open_box (Format (_, str)) -> str
70896
70898
70897
70899
]}
70898
- *)
70899
- let rec eq_expression (x : J.expression) (y : J.expression) =
70900
- match x.expression_desc, y.expression_desc with
70901
- | Number (Int i) , Number (Int j) -> i = j
70902
- | Number (Float i), Number (Float j) -> false (* TODO *)
70903
- | Math (name00,args00), Math(name10,args10) ->
70904
- name00 = name10 && eq_expression_list args00 args10
70905
- | Access (a0,a1), Access(b0,b1) ->
70906
- eq_expression a0 b0 && eq_expression a1 b1
70907
- | Call (a0,args00,_), Call(b0,args10,_) ->
70908
- eq_expression a0 b0 && eq_expression_list args00 args10
70909
- | Var (Id i), Var (Id j) ->
70910
- Ident.same i j
70911
- | Bin (op0, a0,b0) , Bin(op1,a1,b1) ->
70912
- op0 = op1 && eq_expression a0 a1 && eq_expression b0 b1
70913
- | _, _ -> false
70914
-
70900
+ *)
70901
+ let rec eq_expression
70902
+ ({expression_desc = x0} : J.expression)
70903
+ ({expression_desc = y0} : J.expression) =
70904
+ begin match x0 with
70905
+ | Number (Int i) ->
70906
+ begin match y0 with
70907
+ | Number (Int j) -> i = j
70908
+ | _ -> false
70909
+ end
70910
+ | Number (Float i) ->
70911
+ begin match y0 with
70912
+ | Number (Float j) ->
70913
+ false (* conservative *)
70914
+ | _ -> false
70915
+ end
70916
+ | Math (name00,args00) ->
70917
+ begin match y0 with
70918
+ |Math(name10,args10) ->
70919
+ name00 = name10 && eq_expression_list args00 args10
70920
+ | _ -> false
70921
+ end
70922
+ | Access (a0,a1) ->
70923
+ begin match y0 with
70924
+ | Access(b0,b1) ->
70925
+ eq_expression a0 b0 && eq_expression a1 b1
70926
+ | _ -> false
70927
+ end
70928
+ | Call (a0,args00,_) ->
70929
+ begin match y0 with
70930
+ | Call(b0,args10,_) ->
70931
+ eq_expression a0 b0 && eq_expression_list args00 args10
70932
+ | _ -> false
70933
+ end
70934
+ | Var (Id i) ->
70935
+ begin match y0 with
70936
+ | Var (Id j) ->
70937
+ Ident.same i j
70938
+ | _ -> false
70939
+ end
70940
+ | Bin (op0, a0,b0) ->
70941
+ begin match y0 with
70942
+ | Bin(op1,a1,b1) ->
70943
+ op0 = op1 && eq_expression a0 a1 && eq_expression b0 b1
70944
+ | _ -> false
70945
+ end
70946
+ | Str(a0,b0) ->
70947
+ begin match y0 with
70948
+ | Str(a1,b1) -> a0 = a1 && b0 = b1
70949
+ | _ -> false
70950
+ end
70951
+ | Var (Qualified (id0,k0,opts0)) ->
70952
+ begin match y0 with
70953
+ | Var (Qualified (id1,k1,opts1)) ->
70954
+ Ident.same id0 id1 &&
70955
+ k0 = k1 &&
70956
+ opts0 = opts1
70957
+ | _ -> false
70958
+ end
70959
+ | Dot (e0,p0,b0) ->
70960
+ begin match y0 with
70961
+ | Dot(e1,p1,b1) ->
70962
+ p0 = p1 && b0 = b1 && eq_expression e0 e1
70963
+ | _ -> false
70964
+ end
70965
+ | Dump (l0,es0) ->
70966
+ begin match y0 with
70967
+ | Dump(l1,es1) ->
70968
+ l0 = l1 && eq_expression_list es0 es1
70969
+ | _ -> false
70970
+ end
70971
+ | Seq (a0,b0) ->
70972
+ begin match y0 with
70973
+ | Seq(a1,b1) ->
70974
+ eq_expression a0 a1 && eq_expression b0 b1
70975
+ | _ -> false
70976
+ end
70977
+ | Bool a0 ->
70978
+ begin match y0 with
70979
+ | Bool b0 -> a0 = b0
70980
+ | _ -> false
70981
+ end
70982
+ | Length _
70983
+ | Char_of_int _
70984
+ | Char_to_int _
70985
+ | Is_null_undefined_to_boolean _
70986
+ | Array_of_size _
70987
+ | Array_copy _
70988
+ | Array_append _
70989
+ | String_append _
70990
+ | Int_of_boolean _
70991
+ | Anything_to_number _
70992
+
70993
+ | Typeof _
70994
+ | Caml_not _
70995
+ | Js_not _
70996
+ | String_of_small_int_array _
70997
+ | Json_stringify _
70998
+ | Anything_to_string _
70999
+
71000
+
71001
+ | Cond _
71002
+ | FlatCall _
71003
+ | Bind _
71004
+ | String_access _
71005
+
71006
+ | New _
71007
+ | Fun _
71008
+ | Unicode _
71009
+ | Raw_js_code _
71010
+ | Array _
71011
+ | Caml_block _
71012
+ | Caml_uninitialized_obj _
71013
+ | Caml_block_tag _
71014
+ | Caml_block_set_tag _
71015
+ | Caml_block_set_length _
71016
+ | Object _
71017
+ | Number (Uint _ | Nint _)
71018
+
71019
+ -> false
71020
+ end
70915
71021
and eq_expression_list xs ys =
70916
71022
let rec aux xs ys =
70917
71023
match xs,ys with
@@ -70921,13 +71027,49 @@ and eq_expression_list xs ys =
70921
71027
| x::xs, y::ys -> eq_expression x y && aux xs ys
70922
71028
in
70923
71029
aux xs ys
70924
-
70925
- and eq_statement (x : J.statement) (y : J.statement) =
70926
- match x.statement_desc, y.statement_desc with
70927
- | Exp a, Exp b
70928
- | Return { return_value = a ; _} , Return { return_value = b; _} ->
70929
- eq_expression a b
70930
- | _, _ ->
71030
+ and eq_statement_list xs ys =
71031
+ let rec aux xs ys =
71032
+ match xs,ys with
71033
+ | [], [] -> true
71034
+ | [], _ -> false
71035
+ | _ , [] -> false
71036
+ | x::xs, y::ys -> eq_statement x y && aux xs ys
71037
+ in
71038
+ aux xs ys
71039
+ and eq_statement
71040
+ ({statement_desc = x0} : J.statement)
71041
+ ({statement_desc = y0} : J.statement) =
71042
+ match x0 with
71043
+ | Exp a ->
71044
+ begin match y0 with
71045
+ | Exp b -> eq_expression a b
71046
+ | _ -> false
71047
+ end
71048
+ | Return { return_value = a ; _} ->
71049
+ begin match y0 with
71050
+ | Return { return_value = b; _} ->
71051
+ eq_expression a b
71052
+ | _ -> false
71053
+ end
71054
+ | Debugger -> y0 = Debugger
71055
+ | Break -> y0 = Break
71056
+ | Block xs0 ->
71057
+ begin match y0 with
71058
+ | Block ys0 ->
71059
+ eq_statement_list xs0 ys0
71060
+ | _ -> false
71061
+ end
71062
+ | Variable _
71063
+ | If _
71064
+ | While _
71065
+ | ForRange _
71066
+ | Continue _
71067
+
71068
+ | Int_switch _
71069
+ | String_switch _
71070
+ | Throw _
71071
+ | Try _
71072
+ ->
70931
71073
false
70932
71074
70933
71075
let rev_flatten_seq (x : J.expression) =
@@ -70939,17 +71081,17 @@ let rev_flatten_seq (x : J.expression) =
70939
71081
70940
71082
(* TODO: optimization,
70941
71083
counter the number to know if needed do a loop gain instead of doing a diff
70942
- *)
71084
+ *)
70943
71085
70944
71086
let rev_toplevel_flatten block =
70945
71087
let rec aux acc (xs : J.block) : J.block =
70946
71088
match xs with
70947
71089
| [] -> acc
70948
71090
| {statement_desc =
70949
- Variable (
70950
- {ident_info = {used_stats = Dead_pure } ; _}
70951
- | {ident_info = {used_stats = Dead_non_pure}; value = None })
70952
- } :: xs -> aux acc xs
71091
+ Variable (
71092
+ {ident_info = {used_stats = Dead_pure } ; _}
71093
+ | {ident_info = {used_stats = Dead_non_pure}; value = None })
71094
+ } :: xs -> aux acc xs
70953
71095
| {statement_desc = Block b; _ } ::xs -> aux (aux acc b ) xs
70954
71096
70955
71097
| x :: xs -> aux (x :: acc) xs in
0 commit comments