Create an instance of a callable class for a function. Calls to the function will actually call this instance. Note that fn_info refers to the function being assigned, whereas builder.fn_info refers to the function encapsulating the function being turned into a callable class.
(builder: IRBuilder, fn_info: FuncInfo)
| 201 | |
| 202 | |
| 203 | def instantiate_callable_class(builder: IRBuilder, fn_info: FuncInfo) -> Value: |
| 204 | """Create an instance of a callable class for a function. |
| 205 | |
| 206 | Calls to the function will actually call this instance. |
| 207 | |
| 208 | Note that fn_info refers to the function being assigned, whereas |
| 209 | builder.fn_info refers to the function encapsulating the function |
| 210 | being turned into a callable class. |
| 211 | """ |
| 212 | fitem = fn_info.fitem |
| 213 | func_reg = builder.add(Call(fn_info.callable_class.ir.ctor, [], fitem.line)) |
| 214 | |
| 215 | # Set the environment attribute of the callable class to point at |
| 216 | # the environment class defined in the callable class' immediate |
| 217 | # outer scope. Note that there are three possible environment |
| 218 | # class registers we may use. This depends on what the encapsulating |
| 219 | # (parent) function is: |
| 220 | # |
| 221 | # - A nested function: the callable class is instantiated |
| 222 | # from the current callable class' '__call__' function, and hence |
| 223 | # the callable class' environment register is used. |
| 224 | # - A generator function: the callable class is instantiated |
| 225 | # from the '__next__' method of the generator class, and hence the |
| 226 | # environment of the generator class is used. |
| 227 | # - Regular function or comprehension scope: we use the environment |
| 228 | # of the original function. Comprehension scopes are inlined (no |
| 229 | # callable class), so they fall into this case despite is_nested. |
| 230 | curr_env_reg = None |
| 231 | if builder.fn_info.is_generator: |
| 232 | curr_env_reg = builder.fn_info.generator_class.curr_env_reg |
| 233 | elif builder.fn_info.is_nested and not builder.fn_info.is_comprehension_scope: |
| 234 | curr_env_reg = builder.fn_info.callable_class.curr_env_reg |
| 235 | elif builder.fn_info.contains_nested: |
| 236 | curr_env_reg = builder.fn_info.curr_env_reg |
| 237 | if curr_env_reg: |
| 238 | builder.add(SetAttr(func_reg, ENV_ATTR_NAME, curr_env_reg, fitem.line)) |
| 239 | # Initialize function wrapper for callable classes. As opposed to regular functions, |
| 240 | # each instance of a callable class needs its own wrapper because they might be instantiated |
| 241 | # inside other functions. |
| 242 | if not fn_info.in_non_ext and fn_info.is_coroutine: |
| 243 | builder.add_coroutine_setup_call(fn_info.callable_class.ir.name, func_reg) |
| 244 | return func_reg |
no test coverage detected
searching dependent graphs…