Skip to content

Commit edffe62

Browse files
authored
Merge pull request #4916 from rescript-lang/simpilify_visitor2
Finish the optimization around visitor pattern using objects
2 parents 64be639 + 1fb566d commit edffe62

24 files changed

+2606
-1725
lines changed

jscomp/core/js_analyzer.ml

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -44,47 +44,51 @@ let add_defined_idents (x : idents_stats) ident =
4444
Note such shaking is done in the toplevel, so that it requires us to
4545
flatten the statement first
4646
*)
47-
let free_variables (stats : idents_stats) : Js_iter.iter =
48-
object (self)
49-
inherit Js_iter.iter as super
50-
method! variable_declaration st =
51-
add_defined_idents stats st.ident;
52-
match st.value with
53-
| None
54-
-> ()
55-
| Some v
56-
->
57-
self # expression v
58-
method! ident id =
59-
(if not (Set_ident.mem stats.defined_idents id )then
60-
stats.used_idents <- Set_ident.add stats.used_idents id)
61-
62-
method! expression exp =
63-
match exp.expression_desc with
64-
| Fun(_, _,_, env)
65-
(** a optimization to avoid walking into funciton again
66-
if it's already comuted
67-
*)
68-
->
69-
stats.used_idents <-
70-
Set_ident.union (Js_fun_env.get_unbounded env) stats.used_idents
47+
let super = Js_record_iter.iter
48+
let free_variables (stats : idents_stats) = {
49+
super with
50+
variable_declaration = begin fun self st ->
51+
add_defined_idents stats st.ident;
52+
match st.value with
53+
| None
54+
-> ()
55+
| Some v
56+
->
57+
self.expression self v
7158

59+
end;
60+
ident = begin fun _ id ->
61+
if not (Set_ident.mem stats.defined_idents id )then
62+
stats.used_idents <- Set_ident.add stats.used_idents id
63+
end;
64+
expression = begin fun self exp ->
65+
match exp.expression_desc with
66+
| Fun(_, _,_, env)
67+
(** a optimization to avoid walking into funciton again
68+
if it's already comuted
69+
*)
70+
->
71+
stats.used_idents <-
72+
Set_ident.union (Js_fun_env.get_unbounded env) stats.used_idents
73+
| _
74+
->
75+
super.expression self exp
76+
end
77+
}
7278

73-
| _
74-
->
75-
super#expression exp
76-
end
7779

7880
let free_variables_of_statement st =
7981
let init = {used_idents = Set_ident.empty;
80-
defined_idents = Set_ident.empty} in
81-
let _ = (free_variables init)#statement st in
82+
defined_idents = Set_ident.empty} in
83+
let obj = free_variables init in
84+
obj.statement obj st ;
8285
Set_ident.diff init.used_idents init.defined_idents
8386

8487
let free_variables_of_expression st =
8588
let init = {used_idents = Set_ident.empty;
8689
defined_idents = Set_ident.empty} in
87-
let _ = (free_variables init)#expression st in
90+
let obj = free_variables init in
91+
obj.expression obj st ;
8892
Set_ident.diff init.used_idents init.defined_idents
8993

9094
let rec no_side_effect_expression_desc (x : J.expression_desc) =
@@ -139,32 +143,28 @@ and no_side_effect (x : J.expression) =
139143

140144
let no_side_effect_expression (x : J.expression) = no_side_effect x
141145

142-
let no_side_effect clean : Js_iter.iter =
143-
object (self)
144-
inherit Js_iter.iter as super
145-
method! statement s =
146-
if !clean then
146+
let super = Js_record_iter.iter
147+
let no_side_effect_obj =
148+
{super with
149+
statement = (fun self s ->
147150
match s.statement_desc with
148151
| Throw _
149152
| Debugger
150153
| Break
151154
| Variable _
152155
| Continue _ ->
153-
clean := false
154-
| Exp e -> self#expression e
156+
raise_notrace Not_found
157+
| Exp e -> self.expression self e
155158
| Int_switch _ | String_switch _ | ForRange _
156-
| If _ | While _ | Block _ | Return _ | Try _ -> super#statement s
157-
method! list f x =
158-
if !clean then super#list f x
159-
method! expression s =
160-
if !clean then
161-
clean := no_side_effect_expression s
162-
(** only expression would cause side effec *)
163-
end
159+
| If _ | While _ | Block _ | Return _ | Try _ -> super.statement self s );
160+
expression = begin fun _ s ->
161+
if not (no_side_effect_expression s) then raise_notrace Not_found
162+
end}
164163
let no_side_effect_statement st =
165-
let clean = ref true in
166-
(no_side_effect clean)#statement st;
167-
!clean
164+
try
165+
no_side_effect_obj.statement no_side_effect_obj st; true
166+
with _ -> false
167+
168168

169169
(* TODO: generate [fold2]
170170
This make sense, for example:

jscomp/core/js_fold.ml

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11

22
open J
33
let [@inline] unknown _self _ = _self
4+
let [@inline] option sub self = fun v ->
5+
match v with
6+
| None -> self
7+
| Some x -> sub self x
8+
let rec list (sub : 'self_type -> 'a -> 'self_type) self = fun v ->
9+
match v with
10+
| [] -> self
11+
| x::xs ->
12+
let self = sub self x in
13+
list sub self xs
414
class fold =
515
object ((_self : 'self_type))
6-
method option :
7-
'a. ('self_type -> 'a -> 'self_type) -> 'a option -> 'self_type =
8-
fun _f_a -> function | None -> _self | Some _x -> let _self = _f_a _self _x in _self
916
method list :
1017
'a. ('self_type -> 'a -> 'self_type) -> 'a list -> 'self_type =
1118
fun _f_a ->
1219
function
1320
| [] -> _self
1421
| _x :: _x_i1 -> let _self = _f_a _self _x in let _self = _self#list _f_a _x_i1 in _self
1522
method label : label -> 'self_type = unknown _self
16-
method required_modules : required_modules -> 'self_type = _self#list (fun _self -> _self#module_id)
23+
method required_modules : required_modules -> 'self_type = list (fun _self -> _self#module_id) _self
1724
method ident : ident -> 'self_type = unknown _self
1825
method module_id : module_id -> 'self_type = fun { id = _x0;kind = _x1} -> let _self = _self#ident _x0 in _self
1926
method vident : vident -> 'self_type = function
@@ -22,12 +29,11 @@ let _self = _self#ident _x0 in
2229
_self
2330
|Qualified ( _x0,_x1) ->
2431
let _self = _self#module_id _x0 in
25-
let _self = _self#option (fun _self -> unknown _self) _x1 in
2632
_self
2733
method exception_ident : exception_ident -> 'self_type = _self#ident
2834
method for_ident : for_ident -> 'self_type = _self#ident
2935
method for_direction : for_direction -> 'self_type = unknown _self
30-
method property_map : property_map -> 'self_type = _self#list (fun _self -> fun ( _x0,_x1) -> let _self = _self#expression _x1 in _self)
36+
method property_map : property_map -> 'self_type = list (fun _self -> fun ( _x0,_x1) -> let _self = _self#expression _x1 in _self) _self
3137
method length_object : length_object -> 'self_type = unknown _self
3238
method expression_desc : expression_desc -> 'self_type = function
3339
| Length ( _x0,_x1) ->
@@ -73,7 +79,7 @@ let _self = _self#expression _x1 in
7379
_self
7480
|Call ( _x0,_x1,_x2) ->
7581
let _self = _self#expression _x0 in
76-
let _self = _self#list (fun _self -> _self#expression) _x1 in
82+
let _self = list (fun _self -> _self#expression) _self _x1 in
7783
_self
7884
|String_index ( _x0,_x1) ->
7985
let _self = _self#expression _x0 in
@@ -85,30 +91,29 @@ let _self = _self#expression _x1 in
8591
_self
8692
|Static_index ( _x0,_x1,_x2) ->
8793
let _self = _self#expression _x0 in
88-
let _self = _self#option (fun _self -> unknown _self) _x2 in
8994
_self
9095
|New ( _x0,_x1) ->
9196
let _self = _self#expression _x0 in
92-
let _self = _self#option (fun _self -> _self#list (fun _self -> _self#expression)) _x1 in
97+
let _self = option (fun _self -> list (fun _self -> _self#expression) _self) _self _x1 in
9398
_self
9499
|Var ( _x0) ->
95100
let _self = _self#vident _x0 in
96101
_self
97102
|Fun ( _x0,_x1,_x2,_x3) ->
98-
let _self = _self#list (fun _self -> _self#ident) _x1 in
103+
let _self = list (fun _self -> _self#ident) _self _x1 in
99104
let _self = _self#block _x2 in
100105
_self
101106
|Str _ -> _self
102107
|Unicode _ -> _self
103108
|Raw_js_code _ -> _self
104109
|Array ( _x0,_x1) ->
105-
let _self = _self#list (fun _self -> _self#expression) _x0 in
110+
let _self = list (fun _self -> _self#expression) _self _x0 in
106111
_self
107112
|Optional_block ( _x0,_x1) ->
108113
let _self = _self#expression _x0 in
109114
_self
110115
|Caml_block ( _x0,_x1,_x2,_x3) ->
111-
let _self = _self#list (fun _self -> _self#expression) _x0 in
116+
let _self = list (fun _self -> _self#expression) _self _x0 in
112117
let _self = _self#expression _x2 in
113118
_self
114119
|Caml_block_tag ( _x0) ->
@@ -138,12 +143,12 @@ let _self = _self#block _x1 in
138143
let _self = _self#block _x2 in
139144
_self
140145
|While ( _x0,_x1,_x2,_x3) ->
141-
let _self = _self#option (fun _self -> _self#label) _x0 in
146+
let _self = option (fun _self -> _self#label) _self _x0 in
142147
let _self = _self#expression _x1 in
143148
let _self = _self#block _x2 in
144149
_self
145150
|ForRange ( _x0,_x1,_x2,_x3,_x4,_x5) ->
146-
let _self = _self#option (fun _self -> _self#for_ident_expression) _x0 in
151+
let _self = option (fun _self -> _self#for_ident_expression) _self _x0 in
147152
let _self = _self#finish_ident_expression _x1 in
148153
let _self = _self#for_ident _x2 in
149154
let _self = _self#for_direction _x3 in
@@ -158,37 +163,33 @@ let _self = _self#expression _x0 in
158163
_self
159164
|Int_switch ( _x0,_x1,_x2) ->
160165
let _self = _self#expression _x0 in
161-
let _self = _self#list (fun _self -> _self#int_clause) _x1 in
162-
let _self = _self#option (fun _self -> _self#block) _x2 in
166+
let _self = list (fun _self -> _self#int_clause) _self _x1 in
167+
let _self = option (fun _self -> _self#block) _self _x2 in
163168
_self
164169
|String_switch ( _x0,_x1,_x2) ->
165170
let _self = _self#expression _x0 in
166-
let _self = _self#list (fun _self -> _self#string_clause) _x1 in
167-
let _self = _self#option (fun _self -> _self#block) _x2 in
171+
let _self = list (fun _self -> _self#string_clause) _self _x1 in
172+
let _self = option (fun _self -> _self#block) _self _x2 in
168173
_self
169174
|Throw ( _x0) ->
170175
let _self = _self#expression _x0 in
171176
_self
172177
|Try ( _x0,_x1,_x2) ->
173178
let _self = _self#block _x0 in
174-
let _self = _self#option (fun _self -> fun ( _x0,_x1) -> let _self = _self#exception_ident _x0 in let _self = _self#block _x1 in _self) _x1 in
175-
let _self = _self#option (fun _self -> _self#block) _x2 in
179+
let _self = option (fun _self -> fun ( _x0,_x1) -> let _self = _self#exception_ident _x0 in let _self = _self#block _x1 in _self) _self _x1 in
180+
let _self = option (fun _self -> _self#block) _self _x2 in
176181
_self
177182
|Debugger -> _self
178-
method expression : expression -> 'self_type = fun { expression_desc = _x0;comment = _x1} -> let _self = _self#expression_desc _x0 in
179-
let _self = _self#option (fun _self -> unknown _self) _x1 in _self
180-
method statement : statement -> 'self_type = fun { statement_desc = _x0;comment = _x1} -> let _self = _self#statement_desc _x0 in
181-
let _self = _self#option (fun _self -> unknown _self) _x1 in _self
183+
method expression : expression -> 'self_type = fun { expression_desc = _x0;comment = _x1} -> let _self = _self#expression_desc _x0 in _self
184+
method statement : statement -> 'self_type = fun { statement_desc = _x0;comment = _x1} -> let _self = _self#statement_desc _x0 in _self
182185
method variable_declaration : variable_declaration -> 'self_type = fun { ident = _x0;value = _x1;property = _x2;ident_info = _x3} -> let _self = _self#ident _x0 in
183-
let _self = _self#option (fun _self -> _self#expression) _x1 in _self
186+
let _self = option (fun _self -> _self#expression) _self _x1 in _self
184187
method string_clause : string_clause -> 'self_type = fun ( _x0,_x1) -> let _self = _self#case_clause _x1 in _self
185188
method int_clause : int_clause -> 'self_type = fun ( _x0,_x1) -> let _self = _self#case_clause _x1 in _self
186-
method case_clause : case_clause -> 'self_type = fun { switch_body = _x0;should_break = _x1;comment = _x2} -> let _self = _self#block _x0 in
187-
let _self = _self#option (fun _self -> unknown _self) _x2 in _self
188-
method block : block -> 'self_type = _self#list (fun _self -> _self#statement)
189+
method case_clause : case_clause -> 'self_type = fun { switch_body = _x0;should_break = _x1;comment = _x2} -> let _self = _self#block _x0 in _self
190+
method block : block -> 'self_type = list (fun _self -> _self#statement) _self
189191
method program : program -> 'self_type = fun { block = _x0;exports = _x1;export_set = _x2} -> let _self = _self#block _x0 in _self
190192
method deps_program : deps_program -> 'self_type = fun { program = _x0;modules = _x1;side_effect = _x2} -> let _self = _self#program _x0 in
191-
let _self = _self#required_modules _x1 in
192-
let _self = _self#option (fun _self -> unknown _self) _x2 in _self
193+
let _self = _self#required_modules _x1 in _self
193194
end
194195

jscomp/core/js_fold_basic.ml

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,30 @@
2727

2828
let add_lam_module_ident = Lam_module_ident.Hash_set.add
2929
let create = Lam_module_ident.Hash_set.create
30-
let count_hard_dependencies hard_dependencies =
31-
object
32-
inherit Js_iter.iter as super
33-
method! module_id vid =
34-
add_lam_module_ident hard_dependencies vid
35-
method! expression x =
36-
(* check {!Js_pass_scope} when making changes *)
30+
31+
let super = Js_record_iter.iter
32+
let count_hard_dependencies hard_dependencies = {
33+
super with
34+
module_id = begin
35+
fun _ vid ->
36+
add_lam_module_ident hard_dependencies vid
37+
end;
38+
expression = begin
39+
fun self x ->
3740
(match Js_block_runtime.check_additional_id x with
3841
| Some id ->
3942
add_lam_module_ident hard_dependencies
4043
(Lam_module_ident.of_runtime
4144
id)
4245
| _ -> ());
43-
super#expression x
44-
end
46+
super.expression self x
47+
end
48+
}
4549

4650
let calculate_hard_dependencies block =
4751
let hard_dependencies = create 17 in
48-
(count_hard_dependencies hard_dependencies)#block block ;
52+
let obj = (count_hard_dependencies hard_dependencies) in
53+
obj.block obj block ;
4954
hard_dependencies
5055

5156
(*

0 commit comments

Comments
 (0)