This module provides support for closures and inner functions.
@autojit def outer():
a = 10 # this is a cellvar
@jit(‘void()’) def inner():
print a # this is a freevarinner() a = 12 return inner
The ‘inner’ function closes over the outer scope. Each function with cellvars packs them into a heap-allocated structure, the closure scope.
The closure scope is passed into ‘inner’ when called from within outer.
The closure scope is an extension type with the cellvars as attributes. Closure scopes are chained together, since multiple inner scopes may need to share a single outer scope. E.g.
- def outer(a):
- def inner(b):
- def inner_inner():
- print a, b
return inner_inner
return inner(1), inner(2)
We have three live closure scopes here:
scope_outer = { ‘a’: a } # call to ‘outer’ scope_inner_1 = { ‘scope_outer’: scope_outer, ‘b’: 1 } # call to ‘inner’ with b=1 scope_inner_2 = { ‘scope_outer’: scope_outer, ‘b’: 2 } # call to ‘inner’ with b=2
Function ‘inner_inner’ defines no new scope, since it contains no cellvars. But it does contain a freevar from scope_outer and scope_inner, so it gets scope_inner passed as first argument. scope_inner has a reference to scope outer, so all variables can be resolved.
These scopes are instances of a numba extension class.
Runs during late specialization.
- Instantiates the closure scope and makes the necessary assignments
- Rewrites local variable accesses to accesses on the instantiated scope
- Instantiate function with closure scope
Assign closure to its name. NOT USED, already happened in CFG
Compile the inner function.
Instantiate a closure scope.
After instantiation, assign the parent scope and all function arguments that belong in the scope to the scope.
Resolve cellvars and freevars
Handles closures during type inference. Mostly performs error checking for closure signatures.
Generates ClosureNodes that hold inner functions. When visited, they do not recurse into the inner functions themselves!
Runs just after type inference after the outer variables types are resolved.
Patch closures to get the closure scope as the first argument.
Look up a variable in the closure scope
Process closures recursively and for each variable in each function determine whether it is a freevar, a cellvar, a local or otherwise.