[closure] Keep closure parameter in specialized procedure

Summary:
This diff keeps closure parameters in closure-specializated procedures.

What the closure-specialization is doing is a propagation of concrete closures.  For example, it
translates:

```
foo(block b) {
  b();
}

goo() {
  foo(^{...});
}
```

to

```
foo_new() {
  (^{...})();
}

goo() {
  foo_new();
}
```

However, if `foo` addresses `b` as a normal value like

```
foo(block b) {
  block c = b;
}
```

this is translated to

```
foo_new() {
  block c = b;
}
```

Note that the closure parameter of `foo` is removed, thus `b` becomes a free variable.  Not good.
To avoid the situation, this diff keeps the closure parameters intact.

Reviewed By: da319

Differential Revision: D23905580

fbshipit-source-id: 014989fbf
master
Sungkeun Cho 4 years ago committed by Facebook GitHub Bot
parent 26dcd63a25
commit a9e2322bda

@ -56,6 +56,7 @@ let formals_actuals_new_set map =
(fun formal actual set ->
match actual with
| Exp.Closure closure, _ ->
let set = FormalsActualsSet.add {formal; actual} set in
List.fold_left closure.Exp.captured_vars ~init:set ~f:(fun set (exp, var, typ, _) ->
let formal_annot =
{formal_type= (Pvar.build_formal_from_pvar var, typ); formal_annot= Annot.Item.empty}

@ -50,7 +50,8 @@ module Call = struct
[ +PatternMatch.ObjectiveC.implements "NSObject" &:: "autorelease" &--> unit_cost
; -"CFAutorelease" &--> unit_cost
; +PatternMatch.ObjectiveC.implements "NSArray"
&:: "indexOfObjectPassingTest:" $ capt_exp $--> NSArray.index_of_object_passing_test
&:: "indexOfObjectPassingTest:" $ capt_exp $+ any_arg
$--> NSArray.index_of_object_passing_test
; +PatternMatch.ObjectiveC.implements "NSKeyedUnarchiver"
&:: "initForReadingFromData:error:" &--> unit_cost
; +PatternMatch.ObjectiveC.implements "NSKeyedUnarchiver"

@ -52,7 +52,7 @@ digraph cfg {
"capture#A#instance.d411336575e4bf632a1828f5f5979726_2" [label="2: Exit A.capture \n " color=yellow style=filled]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$3=*&self:A* [line 45, column 4]\n n$4=*n$3._b:B* [line 45, column 4]\n n$0=*&self:A* [line 45, column 16]\n n$5=_fun_B.sHandler:[objc_blockA.capture_1](n$0:A*,n$4:B*) virtual [line 45, column 3]\n " shape="box"]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$3=*&self:A* [line 45, column 4]\n n$4=*n$3._b:B* [line 45, column 4]\n n$0=*&self:A* [line 45, column 16]\n n$5=_fun_B.sHandler:[objc_blockA.capture_1](n$0:A*,n$4:B*,(_fun_objc_blockA.capture_1,([by ref]n$0 &self:A*)):_fn_(*)) virtual [line 45, column 3]\n " shape="box"]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" -> "capture#A#instance.d411336575e4bf632a1828f5f5979726_2" ;

@ -88,7 +88,7 @@ digraph cfg {
"bar2#A#instance.413fa5106d6a23f2bf18df99659efb82_3" -> "bar2#A#instance.413fa5106d6a23f2bf18df99659efb82_2" ;
"bar2#A#instance.413fa5106d6a23f2bf18df99659efb82_4" [label="4: Call _fun_foo \n n$14=*&self:A* [line 40, column 7]\n n$16=*&self:A* [line 43, column 7]\n n$18=*&self:A* [line 46, column 7]\n n$19=_fun_foo[objc_blockA.bar2_3^objc_blockA.bar2_4](n$14:A*,n$18:A*) [line 39, column 3]\n " shape="box"]
"bar2#A#instance.413fa5106d6a23f2bf18df99659efb82_4" [label="4: Call _fun_foo \n n$14=*&self:A* [line 40, column 7]\n n$16=*&self:A* [line 43, column 7]\n n$18=*&self:A* [line 46, column 7]\n n$19=_fun_foo[objc_blockA.bar2_3^objc_blockA.bar2_4](n$14:A*,(_fun_objc_blockA.bar2_4,([by ref]n$16 &self:A*)):_fn_(*),(_fun_objc_blockA.bar2_3,([by ref]n$14 &self:A*)):_fn_(*),n$18:A*) [line 39, column 3]\n " shape="box"]
"bar2#A#instance.413fa5106d6a23f2bf18df99659efb82_4" -> "bar2#A#instance.413fa5106d6a23f2bf18df99659efb82_3" ;
@ -107,7 +107,7 @@ digraph cfg {
"bar:#A(class A)#instance.3e4a860660eb436d473f8ceeb9c1a72b_4" -> "bar:#A(class A)#instance.3e4a860660eb436d473f8ceeb9c1a72b_3" ;
"bar:#A(class A)#instance.3e4a860660eb436d473f8ceeb9c1a72b_5" [label="5: Call _fun_foo \n n$3=*&self:A* [line 27, column 7]\n n$4=*&x:int [line 27, column 7]\n n$7=*&self:A* [line 30, column 7]\n n$10=*&a:A* [line 33, column 7]\n n$11=_fun_foo[objc_blockA.bar:_1^objc_blockA.bar:_2](n$4:int,n$3:A*,n$10:A*) [line 26, column 3]\n " shape="box"]
"bar:#A(class A)#instance.3e4a860660eb436d473f8ceeb9c1a72b_5" [label="5: Call _fun_foo \n n$3=*&self:A* [line 27, column 7]\n n$4=*&x:int [line 27, column 7]\n n$7=*&self:A* [line 30, column 7]\n n$10=*&a:A* [line 33, column 7]\n n$11=_fun_foo[objc_blockA.bar:_1^objc_blockA.bar:_2](n$4:int,n$3:A*,(_fun_objc_blockA.bar:_2,([by ref]n$7 &self:A*)):_fn_(*),(_fun_objc_blockA.bar:_1,([by ref]n$3 &self:A*),([by ref]n$4 &x:int)):_fn_(*),n$10:A*) [line 26, column 3]\n " shape="box"]
"bar:#A(class A)#instance.3e4a860660eb436d473f8ceeb9c1a72b_5" -> "bar:#A(class A)#instance.3e4a860660eb436d473f8ceeb9c1a72b_4" ;
@ -126,11 +126,11 @@ digraph cfg {
"call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_3" -> "call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_2" ;
"call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_4" [label="4: Call _fun_foo \n n$22=*&b:_fn_(*) [line 55, column 7]\n n$23=*&b:_fn_(*) [line 55, column 10]\n n$24=*&self:A* [line 55, column 13]\n n$25=_fun_foo[objc_blockA.call_foo_with_same_param_5^objc_blockA.call_foo_with_same_param_5](n$30:A*,n$24:A*) [line 55, column 3]\n " shape="box"]
"call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_4" [label="4: Call _fun_foo \n n$22=*&b:_fn_(*) [line 55, column 7]\n n$23=*&b:_fn_(*) [line 55, column 10]\n n$24=*&self:A* [line 55, column 13]\n n$25=_fun_foo[objc_blockA.call_foo_with_same_param_5^objc_blockA.call_foo_with_same_param_5](n$30:A*,(_fun_objc_blockA.call_foo_with_same_param_5,([by ref]n$30 &self:A*)):_fn_(*),(_fun_objc_blockA.call_foo_with_same_param_5,([by ref]n$30 &self:A*)):_fn_(*),n$24:A*) [line 55, column 3]\n " shape="box"]
"call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_4" -> "call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_3" ;
"call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_5" [label="5: Call _fun_foo \n n$26=*&b:_fn_(*) [line 54, column 7]\n n$27=*&b:_fn_(*) [line 54, column 10]\n n$28=*&self:A* [line 54, column 13]\n n$29=_fun_foo[objc_blockA.call_foo_with_same_param_5^objc_blockA.call_foo_with_same_param_5](n$30:A*,n$28:A*) [line 54, column 3]\n " shape="box"]
"call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_5" [label="5: Call _fun_foo \n n$26=*&b:_fn_(*) [line 54, column 7]\n n$27=*&b:_fn_(*) [line 54, column 10]\n n$28=*&self:A* [line 54, column 13]\n n$29=_fun_foo[objc_blockA.call_foo_with_same_param_5^objc_blockA.call_foo_with_same_param_5](n$30:A*,(_fun_objc_blockA.call_foo_with_same_param_5,([by ref]n$30 &self:A*)):_fn_(*),(_fun_objc_blockA.call_foo_with_same_param_5,([by ref]n$30 &self:A*)):_fn_(*),n$28:A*) [line 54, column 3]\n " shape="box"]
"call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_5" -> "call_foo_with_same_param#A#instance.7f01b1476c1662f7ce825ec7b1739a00_4" ;

@ -33,7 +33,7 @@ digraph cfg {
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_2" ;
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$4=*&self:B* [line 23, column 10]\n n$5=*n$4.h:int [line 23, column 10]\n n$2=*&self:B* const [line 24, column 11]\n n$6=_fun_B.foo:and:[objc_blockB.f_1](n$5:int,n$2:B* const ) [line 23, column 3]\n " shape="box"]
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$4=*&self:B* [line 23, column 10]\n n$5=*n$4.h:int [line 23, column 10]\n n$2=*&self:B* const [line 24, column 11]\n n$6=_fun_B.foo:and:[objc_blockB.f_1](n$5:int,n$2:B* const ,(_fun_objc_blockB.f_1,([by ref]n$2 &self:B* const )):_fn_(*)) [line 23, column 3]\n " shape="box"]
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" ;

@ -63,7 +63,7 @@ digraph cfg {
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_2" [label="2: Exit MyBlock.array \n " color=yellow style=filled]
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_3" [label="3: Message Call: enumerateObjectsUsingBlock: \n n$5=*&a:NSArray* [line 19, column 4]\n n$6=_fun_NSArray.enumerateObjectsUsingBlock:[objc_blockMyBlock.array_1](n$5:NSArray*) virtual [line 19, column 3]\n " shape="box"]
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_3" [label="3: Message Call: enumerateObjectsUsingBlock: \n n$5=*&a:NSArray* [line 19, column 4]\n n$6=_fun_NSArray.enumerateObjectsUsingBlock:[objc_blockMyBlock.array_1](n$5:NSArray*,(_fun_objc_blockMyBlock.array_1):_fn_(*)) virtual [line 19, column 3]\n " shape="box"]
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_3" -> "array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_2" ;

Loading…
Cancel
Save