Beispiel #1
0
 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)
Beispiel #2
0
    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
Beispiel #3
0
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
Beispiel #4
0
    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)
Beispiel #5
0
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