def build_wrapper_function_ast(env, wrapper_lfunc, llvm_module): """ Build AST for LLVM function wrapper. lfunc: LLVM function to wrap llvm_module: module the wrapper is being defined in The resulting AST has a NativeCallNode to the wrapped function. The arguments are LLVMValueRefNode nodes which still need their llvm_value set to the object from the tuple. This happens in visit_FunctionWrapperNode during codegen. """ func = env.crnt.func func_signature = env.crnt.func_signature func_name = env.crnt.func_name # Insert external declaration lfunc = llvm_module.get_or_insert_function(func_signature.to_llvm(env.context), env.crnt.lfunc.name) # Build AST wrapper = nodes.FunctionWrapperNode(lfunc, func_signature, func, fake_pyfunc, func_name) error_return = ast.Return(nodes.CoercionNode(nodes.NULL_obj, object_)) is_closure = bool(closures.is_closure_signature(func_signature)) nargs = len(func_signature.args) - is_closure # Call wrapped function with unpacked object arguments # (delay actual arguments) args = [nodes.LLVMValueRefNode(object_, None) for i in range(nargs)] if is_closure: # Insert m_self as scope argument type closure_scope = get_closure_scope(func_signature, wrapper_lfunc.args[0]) args.insert(0, closure_scope) func_call = nodes.NativeCallNode(func_signature, args, lfunc) if not is_obj(func_signature.return_type): # Check for error using PyErr_Occurred() func_call = nodes.PyErr_OccurredNode(func_call) # Coerce and return result if func_signature.return_type.is_void: wrapper.body = func_call result_node = nodes.ObjectInjectNode(None) else: wrapper.body = None result_node = func_call wrapper.return_result = ast.Return(value=nodes.CoercionNode(result_node, object_)) # Update wrapper wrapper.error_return = error_return wrapper.cellvars = [] wrapper.wrapped_nargs = nargs wrapper.wrapped_args = args[is_closure:] return wrapper
def build_wrapper_function_ast(env, wrapper_lfunc, llvm_module): """ Build AST for LLVM function wrapper. lfunc: LLVM function to wrap llvm_module: module the wrapper is being defined in The resulting AST has a NativeCallNode to the wrapped function. The arguments are LLVMValueRefNode nodes which still need their llvm_value set to the object from the tuple. This happens in visit_FunctionWrapperNode during codegen. """ func = env.crnt.func func_signature = env.crnt.func_signature func_name = env.crnt.func_name # Insert external declaration lfunc = llvm_module.get_or_insert_function( func_signature.to_llvm(env.context), env.crnt.lfunc.name) # Build AST wrapper = nodes.FunctionWrapperNode(lfunc, func_signature, func, fake_pyfunc, func_name) error_return = ast.Return(nodes.CoercionNode(nodes.NULL_obj, object_)) is_closure = bool(closures.is_closure_signature(func_signature)) nargs = len(func_signature.args) - is_closure # Call wrapped function with unpacked object arguments # (delay actual arguments) args = [nodes.LLVMValueRefNode(object_, None) for i in range(nargs)] if is_closure: # Insert m_self as scope argument type closure_scope = get_closure_scope(func_signature, wrapper_lfunc.args[0]) args.insert(0, closure_scope) func_call = nodes.NativeCallNode(func_signature, args, lfunc) if not is_obj(func_signature.return_type): # Check for error using PyErr_Occurred() func_call = nodes.PyErr_OccurredNode(func_call) # Coerce and return result if func_signature.return_type.is_void: wrapper.body = func_call result_node = nodes.ObjectInjectNode(None) else: wrapper.body = None result_node = func_call wrapper.return_result = ast.Return(value=nodes.CoercionNode(result_node, object_)) # Update wrapper wrapper.error_return = error_return wrapper.cellvars = [] wrapper.wrapped_nargs = nargs wrapper.wrapped_args = args[is_closure:] return wrapper
def is_closure_signature(self, func_signature): from numba import closures return closures.is_closure_signature(func_signature)