@@ -70661,13 +70661,13 @@ module Js_analyzer : sig
7066170661(** Analyzing utilities for [J] module *)
7066270662
7066370663(** for example, whether it has side effect or not.
70664- *)
70664+ *)
7066570665
7066670666val 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
7066870668
7066970669val 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
7067170671
7067270672val no_side_effect_expression_desc :
7067370673 J.expression_desc -> bool
@@ -70680,21 +70680,23 @@ val no_side_effect_expression :
7068070680 when you want to do a deep copy, the expression passed to you is pure
7068170681 but you still have to call the function to make a copy,
7068270682 since it maybe changed later
70683- *)
70683+ *)
7068470684
7068570685val no_side_effect_statement :
70686- J.statement -> bool
70686+ J.statement -> bool
7068770687(**
7068870688 here we say
70689- {[ var x = no_side_effect_expression ]}
70689+ {[ var x = no_side_effect_expression ]}
7069070690 is [no side effect], but it is actually side effect,
7069170691 since we are defining a variable, however, if it is not exported or used,
7069270692 then it's fine, so we delay this check later
70693- *)
70693+ *)
7069470694
70695- val eq_expression : J.expression -> J.expression -> bool
70695+ val eq_expression :
70696+ J.expression -> J.expression -> bool
7069670697
70697- val eq_statement : J.statement -> J.statement -> bool
70698+ val eq_statement :
70699+ J.statement -> J.statement -> bool
7069870700
7069970701val rev_flatten_seq : J.expression -> J.block
7070070702
@@ -70709,7 +70711,7 @@ val is_constant : J.expression -> bool
7070970711*)
7071070712
7071170713val is_simple_no_side_effect_expression
70712- : J.expression -> bool
70714+ : J.expression -> bool
7071370715end = struct
7071470716#1 "js_analyzer.ml"
7071570717(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
@@ -70751,7 +70753,7 @@ end = struct
7075170753
7075270754 Note such shaking is done in the toplevel, so that it requires us to
7075370755 flatten the statement first
70754- *)
70756+ *)
7075570757let free_variables used_idents defined_idents =
7075670758 object (self)
7075770759 inherit Js_fold.fold as super
@@ -70772,9 +70774,9 @@ let free_variables used_idents defined_idents =
7077270774
7077370775 match exp.expression_desc with
7077470776 | 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+ *)
7077870780 ->
7077970781 {< used_idents =
7078070782 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) =
7080870810 | Array (xs,_mutable_flag)
7080970811 | Caml_block (xs, _mutable_flag, _, _)
7081070812 ->
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
7081770819 | Bind(fn, obj) -> no_side_effect fn && no_side_effect obj
7081870820 | Object kvs ->
7081970821 List.for_all (fun (_property_name, y) -> no_side_effect y ) kvs
@@ -70865,53 +70867,157 @@ let no_side_effect init =
7086570867
7086670868 method! statement s =
7086770869 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
7087870880 method! list f x =
7087970881 if not self#get_no_side_effect then self else super#list f x
7088070882 method! expression s =
7088170883 if not no_side_effect then self
7088270884 else {< no_side_effect = no_side_effect_expression s >}
7088370885
70884- (** only expression would cause side effec *)
70886+ (** only expression would cause side effec *)
7088570887 end
7088670888let no_side_effect_statement st = ((no_side_effect true)#statement st)#get_no_side_effect
7088770889
7088870890(* TODO: generate [fold2]
7088970891 This make sense, for example:
7089070892 {[
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
7089670898
7089770899 ]}
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
7091571021and eq_expression_list xs ys =
7091671022 let rec aux xs ys =
7091771023 match xs,ys with
@@ -70921,13 +71027,49 @@ and eq_expression_list xs ys =
7092171027 | x::xs, y::ys -> eq_expression x y && aux xs ys
7092271028 in
7092371029 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+ ->
7093171073 false
7093271074
7093371075let rev_flatten_seq (x : J.expression) =
@@ -70939,17 +71081,17 @@ let rev_flatten_seq (x : J.expression) =
7093971081
7094071082(* TODO: optimization,
7094171083 counter the number to know if needed do a loop gain instead of doing a diff
70942- *)
71084+ *)
7094371085
7094471086let rev_toplevel_flatten block =
7094571087 let rec aux acc (xs : J.block) : J.block =
7094671088 match xs with
7094771089 | [] -> acc
7094871090 | {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
7095371095 | {statement_desc = Block b; _ } ::xs -> aux (aux acc b ) xs
7095471096
7095571097 | x :: xs -> aux (x :: acc) xs in
0 commit comments