def build_array(self): self.dst_data = nodes.LLVMValueRefNode(void.pointer(), None) self.dst_shape = nodes.LLVMValueRefNode(self.shape_type, None) self.dst_strides = nodes.LLVMValueRefNode(self.shape_type, None) array_node = nodes.ArrayNewNode( self.type, self.dst_data, self.dst_shape, self.dst_strides, base=self.value.clone) return nodes.CoercionNode(array_node, self.type)
def visit_Name(self, node): if (is_obj(node.type) and isinstance(node.ctx, ast.Load) and getattr(node, 'cf_maybe_null', False)): # Check for unbound objects and raise UnboundLocalError if so value = nodes.LLVMValueRefNode(Py_uintptr_t, None) node.loaded_name = value exc_msg = node.variable.name if hasattr(node, 'lineno'): exc_msg = '%s%s' % (error.format_pos(node), exc_msg) check_unbound = nodes.CheckErrorNode(value, badval=nodes.const( 0, Py_uintptr_t), exc_type=UnboundLocalError, exc_msg=exc_msg) node.check_unbound = self.visit(check_unbound) return node
def get_closure_scope(func_signature, func_obj): """ Retrieve the closure from the NumbaFunction from the func_closure attribute. func_signature: signature of closure function func_obj: LLVM Value referencing the closure function as a Python object """ closure_scope_type = func_signature.args[0] offset = numbawrapper.numbafunc_closure_field_offset closure = nodes.LLVMValueRefNode(void.pointer(), func_obj) closure = nodes.CoercionNode(closure, char.pointer()) closure_field = nodes.pointer_add(closure, nodes.const(offset, size_t)) closure_field = nodes.CoercionNode(closure_field, closure_scope_type.pointer()) closure_scope = nodes.DereferenceNode(closure_field) return closure_scope
def __init__(self, array_type, operands, **kwargs): super(BroadcastNode, self).__init__(**kwargs) self.operands = operands self.shape_type = numba.carray(npy_intp, array_type.ndim) self.array_type = array_type self.type = npy_intp.pointer() self.broadcast_retvals = {} self.check_errors = [] for op in operands: if op.type.is_array: # TODO: Put the raise code in a separate basic block and jump return_value = nodes.LLVMValueRefNode(int_, None) check_error = nodes.CheckErrorNode( return_value, 0, exc_type=ValueError, exc_msg="Shape mismatch while broadcasting") self.broadcast_retvals[op] = return_value self.check_errors.append(check_error)
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