You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

22 lines
1.0 KiB

[clang] Executing methods with blocks as parameters by instantiating the parameters with current blocks Summary: This diff adds a new way of executing blocks when they are passed as parameters to a method. So far we just skipped the block in this case. Now we can execute it. Let's demonstrate with an example. Say we have //foo has a block parameter that it executes in its body foo (Block block) { block();} // bar calls foo with a concrete block bar() { foo (^(){ self->x = 10; }); }; Now, when we call the method foo with a concrete block, we create a copy of foo instantiated with the concrete block, which in itself is translated as a method with a made-up name. The copy of foo will get a name that is foo extended with the name of the block parameter, the call to the block parameter will be replaced to a call to the concrete block, and the captured variables of the concrete block (self in this case), will be added to the formals of the specialized method foo_block_name. This is turned on at the moment for ObjC methods with ObjC blocks as parameters, and called with concrete blocks. Later on we can extend it to other types of methods, and to C++ lambdas, that are handled similarly to blocks. Another extension is to check when the block has been called with nil instead of an actual block, and raise an error in that case. After this diff, we can also model various methods and functions from the standard library that take blocks as parameters, and remove frontend hacks to deal with that. Reviewed By: ddino Differential Revision: D6260792 fbshipit-source-id: 0b6f22e
7 years ago
(*
* Copyright (c) 2017 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
val resolve_method_with_block_args_and_analyze :
Procdesc.t -> Typ.Procname.t -> (Exp.t * Typ.t) list
-> (Specs.summary * (Exp.t * Typ.t) list) option
(* [resolve_method_with_block_args_and_analyze caller_pdesc pname args]
create a copy of the method pname if it is defined and it's called with
the correct number of arguments, and some arguments are block closures.
The copy is created by adding extra formals for each captured variable,
and by swapping the calls to the block arguments to the calls to the concrete
blocks.
The new procedure is analyzed and the possibly computed summary is returned
together with the list of arguments where the closures where swapped by their
captured variables. *)