コード例 #1
0
def _unbox_native_field(typ, obj, field_name: str, c):
    ret_ptr = cgutils.alloca_once(c.builder, c.context.get_value_type(typ))
    is_error_ptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
    fail_obj = c.context.get_constant_null(typ)

    with local_return(c.builder) as ret:
        fail_blk = c.builder.append_basic_block("fail")
        with c.builder.goto_block(fail_blk):
            c.builder.store(cgutils.true_bit, is_error_ptr)
            c.builder.store(fail_obj, ret_ptr)
            ret()

        field_obj = c.pyapi.object_getattr_string(obj, field_name)
        with cgutils.if_unlikely(c.builder,
                                 cgutils.is_null(c.builder, field_obj)):
            c.builder.branch(fail_blk)

        field_native = c.unbox(typ, field_obj)
        c.pyapi.decref(field_obj)
        with cgutils.if_unlikely(c.builder, field_native.is_error):
            c.builder.branch(fail_blk)

        c.builder.store(cgutils.false_bit, is_error_ptr)
        c.builder.store(field_native.value, ret_ptr)

    return NativeValue(c.builder.load(ret_ptr),
                       is_error=c.builder.load(is_error_ptr))
コード例 #2
0
ファイル: nrtdynmod.py プロジェクト: FedericoStra/numba
def _define_nrt_decref(module, atomic_decr):
    """
    Implement NRT_decref in the module
    """
    fn_decref = module.get_or_insert_function(incref_decref_ty,
                                              name="NRT_decref")
    calldtor = module.add_function(ir.FunctionType(ir.VoidType(), [_pointer_type]),
                                   name="NRT_MemInfo_call_dtor")

    builder = ir.IRBuilder(fn_decref.append_basic_block())
    [ptr] = fn_decref.args
    is_null = builder.icmp_unsigned("==", ptr, cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()

    if _debug_print:
        cgutils.printf(builder, "*** NRT_Decref %zu [%p]\n", builder.load(ptr),
                       ptr)
    newrefct = builder.call(atomic_decr,
                            [builder.bitcast(ptr, atomic_decr.args[0].type)])

    refct_eq_0 = builder.icmp_unsigned("==", newrefct,
                                       ir.Constant(newrefct.type, 0))
    with cgutils.if_unlikely(builder, refct_eq_0):
        builder.call(calldtor, [ptr])
    builder.ret_void()
コード例 #3
0
ファイル: atomicops.py プロジェクト: chas-mellish/numba
def _define_decref(module, atomic_decr):
    """
    Implement NRT_decref in the module
    """
    if "NRT_decref" not in module.globals:
        return
    fn_decref = module.get_global_variable_named("NRT_decref")
    fn_decref.linkage = 'linkonce_odr'
    calldtor = module.add_function(ir.FunctionType(
        ir.VoidType(), [ir.IntType(8).as_pointer(),
                        ir.IntType(32)]),
                                   name="NRT_MemInfo_call_dtor")

    builder = ir.IRBuilder(fn_decref.append_basic_block())
    [ptr] = fn_decref.args
    is_null = builder.icmp_unsigned("==", ptr,
                                    cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()
    newrefct = builder.call(atomic_decr,
                            [builder.bitcast(ptr, atomic_decr.args[0].type)])

    refct_eq_0 = builder.icmp_unsigned("==", newrefct,
                                       ir.Constant(newrefct.type, 0))
    with cgutils.if_unlikely(builder, refct_eq_0):
        do_defer = ir.Constant(ir.IntType(32), 0)
        builder.call(calldtor, [ptr, do_defer])
    builder.ret_void()
コード例 #4
0
    def builtin_lookup(self, mod, name):
        """
        Args
        ----
        mod:
            The __builtins__ dictionary or module, as looked up in
            a module's globals.
        name: str
            The object to lookup
        """
        fromdict = self.pyapi.dict_getitem_string(mod, name)
        self.incref(fromdict)  # fromdict is borrowed
        bbifdict = self.builder.basic_block

        with cgutils.if_unlikely(self.builder, self.is_null(fromdict)):
            # This happen if we are using the __main__ module
            frommod = self.pyapi.object_getattr_string(mod, name)

            with cgutils.if_unlikely(self.builder, self.is_null(frommod)):
                self.pyapi.raise_missing_global_error(name)
                self.return_exception_raised()

            bbifmod = self.builder.basic_block

        builtin = self.builder.phi(self.pyapi.pyobj)
        builtin.add_incoming(fromdict, bbifdict)
        builtin.add_incoming(frommod, bbifmod)

        return builtin
コード例 #5
0
ファイル: atomicops.py プロジェクト: jriehl/numba
def _define_decref(module, atomic_decr):
    """
    Implement NRT_decref in the module
    """
    if "NRT_decref" not in module.globals:
        return
    fn_decref = module.get_global_variable_named("NRT_decref")
    fn_decref.linkage = 'linkonce_odr'
    calldtor = module.add_function(ir.FunctionType(ir.VoidType(),
        [ir.IntType(8).as_pointer(), ir.IntType(32)]),
        name="NRT_MemInfo_call_dtor")

    builder = ir.IRBuilder(fn_decref.append_basic_block())
    [ptr] = fn_decref.args
    is_null = builder.icmp_unsigned("==", ptr, cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()
    newrefct = builder.call(atomic_decr,
                            [builder.bitcast(ptr, atomic_decr.args[0].type)])

    refct_eq_0 = builder.icmp_unsigned("==", newrefct,
                                       ir.Constant(newrefct.type, 0))
    with cgutils.if_unlikely(builder, refct_eq_0):
        do_defer = ir.Constant(ir.IntType(32), 0)
        builder.call(calldtor, [ptr, do_defer])
    builder.ret_void()
コード例 #6
0
    def builtin_lookup(self, mod, name):
        """
        Args
        ----
        mod:
            The __builtins__ dictionary or module, as looked up in
            a module's globals.
        name: str
            The object to lookup
        """
        fromdict = self.pyapi.dict_getitem(mod, self._freeze_string(name))
        self.incref(fromdict)       # fromdict is borrowed
        bbifdict = self.builder.basic_block

        with cgutils.if_unlikely(self.builder, self.is_null(fromdict)):
            # This happen if we are using the __main__ module
            frommod = self.pyapi.object_getattr(mod, self._freeze_string(name))

            with cgutils.if_unlikely(self.builder, self.is_null(frommod)):
                self.pyapi.raise_missing_global_error(name)
                self.return_exception_raised()

            bbifmod = self.builder.basic_block

        builtin = self.builder.phi(self.pyapi.pyobj)
        builtin.add_incoming(fromdict, bbifdict)
        builtin.add_incoming(frommod, bbifmod)

        return builtin
コード例 #7
0
ファイル: nrtdynmod.py プロジェクト: bmk10/GridMateBook_1.18
def _define_nrt_decref(module, atomic_decr):
    """
    Implement NRT_decref in the module
    """
    fn_decref = module.get_or_insert_function(incref_decref_ty,
                                              name="NRT_decref")
    # Cannot inline this for refcount pruning to work
    fn_decref.attributes.add('noinline')
    calldtor = module.add_function(ir.FunctionType(ir.VoidType(),
                                                   [_pointer_type]),
                                   name="NRT_MemInfo_call_dtor")

    builder = ir.IRBuilder(fn_decref.append_basic_block())
    [ptr] = fn_decref.args
    is_null = builder.icmp_unsigned("==", ptr,
                                    cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()

    if _debug_print:
        cgutils.printf(builder, "*** NRT_Decref %zu [%p]\n", builder.load(ptr),
                       ptr)
    newrefct = builder.call(atomic_decr,
                            [builder.bitcast(ptr, atomic_decr.args[0].type)])

    refct_eq_0 = builder.icmp_unsigned("==", newrefct,
                                       ir.Constant(newrefct.type, 0))
    with cgutils.if_unlikely(builder, refct_eq_0):
        builder.call(calldtor, [ptr])
    builder.ret_void()
コード例 #8
0
ファイル: iterators.py プロジェクト: gyenney/Tools
def iternext_zip(context, builder, sig, args, result):
    genty, = sig.args
    gen, = args
    # XXX We should link with the generator's library.
    # Currently, this doesn't make a difference as the library has already
    # been linked for the generator init function.
    impl = context.get_generator_impl(genty)
    status, retval = impl(context, builder, sig, args)
    with cgutils.if_likely(builder, status.is_ok):
        result.set_valid(True)
        result.yield_(retval)
    with cgutils.if_unlikely(builder, status.is_stop_iteration):
        result.set_exhausted()
    with cgutils.if_unlikely(builder, builder.and_(status.is_error, builder.not_(status.is_stop_iteration))):
        context.call_conv.return_status_propagate(builder, status)
コード例 #9
0
ファイル: lowering.py プロジェクト: jenshnielsen/numba
    def lower_global(self, name, value):
        """
        1) Check global scope dictionary.
        2) Check __builtins__.
            2a) is it a dictionary (for non __main__ module)
            2b) is it a module (for __main__ module)
        """
        moddict = self.pyapi.get_module_dict()
        obj = self.pyapi.dict_getitem_string(moddict, name)
        self.incref(obj)  # obj is borrowed

        if hasattr(builtins, name):
            obj_is_null = self.is_null(obj)
            bbelse = self.builder.basic_block

            with cgutils.ifthen(self.builder, obj_is_null):
                mod = self.pyapi.dict_getitem_string(moddict, "__builtins__")
                builtin = self.builtin_lookup(mod, name)
                bbif = self.builder.basic_block

            retval = self.builder.phi(self.pyapi.pyobj)
            retval.add_incoming(obj, bbelse)
            retval.add_incoming(builtin, bbif)

        else:
            retval = obj
            with cgutils.if_unlikely(self.builder, self.is_null(retval)):
                self.pyapi.raise_missing_global_error(name)
                self.return_exception_raised()

        self.incref(retval)
        return retval
コード例 #10
0
    def check_occurred(self):
        err_occurred = cgutils.is_not_null(self.builder,
                                           self.pyapi.err_occurred())

        with cgutils.if_unlikely(self.builder, err_occurred):
            # FIXME: this should decref all live variables before returning
            self.return_exception_raised()
コード例 #11
0
ファイル: lowering.py プロジェクト: jenshnielsen/numba
    def set_iter_valid(self, state, item):
        iterstate = PyIterState(self.context, self.builder, ref=state)
        iterstate.valid = cgutils.as_bool_byte(
            self.builder, cgutils.is_not_null(self.builder, item))

        with cgutils.if_unlikely(self.builder, self.is_null(item)):
            self.check_occurred()
コード例 #12
0
ファイル: pythonapi.py プロジェクト: johandroid/numba
    def to_native_arg(self, obj, typ):
        if isinstance(typ, types.Record):
            # Generate a dummy integer type that has the size of Py_buffer
            dummy_py_buffer_type = Type.int(_helperlib.py_buffer_size * 8)
            # Allocate the Py_buffer
            py_buffer = cgutils.alloca_once(self.builder, dummy_py_buffer_type)

            # Zero-fill the py_buffer. where the obj field in Py_buffer is NULL
            # PyBuffer_Release has no effect.
            zeroed_buffer = lc.Constant.null(dummy_py_buffer_type)
            self.builder.store(zeroed_buffer, py_buffer)

            buf_as_voidptr = self.builder.bitcast(py_buffer, self.voidptr)
            ptr = self.extract_record_data(obj, buf_as_voidptr)

            with cgutils.if_unlikely(self.builder,
                                     cgutils.is_null(self.builder, ptr)):
                self.builder.ret(ptr)

            ltyp = self.context.get_value_type(typ)
            val = cgutils.init_record_by_ptr(self.builder, ltyp, ptr)

            def dtor():
                self.release_record_buffer(buf_as_voidptr)

        else:
            val = self.to_native_value(obj, typ)

            def dtor():
                pass

        return val, dtor
コード例 #13
0
def iternext_zip(context, builder, sig, args, result):
    genty, = sig.args
    gen, = args
    impl = context.get_generator_impl(genty)
    status, retval = impl(context, builder, sig, args)
    context.add_linking_libs(getattr(impl, 'libs', ()))

    with cgutils.if_likely(builder, status.is_ok):
        result.set_valid(True)
        result.yield_(retval)
    with cgutils.if_unlikely(builder, status.is_stop_iteration):
        result.set_exhausted()
    with cgutils.if_unlikely(builder,
                             builder.and_(status.is_error,
                                          builder.not_(status.is_stop_iteration))):
        context.call_conv.return_status_propagate(builder, status)
コード例 #14
0
ファイル: callwrapper.py プロジェクト: smtlify/numba
    def add_arg(self, obj, ty):
        """
        Unbox argument and emit code that handles any error during unboxing.
        Args are cleaned up in reverse order of the parameter list, and
        cleanup begins as soon as unboxing of any argument fails. E.g. failure
        on arg2 will result in control flow going through:

            arg2.err -> arg1.err -> arg0.err -> arg.end (returns)
        """
        # Unbox argument
        val, dtor = self.api.to_native_arg(self.builder.load(obj), ty)

        # check for Python C-API Error
        error_check = self.api.err_occurred()
        err_happened = self.builder.icmp(lc.ICMP_NE, error_check,
                                         self.api.get_null_object())

        # Write the cleanup block
        cleanupblk = cgutils.append_basic_block(self.builder,
                                                "arg%d.err" % self.arg_count)
        with cgutils.goto_block(self.builder, cleanupblk):
            dtor()
            # Go to next cleanup block
            self.builder.branch(self.nextblk)

        # If an error occurred, go to the cleanup block
        with cgutils.if_unlikely(self.builder, err_happened):
            self.builder.branch(cleanupblk)

        self.cleanups.append(dtor)
        self.nextblk = cleanupblk
        self.arg_count += 1
        return val
コード例 #15
0
 def imp(context, builder, sig, args):
     func = context.declare_function(cgutils.get_module(builder), fndesc)
     status, retval = context.call_function(builder, func, fndesc.restype,
                                            fndesc.argtypes, args)
     with cgutils.if_unlikely(builder, status.err):
         context.return_errcode_propagate(builder, status.code)
     return retval
コード例 #16
0
ファイル: randomimpl.py プロジェクト: smtlify/numba
def get_next_int32(context, builder, state_ptr):
    """
    Get the next int32 generated by the PRNG at *state_ptr*.
    """
    idxptr = get_index_ptr(builder, state_ptr)
    idx = builder.load(idxptr)
    need_reshuffle = builder.icmp_unsigned('>=', idx, N_const)
    with cgutils.if_unlikely(builder, need_reshuffle):
        fnty = ir.FunctionType(ir.VoidType(), (rnd_state_ptr_t,))
        fn = builder.function.module.get_or_insert_function(fnty, "numba_rnd_shuffle")
        builder.call(fn, (state_ptr,))
        builder.store(const_int(0), idxptr)
    idx = builder.load(idxptr)
    array_ptr = get_array_ptr(builder, state_ptr)
    y = builder.load(cgutils.gep(builder, array_ptr, 0, idx))
    idx = builder.add(idx, const_int(1))
    builder.store(idx, idxptr)
    # Tempering
    y = builder.xor(y, builder.lshr(y, const_int(11)))
    y = builder.xor(y, builder.and_(builder.shl(y, const_int(7)),
                                    const_int(0x9d2c5680)))
    y = builder.xor(y, builder.and_(builder.shl(y, const_int(15)),
                                    const_int(0xefc60000)))
    y = builder.xor(y, builder.lshr(y, const_int(18)))
    return y
コード例 #17
0
ファイル: arrayobj.py プロジェクト: PierreBizouard/numba
            def init_specific(self, context, builder, arrty, arr):
                zero = context.get_constant(types.intp, 0)
                data = arr.data
                ndim = arrty.ndim
                shapes = cgutils.unpack_tuple(builder, arr.shape, ndim)

                indices = cgutils.alloca_once(builder, zero.type,
                                              size=context.get_constant(types.intp,
                                                                        arrty.ndim))
                pointers = cgutils.alloca_once(builder, data.type,
                                               size=context.get_constant(types.intp,
                                                                         arrty.ndim))
                strides = cgutils.unpack_tuple(builder, arr.strides, ndim)
                exhausted = cgutils.alloca_once_value(builder, cgutils.false_byte)

                # Initialize indices and pointers with their start values.
                for dim in range(ndim):
                    idxptr = cgutils.gep(builder, indices, dim)
                    ptrptr = cgutils.gep(builder, pointers, dim)
                    builder.store(data, ptrptr)
                    builder.store(zero, idxptr)
                    # 0-sized dimensions really indicate an empty array,
                    # but we have to catch that condition early to avoid
                    # a bug inside the iteration logic (see issue #846).
                    dim_size = shapes[dim]
                    dim_is_empty = builder.icmp(lc.ICMP_EQ, dim_size, zero)
                    with cgutils.if_unlikely(builder, dim_is_empty):
                        builder.store(cgutils.true_byte, exhausted)

                self.indices = indices
                self.pointers = pointers
                self.exhausted = exhausted
コード例 #18
0
            def init_specific(self, context, builder, arrty, arr):
                zero = context.get_constant(types.intp, 0)
                data = arr.data
                ndim = arrty.ndim
                shapes = cgutils.unpack_tuple(builder, arr.shape, ndim)

                indices = cgutils.alloca_once(builder,
                                              zero.type,
                                              size=context.get_constant(
                                                  types.intp, arrty.ndim))
                pointers = cgutils.alloca_once(builder,
                                               data.type,
                                               size=context.get_constant(
                                                   types.intp, arrty.ndim))
                strides = cgutils.unpack_tuple(builder, arr.strides, ndim)
                exhausted = cgutils.alloca_once_value(builder,
                                                      cgutils.false_byte)

                # Initialize indices and pointers with their start values.
                for dim in range(ndim):
                    idxptr = cgutils.gep(builder, indices, dim)
                    ptrptr = cgutils.gep(builder, pointers, dim)
                    builder.store(data, ptrptr)
                    builder.store(zero, idxptr)
                    # 0-sized dimensions really indicate an empty array,
                    # but we have to catch that condition early to avoid
                    # a bug inside the iteration logic (see issue #846).
                    dim_size = shapes[dim]
                    dim_is_empty = builder.icmp(lc.ICMP_EQ, dim_size, zero)
                    with cgutils.if_unlikely(builder, dim_is_empty):
                        builder.store(cgutils.true_byte, exhausted)

                self.indices = indices
                self.pointers = pointers
                self.exhausted = exhausted
コード例 #19
0
ファイル: imputils.py プロジェクト: jiaxu825/numba
 def imp(context, builder, sig, args):
     func = context.declare_function(cgutils.get_module(builder), fndesc)
     status, retval = context.call_function(builder, func, fndesc.restype,
                                            fndesc.argtypes, args)
     with cgutils.if_unlikely(builder, status.err):
         context.return_errcode_propagate(builder, status.code)
     return retval
コード例 #20
0
ファイル: iterators.py プロジェクト: numba/numba
def iternext_zip(context, builder, sig, args, result):
    genty, = sig.args
    gen, = args
    impl = context.get_generator_impl(genty)
    status, retval = impl(context, builder, sig, args)
    context.add_linking_libs(getattr(impl, 'libs', ()))

    with cgutils.if_likely(builder, status.is_ok):
        result.set_valid(True)
        result.yield_(retval)
    with cgutils.if_unlikely(builder, status.is_stop_iteration):
        result.set_exhausted()
    with cgutils.if_unlikely(builder,
                             builder.and_(status.is_error,
                                          builder.not_(status.is_stop_iteration))):
        context.call_conv.return_status_propagate(builder, status)
コード例 #21
0
ファイル: callwrapper.py プロジェクト: PierreBizouard/numba
    def add_arg(self, obj, ty):
        """
        Unbox argument and emit code that handles any error during unboxing.
        Args are cleaned up in reverse order of the parameter list, and
        cleanup begins as soon as unboxing of any argument fails. E.g. failure
        on arg2 will result in control flow going through:

            arg2.err -> arg1.err -> arg0.err -> arg.end (returns)
        """
        # Unbox argument
        native = self.api.to_native_value(self.builder.load(obj), ty)

        # If an error occurred, go to the cleanup block for the previous argument.
        with cgutils.if_unlikely(self.builder, native.is_error):
            self.builder.branch(self.nextblk)

        # Write the cleanup block for this argument
        cleanupblk = cgutils.append_basic_block(self.builder,
                                                "arg%d.err" % self.arg_count)
        with cgutils.goto_block(self.builder, cleanupblk):
            if native.cleanup is not None:
                native.cleanup()
                self.cleanups.append(native.cleanup)
            # Go to next cleanup block
            self.builder.branch(self.nextblk)

        self.nextblk = cleanupblk
        self.arg_count += 1
        return native.value
コード例 #22
0
    def build_wrapper(self, api, builder, closure, args, kws):
        nargs = len(self.fndesc.argtypes)

        objs = [api.alloca_obj() for _ in range(nargs)]
        parseok = api.unpack_tuple(args, self.fndesc.qualname, nargs, nargs,
                                   *objs)

        pred = builder.icmp(lc.ICMP_EQ, parseok, Constant.null(parseok.type))
        with cgutils.if_unlikely(builder, pred):
            builder.ret(api.get_null_object())

        # Block that returns after erroneous argument unboxing/cleanup
        endblk = builder.append_basic_block("arg.end")
        with builder.goto_block(endblk):
            builder.ret(api.get_null_object())

        # Extract the Environment object from the Closure
        envptr, env_manager = self.get_env(api, builder, closure)

        cleanup_manager = _ArgManager(self.context, builder, api, env_manager,
                                      endblk, nargs)

        # Compute the arguments to the compiled Numba function.
        innerargs = []
        for obj, ty in zip(objs, self.fndesc.argtypes):
            if isinstance(ty, types.Omitted):
                # It's an omitted value => ignore dummy Python object
                innerargs.append(None)
            else:
                val = cleanup_manager.add_arg(builder.load(obj), ty)
                innerargs.append(val)

        if self.release_gil:
            cleanup_manager = _GilManager(builder, api, cleanup_manager)

        status, retval = self.context.call_conv.call_function(
            builder,
            self.func,
            self.fndesc.restype,
            self.fndesc.argtypes,
            innerargs,
            env=envptr)
        # Do clean up
        self.debug_print(builder, "# callwrapper: emit_cleanup")
        cleanup_manager.emit_cleanup()
        self.debug_print(builder, "# callwrapper: emit_cleanup end")

        # Determine return status
        with builder.if_then(status.is_ok, likely=True):
            # Ok => return boxed Python value
            with builder.if_then(status.is_none):
                api.return_none()

            retty = self._simplified_return_type()
            obj = api.from_native_return(retty, retval, env_manager)
            builder.ret(obj)

        # Error out
        self.context.call_conv.raise_error(builder, api, status)
        builder.ret(api.get_null_object())
コード例 #23
0
ファイル: lowering.py プロジェクト: MJJoyce/numba
    def lower_global(self, name, value):
        """
        1) Check global scope dictionary.
        2) Check __builtins__.
            2a) is it a dictionary (for non __main__ module)
            2b) is it a module (for __main__ module)
        """
        moddict = self.pyapi.get_module_dict()
        obj = self.pyapi.dict_getitem_string(moddict, name)
        self.incref(obj)  # obj is borrowed

        if hasattr(builtins, name):
            obj_is_null = self.is_null(obj)
            bbelse = self.builder.basic_block

            with cgutils.ifthen(self.builder, obj_is_null):
                mod = self.pyapi.dict_getitem_string(moddict, "__builtins__")
                builtin = self.builtin_lookup(mod, name)
                bbif = self.builder.basic_block

            retval = self.builder.phi(self.pyapi.pyobj)
            retval.add_incoming(obj, bbelse)
            retval.add_incoming(builtin, bbif)

        else:
            retval = obj
            with cgutils.if_unlikely(self.builder, self.is_null(retval)):
                self.pyapi.raise_missing_global_error(name)
                self.return_exception_raised()

        self.incref(retval)
        return retval
コード例 #24
0
    def add_arg(self, obj, ty):
        """
        Unbox argument and emit code that handles any error during unboxing.
        Args are cleaned up in reverse order of the parameter list, and
        cleanup begins as soon as unboxing of any argument fails. E.g. failure
        on arg2 will result in control flow going through:

            arg2.err -> arg1.err -> arg0.err -> arg.end (returns)
        """
        # Unbox argument
        val, dtor = self.api.to_native_arg(self.builder.load(obj), ty)

        # check for Python C-API Error
        error_check = self.api.err_occurred()
        err_happened = self.builder.icmp(lc.ICMP_NE, error_check,
                                         self.api.get_null_object())

        # Write the cleanup block
        cleanupblk = cgutils.append_basic_block(self.builder,
                                                "arg%d.err" % self.arg_count)
        with cgutils.goto_block(self.builder, cleanupblk):
            dtor()
            # Go to next cleanup block
            self.builder.branch(self.nextblk)

        # If an error occurred, go to the cleanup block
        with cgutils.if_unlikely(self.builder, err_happened):
            self.builder.branch(cleanupblk)

        self.cleanups.append(dtor)
        self.nextblk = cleanupblk
        self.arg_count += 1
        return val
コード例 #25
0
ファイル: builtins.py プロジェクト: apsaltis/numba
def getiter_range_generic(context, builder, iterobj, start, stop, step):
    diff = builder.sub(stop, start)
    intty = start.type
    zero = Constant.int(intty, 0)
    one = Constant.int(intty, 1)
    pos_diff = builder.icmp(lc.ICMP_SGT, diff, zero)
    pos_step = builder.icmp(lc.ICMP_SGT, step, zero)
    sign_differs = builder.xor(pos_diff, pos_step)
    zero_step = builder.icmp(lc.ICMP_EQ, step, zero)

    with cgutils.if_unlikely(builder, zero_step):
        # step shouldn't be zero
        context.return_errcode(builder, 1)

    with cgutils.ifelse(builder, sign_differs) as (then, orelse):
        with then:
            builder.store(zero, iterobj.count)

        with orelse:
            rem = builder.srem(diff, step)
            uneven = builder.icmp(lc.ICMP_SGT, rem, zero)
            newcount = builder.add(builder.sdiv(diff, step),
                                   builder.select(uneven, one, zero))
            builder.store(newcount, iterobj.count)

    return iterobj._getvalue()
コード例 #26
0
ファイル: randomimpl.py プロジェクト: PierreBizouard/numba
def get_next_int32(context, builder, state_ptr):
    """
    Get the next int32 generated by the PRNG at *state_ptr*.
    """
    idxptr = get_index_ptr(builder, state_ptr)
    idx = builder.load(idxptr)
    need_reshuffle = builder.icmp_unsigned('>=', idx, N_const)
    with cgutils.if_unlikely(builder, need_reshuffle):
        fnty = ir.FunctionType(ir.VoidType(), (rnd_state_ptr_t,))
        fn = builder.function.module.get_or_insert_function(fnty, "numba_rnd_shuffle")
        builder.call(fn, (state_ptr,))
        builder.store(const_int(0), idxptr)
    idx = builder.load(idxptr)
    array_ptr = get_array_ptr(builder, state_ptr)
    y = builder.load(cgutils.gep(builder, array_ptr, 0, idx))
    idx = builder.add(idx, const_int(1))
    builder.store(idx, idxptr)
    # Tempering
    y = builder.xor(y, builder.lshr(y, const_int(11)))
    y = builder.xor(y, builder.and_(builder.shl(y, const_int(7)),
                                    const_int(0x9d2c5680)))
    y = builder.xor(y, builder.and_(builder.shl(y, const_int(15)),
                                    const_int(0xefc60000)))
    y = builder.xor(y, builder.lshr(y, const_int(18)))
    return y
コード例 #27
0
ファイル: pythonapi.py プロジェクト: johandroid/numba
    def to_native_arg(self, obj, typ):
        if isinstance(typ, types.Record):
            # Generate a dummy integer type that has the size of Py_buffer
            dummy_py_buffer_type = Type.int(_helperlib.py_buffer_size * 8)
            # Allocate the Py_buffer
            py_buffer = cgutils.alloca_once(self.builder, dummy_py_buffer_type)

            # Zero-fill the py_buffer. where the obj field in Py_buffer is NULL
            # PyBuffer_Release has no effect.
            zeroed_buffer = lc.Constant.null(dummy_py_buffer_type)
            self.builder.store(zeroed_buffer, py_buffer)

            buf_as_voidptr = self.builder.bitcast(py_buffer, self.voidptr)
            ptr = self.extract_record_data(obj, buf_as_voidptr)

            with cgutils.if_unlikely(self.builder,
                                     cgutils.is_null(self.builder, ptr)):
                self.builder.ret(ptr)

            ltyp = self.context.get_value_type(typ)
            val = cgutils.init_record_by_ptr(self.builder, ltyp, ptr)

            def dtor():
                self.release_record_buffer(buf_as_voidptr)

        else:
            val = self.to_native_value(obj, typ)

            def dtor():
                pass

        return val, dtor
コード例 #28
0
ファイル: builtins.py プロジェクト: aburan28/numba
def getitem_array1d(context, builder, sig, args):
    aryty, _ = sig.args
    if aryty.ndim != 1:
        # TODO
        raise NotImplementedError("1D indexing into %dD array" % aryty.ndim)

    ary, idx = args

    arystty = make_array(aryty)
    ary = arystty(context, builder, ary)
    dataptr = ary.data

    if True or WARPAROUND:  # TODO target flag
        ZERO = context.get_constant(types.intp, 0)
        negative = builder.icmp(lc.ICMP_SLT, idx, ZERO)
        bbnormal = builder.basic_block
        with cgutils.if_unlikely(builder, negative):
            # Index is negative, wraparound
            [nelem] = cgutils.unpack_tuple(builder, ary.shape, 1)
            wrapped = builder.add(nelem, idx)
            bbwrapped = builder.basic_block

        where = builder.phi(idx.type)
        where.add_incoming(idx, bbnormal)
        where.add_incoming(wrapped, bbwrapped)

        ptr = builder.gep(dataptr, [where])
    else:
        # No wraparound
        ptr = builder.gep(dataptr, [idx])

    if context.is_struct_type(aryty.dtype):
        return ptr
    else:
        return builder.load(ptr)
コード例 #29
0
        def iternext_specific(self, context, builder, result):
            zero = context.get_constant(types.intp, 0)
            one = context.get_constant(types.intp, 1)

            bbend = cgutils.append_basic_block(builder, 'end')

            exhausted = cgutils.as_bool_bit(builder,
                                            builder.load(self.exhausted))
            with cgutils.if_unlikely(builder, exhausted):
                result.set_valid(False)
                builder.branch(bbend)

            indices = [
                builder.load(cgutils.gep(builder, self.indices, dim))
                for dim in range(ndim)
            ]
            result.yield_(cgutils.pack_array(builder, indices))
            result.set_valid(True)

            shape = cgutils.unpack_tuple(builder, self.shape, ndim)
            _increment_indices(context, builder, ndim, shape, self.indices,
                               self.exhausted)

            builder.branch(bbend)
            builder.position_at_end(bbend)
コード例 #30
0
 def check_int_status(self, num, ok_value=0):
     """
     Raise an exception if *num* is smaller than *ok_value*.
     """
     ok = lc.Constant.int(num.type, ok_value)
     pred = self.builder.icmp(lc.ICMP_SLT, num, ok)
     with cgutils.if_unlikely(self.builder, pred):
         self.return_exception_raised()
コード例 #31
0
ファイル: lowering.py プロジェクト: B-Rich/numba
    def set_iter_valid(self, state, item):
        iterstate = PyIterState(self.context, self.builder, ref=state)
        iterstate.valid = cgutils.as_bool_byte(self.builder,
                                               cgutils.is_not_null(self.builder,
                                                                   item))

        with cgutils.if_unlikely(self.builder, self.is_null(item)):
            self.check_occurred()
コード例 #32
0
def iternext_zip(context, builder, sig, args, result):
    genty, = sig.args
    gen, = args
    # XXX We should link with the generator's library.
    # Currently, this doesn't make a difference as the library has already
    # been linked for the generator init function.
    impl = context.get_generator_impl(genty)
    status, retval = impl(context, builder, sig, args)
    with cgutils.if_likely(builder, status.is_ok):
        result.set_valid(True)
        result.yield_(retval)
    with cgutils.if_unlikely(builder, status.is_stop_iteration):
        result.set_exhausted()
    with cgutils.if_unlikely(builder,
                             builder.and_(status.is_error,
                                          builder.not_(status.is_stop_iteration))):
        context.call_conv.return_status_propagate(builder, status)
コード例 #33
0
 def check_int_status(self, num, ok_value=0):
     """
     Raise an exception if *num* is smaller than *ok_value*.
     """
     ok = lc.Constant.int(num.type, ok_value)
     pred = self.builder.icmp(lc.ICMP_SLT, num, ok)
     with cgutils.if_unlikely(self.builder, pred):
         self.return_exception_raised()
コード例 #34
0
ファイル: randomimpl.py プロジェクト: PierreBizouard/numba
def getrandbits_impl(context, builder, sig, args):
    nbits, = args
    too_large = builder.icmp_unsigned(">=", nbits, const_int(65))
    too_small = builder.icmp_unsigned("==", nbits, const_int(0))
    with cgutils.if_unlikely(builder, builder.or_(too_large, too_small)):
        msg = "getrandbits() limited to 64 bits"
        context.call_conv.return_user_exc(builder, OverflowError, (msg,))
    state_ptr = get_state_ptr(context, builder, "py")
    return get_next_int(context, builder, state_ptr, nbits)
コード例 #35
0
ファイル: randomimpl.py プロジェクト: smtlify/numba
def getrandbits_impl(context, builder, sig, args):
    nbits, = args
    too_large = builder.icmp_unsigned(">=", nbits, const_int(65))
    too_small = builder.icmp_unsigned("==", nbits, const_int(0))
    with cgutils.if_unlikely(builder, builder.or_(too_large, too_small)):
        msg = "getrandbits() limited to 64 bits"
        context.call_conv.return_user_exc(builder, OverflowError, (msg,))
    state_ptr = get_state_ptr(context, builder, "py")
    return get_next_int(context, builder, state_ptr, nbits)
コード例 #36
0
def iternext_numpy_flatiter(context, builder, sig, args, result):
    [flatiterty] = sig.args
    [flatiter] = args

    flatitercls = make_array_flat_cls(flatiterty)
    flatiter = flatitercls(context, builder, value=flatiter)

    arrty = flatiterty.array_type
    arrcls = context.make_array(arrty)
    arr = arrcls(context, builder, value=builder.load(flatiter.array))

    ndim = arrty.ndim
    shapes = cgutils.unpack_tuple(builder, arr.shape, ndim)
    indptr = flatiter.iters

    # Load indices and check if they are valid
    indices = []
    is_valid = cgutils.true_bit
    zero = context.get_constant(types.intp, 0)
    one = context.get_constant(types.intp, 1)
    for ax in range(ndim):
        axsize = shapes[ax]
        idxptr = builder.gep(indptr, [context.get_constant(types.intp, ax)])
        idx = builder.load(idxptr)
        ax_valid = builder.icmp(lc.ICMP_SLT, idx, axsize)

        indices.append(idx)
        is_valid = builder.and_(is_valid, ax_valid)

    result.set_valid(is_valid)

    with cgutils.if_likely(builder, is_valid):
        # Get yielded value
        valptr = cgutils.get_item_pointer(builder, arrty, arr, indices)
        yield_value = builder.load(valptr)
        result.yield_(yield_value)

        # Increment iterator indices
        carry_flags = [cgutils.true_bit]
        for ax, (idx, axsize) in reversed(list(enumerate(zip(indices,
                                                             shapes)))):
            idxptr = builder.gep(indptr,
                                 [context.get_constant(types.intp, ax)])
            lastcarry = carry_flags[-1]
            idxp1 = builder.add(idx, one)
            carry = builder.icmp(lc.ICMP_SGE, idxp1, axsize)
            idxfinal = builder.select(lastcarry,
                                      builder.select(carry, zero, idxp1), idx)
            builder.store(idxfinal, idxptr)
            carry_flags.append(builder.and_(carry, lastcarry))

        with cgutils.if_unlikely(builder, carry_flags[-1]):
            # If we have iterated all elements,
            # Set first index to out-of-bound
            idxptr = builder.gep(indptr, [context.get_constant(types.intp, 0)])
            builder.store(shapes[0], idxptr)
コード例 #37
0
ファイル: arrayobj.py プロジェクト: genba/numba
def iternext_numpy_flatiter(context, builder, sig, args, result):
    [flatiterty] = sig.args
    [flatiter] = args

    flatitercls = make_array_flat_cls(flatiterty)
    flatiter = flatitercls(context, builder, value=flatiter)

    arrty = flatiterty.array_type
    arrcls = context.make_array(arrty)
    arr = arrcls(context, builder, value=builder.load(flatiter.array))

    ndim = arrty.ndim
    shapes = cgutils.unpack_tuple(builder, arr.shape, ndim)
    indptr = flatiter.iters

    # Load indices and check if they are valid
    indices = []
    is_valid = cgutils.true_bit
    zero = context.get_constant(types.intp, 0)
    one = context.get_constant(types.intp, 1)
    for ax in range(ndim):
        axsize = shapes[ax]
        idxptr = builder.gep(indptr, [context.get_constant(types.intp, ax)])
        idx = builder.load(idxptr)
        ax_valid = builder.icmp(lc.ICMP_SLT, idx, axsize)

        indices.append(idx)
        is_valid = builder.and_(is_valid, ax_valid)

    result.set_valid(is_valid)

    with cgutils.if_likely(builder, is_valid):
        # Get yielded value
        valptr = cgutils.get_item_pointer(builder, arrty, arr, indices)
        yield_value = builder.load(valptr)
        result.yield_(yield_value)

        # Increment iterator indices
        carry_flags = [cgutils.true_bit]
        for ax, (idx, axsize) in reversed(list(enumerate(zip(indices,
                                                             shapes)))):
            idxptr = builder.gep(indptr, [context.get_constant(types.intp, ax)])
            lastcarry = carry_flags[-1]
            idxp1 = builder.add(idx, one)
            carry = builder.icmp(lc.ICMP_SGE, idxp1, axsize)
            idxfinal = builder.select(lastcarry,
                                      builder.select(carry, zero, idxp1),
                                      idx)
            builder.store(idxfinal, idxptr)
            carry_flags.append(builder.and_(carry, lastcarry))

        with cgutils.if_unlikely(builder, carry_flags[-1]):
            # If we have iterated all elements,
            # Set first index to out-of-bound
            idxptr = builder.gep(indptr, [context.get_constant(types.intp, 0)])
            builder.store(shapes[0], idxptr)
コード例 #38
0
ファイル: callwrapper.py プロジェクト: sklam/numba
    def build_wrapper(self, api, builder, closure, args, kws):
        nargs = len(self.fndesc.argtypes)

        objs = [api.alloca_obj() for _ in range(nargs)]
        parseok = api.unpack_tuple(args, self.fndesc.qualname,
                                   nargs, nargs, *objs)

        pred = builder.icmp(lc.ICMP_EQ, parseok, Constant.null(parseok.type))
        with cgutils.if_unlikely(builder, pred):
            builder.ret(api.get_null_object())

        # Block that returns after erroneous argument unboxing/cleanup
        endblk = builder.append_basic_block("arg.end")
        with builder.goto_block(endblk):
            builder.ret(api.get_null_object())

        # Extract the Environment object from the Closure
        envptr, env_manager = self.get_env(api, builder, closure)

        cleanup_manager = _ArgManager(self.context, builder, api,
                                      env_manager, endblk, nargs)

        # Compute the arguments to the compiled Numba function.
        innerargs = []
        for obj, ty in zip(objs, self.fndesc.argtypes):
            if isinstance(ty, types.Omitted):
                # It's an omitted value => ignore dummy Python object
                innerargs.append(None)
            else:
                val = cleanup_manager.add_arg(builder.load(obj), ty)
                innerargs.append(val)

        if self.release_gil:
            cleanup_manager = _GilManager(builder, api, cleanup_manager)

        status, retval = self.context.call_conv.call_function(
            builder, self.func, self.fndesc.restype, self.fndesc.argtypes,
            innerargs, env=envptr)
        # Do clean up
        self.debug_print(builder, "# callwrapper: emit_cleanup")
        cleanup_manager.emit_cleanup()
        self.debug_print(builder, "# callwrapper: emit_cleanup end")

        # Determine return status
        with builder.if_then(status.is_ok, likely=True):
            # Ok => return boxed Python value
            with builder.if_then(status.is_none):
                api.return_none()

            retty = self._simplified_return_type()
            obj = api.from_native_return(retty, retval, env_manager)
            builder.ret(obj)

        # Error out
        self.context.call_conv.raise_error(builder, api, status)
        builder.ret(api.get_null_object())
コード例 #39
0
 def pre_lower(self):
     # Store environment argument for later use
     self.envarg = self.context.get_env_argument(self.function)
     with cgutils.if_unlikely(self.builder, self.is_null(self.envarg)):
         self.pyapi.err_set_string(
             "PyExc_SystemError",
             "Numba internal error: object mode function called "
             "without an environment")
         self.return_exception_raised()
     self.env_body = self.context.get_env_body(self.builder, self.envarg)
コード例 #40
0
 def pre_lower(self):
     # Store environment argument for later use
     self.envarg = self.context.get_env_argument(self.function)
     with cgutils.if_unlikely(self.builder, self.is_null(self.envarg)):
         self.pyapi.err_set_string(
             "PyExc_SystemError",
             "Numba internal error: object mode function called "
             "without an environment")
         self.return_exception_raised()
     self.env_body = self.context.get_env_body(self.builder, self.envarg)
コード例 #41
0
 def loadvar(self, name):
     """
     Load the llvm value of the variable named *name*.
     """
     ptr = self.varmap[name]
     val = self.builder.load(ptr)
     with cgutils.if_unlikely(self.builder, self.is_null(val)):
         self.pyapi.raise_missing_name_error(name)
         self.return_error_occurred()
     return val
コード例 #42
0
 def loadvar(self, name):
     """
     Load the llvm value of the variable named *name*.
     """
     ptr = self.varmap[name]
     val = self.builder.load(ptr)
     with cgutils.if_unlikely(self.builder, self.is_null(val)):
         self.pyapi.raise_missing_name_error(name)
         self.return_error_occurred()
     return val
コード例 #43
0
ファイル: callwrapper.py プロジェクト: walterwsmf/numba
    def build_wrapper(self, api, builder, closure, args, kws):
        nargs = len(self.fndesc.args)

        objs = [api.alloca_obj() for _ in range(nargs)]
        parseok = api.unpack_tuple(args, self.fndesc.qualname, nargs, nargs,
                                   *objs)

        pred = builder.icmp(lc.ICMP_EQ, parseok, Constant.null(parseok.type))
        with cgutils.if_unlikely(builder, pred):
            builder.ret(api.get_null_object())

        # Block that returns after erroneous argument unboxing/cleanup
        endblk = builder.append_basic_block("arg.end")
        with builder.goto_block(endblk):
            builder.ret(api.get_null_object())

        cleanup_manager = _ArgManager(self.context, builder, api, endblk,
                                      nargs)

        innerargs = []
        for obj, ty in zip(objs, self.fndesc.argtypes):
            val = cleanup_manager.add_arg(obj, ty)
            innerargs.append(val)

        if self.release_gil:
            cleanup_manager = _GilManager(builder, api, cleanup_manager)

        # Extract the Environment object from the Closure
        envptr, env_manager = self.get_env(api, builder, closure)

        status, res = self.context.call_conv.call_function(
            builder, self.func, self.fndesc.restype, self.fndesc.argtypes,
            innerargs, envptr)
        # Do clean up
        self.debug_print(builder, "# callwrapper: emit_cleanup")
        cleanup_manager.emit_cleanup()
        self.debug_print(builder, "# callwrapper: emit_cleanup end")

        # Determine return status
        with cgutils.if_likely(builder, status.is_ok):
            # Ok => return boxed Python value
            with builder.if_then(status.is_none):
                api.return_none()

            retval = api.from_native_return(res,
                                            self._simplified_return_type(),
                                            env_manager)
            builder.ret(retval)

        with builder.if_then(builder.not_(status.is_python_exc)):
            # User exception raised
            self.make_exception_switch(api, builder, status)

        # Error out
        builder.ret(api.get_null_object())
コード例 #44
0
ファイル: callwrapper.py プロジェクト: liyangdal/numba
    def build_wrapper(self, api, builder, closure, args, kws):
        nargs = len(self.fndesc.args)
        keywords = self.make_keywords(self.fndesc.args)
        fmt = self.make_const_string("O" * nargs)

        objs = [api.alloca_obj() for _ in range(nargs)]
        parseok = api.parse_tuple_and_keywords(args, kws, fmt, keywords, *objs)

        pred = builder.icmp(lc.ICMP_EQ, parseok, Constant.null(parseok.type))
        with cgutils.if_unlikely(builder, pred):
            builder.ret(api.get_null_object())

        # Block that returns after erroneous argument unboxing/cleanup
        endblk = cgutils.append_basic_block(builder, "arg.end")
        with cgutils.goto_block(builder, endblk):
            builder.ret(api.get_null_object())

        cleanup_manager = _ArgManager(builder, api, endblk, nargs)

        innerargs = []
        for obj, ty in zip(objs, self.fndesc.argtypes):
            val = cleanup_manager.add_arg(obj, ty)
            innerargs.append(val)

        if self.release_gil:
            cleanup_manager = _GilManager(builder, api, cleanup_manager)

        # The wrapped function doesn't take a full closure, only
        # the Environment object.
        env = self.context.get_env_from_closure(builder, closure)

        status, res = self.context.call_function(builder, self.func,
                                                 self.fndesc.restype,
                                                 self.fndesc.argtypes,
                                                 innerargs, env)
        # Do clean up
        cleanup_manager.emit_cleanup()

        # Determine return status
        with cgutils.if_likely(builder, status.ok):
            with cgutils.ifthen(builder, status.none):
                api.return_none()

            retval = api.from_native_return(res, self.fndesc.restype)
            builder.ret(retval)

        with cgutils.ifthen(builder, builder.not_(status.exc)):
            # !ok && !exc
            # User exception raised
            self.make_exception_switch(api, builder, status.code)

        # !ok && exc
        builder.ret(api.get_null_object())
コード例 #45
0
ファイル: atomicops.py プロジェクト: cequencer/numba
def _define_nrt_incref(module, atomic_incr):
    """
    Implement NRT_incref in the module
    """
    fn_incref = module.get_or_insert_function(incref_decref_ty, name="NRT_incref")
    builder = ir.IRBuilder(fn_incref.append_basic_block())
    [ptr] = fn_incref.args
    is_null = builder.icmp_unsigned("==", ptr, cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()
    builder.call(atomic_incr, [builder.bitcast(ptr, atomic_incr.args[0].type)])
    builder.ret_void()
コード例 #46
0
ファイル: base.py プロジェクト: maartenscholl/numba
    def call_internal(self, builder, fndesc, sig, args):
        """Given the function descriptor of an internally compiled function,
        emit a call to that function with the given arguments.
        """
        # Add call to the generated function
        llvm_mod = builder.module
        fn = self.declare_function(llvm_mod, fndesc)
        status, res = self.call_conv.call_function(builder, fn, sig.return_type, sig.args, args)

        with cgutils.if_unlikely(builder, status.is_error):
            self.call_conv.return_status_propagate(builder, status)
        return res
コード例 #47
0
    def build_wrapper(self, api, builder, closure, args, kws):
        nargs = len(self.fndesc.args)
        keywords = self.make_keywords(self.fndesc.args)
        fmt = self.make_const_string("O" * nargs)

        objs = [api.alloca_obj() for _ in range(nargs)]
        parseok = api.parse_tuple_and_keywords(args, kws, fmt, keywords, *objs)

        pred = builder.icmp(lc.ICMP_EQ, parseok, Constant.null(parseok.type))
        with cgutils.if_unlikely(builder, pred):
            builder.ret(api.get_null_object())

        # Block that returns after erroneous argument unboxing/cleanup
        endblk = cgutils.append_basic_block(builder, "arg.end")
        with cgutils.goto_block(builder, endblk):
            builder.ret(api.get_null_object())

        cleanup_manager = _ArgManager(builder, api, endblk, nargs)

        innerargs = []
        for obj, ty in zip(objs, self.fndesc.argtypes):
            val = cleanup_manager.add_arg(obj, ty)
            innerargs.append(val)

        if self.release_gil:
            cleanup_manager = _GilManager(builder, api, cleanup_manager)

        # The wrapped function doesn't take a full closure, only
        # the Environment object.
        env = self.context.get_env_from_closure(builder, closure)

        status, res = self.context.call_function(builder, self.func,
                                                 self.fndesc.restype,
                                                 self.fndesc.argtypes,
                                                 innerargs, env)
        # Do clean up
        cleanup_manager.emit_cleanup()

        # Determine return status
        with cgutils.if_likely(builder, status.ok):
            with cgutils.ifthen(builder, status.none):
                api.return_none()

            retval = api.from_native_return(res, self.fndesc.restype)
            builder.ret(retval)

        with cgutils.ifthen(builder, builder.not_(status.exc)):
            # !ok && !exc
            # User exception raised
            self.make_exception_switch(api, builder, status.code)

        # !ok && exc
        builder.ret(api.get_null_object())
コード例 #48
0
ファイル: callwrapper.py プロジェクト: GaZ3ll3/numba
    def build_wrapper(self, api, builder, closure, args, kws):
        nargs = len(self.fndesc.args)

        objs = [api.alloca_obj() for _ in range(nargs)]
        parseok = api.unpack_tuple(args, self.fndesc.qualname, nargs, nargs, *objs)

        pred = builder.icmp(lc.ICMP_EQ, parseok, Constant.null(parseok.type))
        with cgutils.if_unlikely(builder, pred):
            builder.ret(api.get_null_object())

        # Block that returns after erroneous argument unboxing/cleanup
        endblk = builder.append_basic_block("arg.end")
        with builder.goto_block(endblk):
            builder.ret(api.get_null_object())

        cleanup_manager = _ArgManager(self.context, builder, api, endblk, nargs)

        innerargs = []
        for obj, ty in zip(objs, self.fndesc.argtypes):
            val = cleanup_manager.add_arg(obj, ty)
            innerargs.append(val)

        if self.release_gil:
            cleanup_manager = _GilManager(builder, api, cleanup_manager)

        # Extract the Environment object from the Closure
        envptr, env_manager = self.get_env(api, builder, closure)

        status, retval = self.context.call_conv.call_function(
            builder, self.func, self.fndesc.restype, self.fndesc.argtypes,
            innerargs, envptr)
        # Do clean up
        self.debug_print(builder, "# callwrapper: emit_cleanup")
        cleanup_manager.emit_cleanup()
        self.debug_print(builder, "# callwrapper: emit_cleanup end")

        # Determine return status
        with cgutils.if_likely(builder, status.is_ok):
            # Ok => return boxed Python value
            with builder.if_then(status.is_none):
                api.return_none()

            retty = self._simplified_return_type()
            obj = api.from_native_return(retval, retty, env_manager)
            builder.ret(obj)

        with builder.if_then(builder.not_(status.is_python_exc)):
            # User exception raised
            self.make_exception_switch(api, builder, status)

        # Error out
        builder.ret(api.get_null_object())
コード例 #49
0
def unbox_COO(typ: COOType, obj: COO, c) -> NativeValue:
    ret_ptr = cgutils.alloca_once(c.builder, c.context.get_value_type(typ))
    is_error_ptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
    fail_obj = c.context.get_constant_null(typ)

    with local_return(c.builder) as ret:
        fail_blk = c.builder.append_basic_block("fail")
        with c.builder.goto_block(fail_blk):
            c.builder.store(cgutils.true_bit, is_error_ptr)
            c.builder.store(fail_obj, ret_ptr)
            ret()

        data = _unbox_native_field(typ.data_type, obj, "data", c)
        with cgutils.if_unlikely(c.builder, data.is_error):
            c.builder.branch(fail_blk)

        coords = _unbox_native_field(typ.coords_type, obj, "coords", c)
        with cgutils.if_unlikely(c.builder, coords.is_error):
            c.builder.branch(fail_blk)

        shape = _unbox_native_field(typ.shape_type, obj, "shape", c)
        with cgutils.if_unlikely(c.builder, shape.is_error):
            c.builder.branch(fail_blk)

        fill_value = _unbox_native_field(typ.fill_value_type, obj,
                                         "fill_value", c)
        with cgutils.if_unlikely(c.builder, fill_value.is_error):
            c.builder.branch(fail_blk)

        coo = cgutils.create_struct_proxy(typ)(c.context, c.builder)
        coo.coords = coords.value
        coo.data = data.value
        coo.shape = shape.value
        coo.fill_value = fill_value.value
        c.builder.store(cgutils.false_bit, is_error_ptr)
        c.builder.store(coo._getvalue(), ret_ptr)

    return NativeValue(c.builder.load(ret_ptr),
                       is_error=c.builder.load(is_error_ptr))
コード例 #50
0
ファイル: cpu.py プロジェクト: digideskio/numba
    def get_env_from_closure(self, builder, clo):
        """
        From the pointer *clo* to a _dynfunc.Closure, get a pointer
        to the enclosed _dynfunc.Environment.
        """
        with cgutils.if_unlikely(builder, cgutils.is_null(builder, clo)):
            self.debug_print(builder, "Fatal error: missing _dynfunc.Closure")
            builder.unreachable()

        clo_body_ptr = cgutils.pointer_add(
            builder, clo, _dynfunc._impl_info['offsetof_closure_body'])
        clo_body = ClosureBody(self, builder, ref=clo_body_ptr, cast_ref=True)
        return clo_body.env
コード例 #51
0
    def get_env_from_closure(self, builder, clo):
        """
        From the pointer *clo* to a _dynfunc.Closure, get a pointer
        to the enclosed _dynfunc.Environment.
        """
        with cgutils.if_unlikely(builder, cgutils.is_null(builder, clo)):
            self.debug_print(builder, "Fatal error: missing _dynfunc.Closure")
            builder.unreachable()

        clo_body_ptr = cgutils.pointer_add(
            builder, clo, _dynfunc._impl_info['offsetof_closure_body'])
        clo_body = ClosureBody(self, builder, ref=clo_body_ptr, cast_ref=True)
        return clo_body.env
コード例 #52
0
def _define_nrt_decref(module, atomic_decr):
    """
    Implement NRT_decref in the module
    """
    fn_decref = module.get_or_insert_function(incref_decref_ty,
                                              name="NRT_decref")
    # Cannot inline this for refcount pruning to work
    fn_decref.attributes.add('noinline')
    calldtor = module.add_function(ir.FunctionType(ir.VoidType(),
                                                   [_pointer_type]),
                                   name="NRT_MemInfo_call_dtor")

    builder = ir.IRBuilder(fn_decref.append_basic_block())
    [ptr] = fn_decref.args
    is_null = builder.icmp_unsigned("==", ptr,
                                    cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()

    if _debug_print:
        cgutils.printf(builder, "*** NRT_Decref %zu [%p]\n", builder.load(ptr),
                       ptr)

    # For memory fence usage, see https://llvm.org/docs/Atomics.html

    # A release fence is used before the relevant write operation.
    # No-op on x86.  On POWER, it lowers to lwsync.
    builder.fence("release")
    newrefct = builder.call(atomic_decr,
                            [builder.bitcast(ptr, atomic_decr.args[0].type)])

    refct_eq_0 = builder.icmp_unsigned("==", newrefct,
                                       ir.Constant(newrefct.type, 0))
    with cgutils.if_unlikely(builder, refct_eq_0):
        # An acquire fence is used after the relevant read operation.
        # No-op on x86.  On POWER, it lowers to lwsync.
        builder.fence("acquire")
        builder.call(calldtor, [ptr])
    builder.ret_void()
コード例 #53
0
ファイル: base.py プロジェクト: xuyaocareer/numba
    def call_internal(self, builder, fndesc, sig, args):
        """Given the function descriptor of an internally compiled function,
        emit a call to that function with the given arguments.
        """
        # Add call to the generated function
        llvm_mod = builder.module
        fn = self.declare_function(llvm_mod, fndesc)
        status, res = self.call_conv.call_function(builder, fn, sig.return_type,
                                                   sig.args, args)

        with cgutils.if_unlikely(builder, status.is_error):
            self.call_conv.return_status_propagate(builder, status)
        return res
コード例 #54
0
ファイル: atomicops.py プロジェクト: cequencer/numba
def _define_nrt_incref(module, atomic_incr):
    """
    Implement NRT_incref in the module
    """
    fn_incref = module.get_or_insert_function(incref_decref_ty,
                                              name="NRT_incref")
    builder = ir.IRBuilder(fn_incref.append_basic_block())
    [ptr] = fn_incref.args
    is_null = builder.icmp_unsigned("==", ptr,
                                    cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()
    builder.call(atomic_incr, [builder.bitcast(ptr, atomic_incr.args[0].type)])
    builder.ret_void()
コード例 #55
0
 def emit_environment_sentry(self, envptr, return_pyobject=False):
     """Emits LLVM code to ensure the `envptr` is not NULL
     """
     is_null = cgutils.is_null(self.builder, envptr)
     with cgutils.if_unlikely(self.builder, is_null):
         if return_pyobject:
             fnty = self.builder.function.type.pointee
             assert fnty.return_type == self.pyobj
             self.err_set_string("PyExc_RuntimeError",
                                 "missing Environment")
             self.builder.ret(self.get_null_object())
         else:
             self.context.call_conv.return_user_exc(
                 self.builder, RuntimeError, ("missing Environment", ))
コード例 #56
0
ファイル: callwrapper.py プロジェクト: ASPP/numba
    def build_wrapper(self, api, builder, closure, args, kws):
        nargs = len(self.fndesc.args)
        keywords = self.make_keywords(self.fndesc.args)
        fmt = self.make_const_string("O" * nargs)

        objs = [api.alloca_obj() for _ in range(nargs)]
        parseok = api.parse_tuple_and_keywords(args, kws, fmt, keywords, *objs)

        pred = builder.icmp(lc.ICMP_EQ, parseok, Constant.null(parseok.type))
        with cgutils.if_unlikely(builder, pred):
            builder.ret(api.get_null_object())

        innerargs = []
        cleanups = []
        for obj, ty in zip(objs, self.fndesc.argtypes):
            #api.context.debug_print(builder, "%s -> %s" % (obj, ty))
            #api.print_object(builder.load(obj))
            val, dtor = api.to_native_arg(builder.load(obj), ty)
            innerargs.append(val)
            cleanups.append(dtor)

        # The wrapped function doesn't take a full closure, only
        # the Environment object.
        env = self.context.get_env_from_closure(builder, closure)

        status, res = self.context.call_function(builder, self.func,
                                                 self.fndesc.restype,
                                                 self.fndesc.argtypes,
                                                 innerargs, env)

        # Do clean up
        for dtor in cleanups:
            dtor()

        # Determine return status

        with cgutils.if_likely(builder, status.ok):
            with cgutils.ifthen(builder, status.none):
                api.return_none()

            retval = api.from_native_return(res, self.fndesc.restype)
            builder.ret(retval)

        with cgutils.ifthen(builder, builder.not_(status.exc)):
            # !ok && !exc
            # User exception raised
            self.make_exception_switch(api, builder, status.code)

        # !ok && exc
        builder.ret(api.get_null_object())
コード例 #57
0
ファイル: nrtdynmod.py プロジェクト: cpcloud/numba
def _define_nrt_decref(module, atomic_decr):
    """
    Implement NRT_decref in the module
    """
    fn_decref = module.get_or_insert_function(incref_decref_ty,
                                              name="NRT_decref")
    # Cannot inline this for refcount pruning to work
    fn_decref.attributes.add('noinline')
    calldtor = module.add_function(ir.FunctionType(ir.VoidType(), [_pointer_type]),
                                   name="NRT_MemInfo_call_dtor")

    builder = ir.IRBuilder(fn_decref.append_basic_block())
    [ptr] = fn_decref.args
    is_null = builder.icmp_unsigned("==", ptr, cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()

    if _debug_print:
        cgutils.printf(builder, "*** NRT_Decref %zu [%p]\n", builder.load(ptr),
                       ptr)

    # For memory fence usage, see https://llvm.org/docs/Atomics.html

    # A release fence is used before the relevant write operation.
    # No-op on x86.  On POWER, it lowers to lwsync.
    builder.fence("release")
    newrefct = builder.call(atomic_decr,
                            [builder.bitcast(ptr, atomic_decr.args[0].type)])

    refct_eq_0 = builder.icmp_unsigned("==", newrefct,
                                       ir.Constant(newrefct.type, 0))
    with cgutils.if_unlikely(builder, refct_eq_0):
        # An acquire fence is used after the relevant read operation.
        # No-op on x86.  On POWER, it lowers to lwsync.
        builder.fence("acquire")
        builder.call(calldtor, [ptr])
    builder.ret_void()
コード例 #58
0
ファイル: atomicops.py プロジェクト: cequencer/numba
def _define_nrt_decref(module, atomic_decr):
    """
    Implement NRT_decref in the module
    """
    fn_decref = module.get_or_insert_function(incref_decref_ty,
                                              name="NRT_decref")
    calldtor = module.add_function(ir.FunctionType(ir.VoidType(),
                                                   [_pointer_type]),
                                   name="NRT_MemInfo_call_dtor")

    builder = ir.IRBuilder(fn_decref.append_basic_block())
    [ptr] = fn_decref.args
    is_null = builder.icmp_unsigned("==", ptr,
                                    cgutils.get_null_value(ptr.type))
    with cgutils.if_unlikely(builder, is_null):
        builder.ret_void()
    newrefct = builder.call(atomic_decr,
                            [builder.bitcast(ptr, atomic_decr.args[0].type)])

    refct_eq_0 = builder.icmp_unsigned("==", newrefct,
                                       ir.Constant(newrefct.type, 0))
    with cgutils.if_unlikely(builder, refct_eq_0):
        builder.call(calldtor, [ptr])
    builder.ret_void()
コード例 #59
0
ファイル: pythonapi.py プロジェクト: shaweiguo/numba
 def emit_environment_sentry(self, envptr, return_pyobject=False):
     """Emits LLVM code to ensure the `envptr` is not NULL
     """
     is_null = cgutils.is_null(self.builder, envptr)
     with cgutils.if_unlikely(self.builder, is_null):
         if return_pyobject:
             fnty = self.builder.function.type.pointee
             assert fnty.return_type == self.pyobj
             self.err_set_string("PyExc_RuntimeError",
                                 "missing Environment")
             self.builder.ret(self.get_null_object())
         else:
             self.context.call_conv.return_user_exc(self.builder,
                                                    RuntimeError,
                                                    ("missing Environment",))
コード例 #60
0
ファイル: pythonapi.py プロジェクト: johandroid/numba
 def to_native_array(self, typ, ary):
     # TODO check matching dtype.
     #      currently, mismatching dtype will still work and causes
     #      potential memory corruption
     voidptr = Type.pointer(Type.int(8))
     nativearycls = self.context.make_array(typ)
     nativeary = nativearycls(self.context, self.builder)
     aryptr = nativeary._getpointer()
     ptr = self.builder.bitcast(aryptr, voidptr)
     errcode = self.numba_array_adaptor(ary, ptr)
     failed = cgutils.is_not_null(self.builder, errcode)
     with cgutils.if_unlikely(self.builder, failed):
         # TODO
         self.builder.unreachable()
     return self.builder.load(aryptr)