示例#1
0
def box_list(typ, val, c):
    """
    Convert native list *val* to a list object.
    """
    list = listobj.ListInstance(c.context, c.builder, typ, val)
    obj = list.parent
    res = cgutils.alloca_once_value(c.builder, obj)
    with c.builder.if_else(cgutils.is_not_null(c.builder, obj)) as (has_parent,
                                                                    otherwise):
        with has_parent:
            # List is actually reflected => return the original object
            # (note not all list instances whose *type* is reflected are
            #  actually reflected; see numba.tests.test_lists for an example)
            c.pyapi.incref(obj)

        with otherwise:
            # Build a new Python list
            nitems = list.size
            obj = c.pyapi.list_new(nitems)
            with c.builder.if_then(cgutils.is_not_null(c.builder, obj),
                                   likely=True):
                with cgutils.for_range(c.builder, nitems) as loop:
                    item = list.getitem(loop.index)
                    list.incref_value(item)
                    itemobj = c.box(typ.dtype, item)
                    c.pyapi.list_setitem(obj, loop.index, itemobj)

            c.builder.store(obj, res)

    # Steal NRT ref
    c.context.nrt.decref(c.builder, typ, val)
    return c.builder.load(res)
示例#2
0
def unbox_pandas_timestamp(typ, val, c):
    year_obj = c.pyapi.object_getattr_string(val, "year")
    month_obj = c.pyapi.object_getattr_string(val, "month")
    day_obj = c.pyapi.object_getattr_string(val, "day")
    hour_obj = c.pyapi.object_getattr_string(val, "hour")
    minute_obj = c.pyapi.object_getattr_string(val, "minute")
    second_obj = c.pyapi.object_getattr_string(val, "second")
    microsecond_obj = c.pyapi.object_getattr_string(val, "microsecond")
    nanosecond_obj = c.pyapi.object_getattr_string(val, "nanosecond")

    pd_timestamp = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    pd_timestamp.year = c.pyapi.long_as_longlong(year_obj)
    pd_timestamp.month = c.pyapi.long_as_longlong(month_obj)
    pd_timestamp.day = c.pyapi.long_as_longlong(day_obj)
    pd_timestamp.hour = c.pyapi.long_as_longlong(hour_obj)
    pd_timestamp.minute = c.pyapi.long_as_longlong(minute_obj)
    pd_timestamp.second = c.pyapi.long_as_longlong(second_obj)
    pd_timestamp.microsecond = c.pyapi.long_as_longlong(microsecond_obj)
    pd_timestamp.nanosecond = c.pyapi.long_as_longlong(nanosecond_obj)

    c.pyapi.decref(year_obj)
    c.pyapi.decref(month_obj)
    c.pyapi.decref(day_obj)
    c.pyapi.decref(hour_obj)
    c.pyapi.decref(minute_obj)
    c.pyapi.decref(second_obj)
    c.pyapi.decref(microsecond_obj)
    c.pyapi.decref(nanosecond_obj)

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(pd_timestamp._getvalue(), is_error=is_error)
示例#3
0
def print_item_impl(context, builder, sig, args):
    """
    Print a single native value by boxing it in a Python object and
    invoking the Python interpreter's print routine.
    """
    ty, = sig.args
    val, = args

    pyapi = context.get_python_api(builder)
    env_manager = context.get_env_manager(builder)

    if context.enable_nrt:
        context.nrt.incref(builder, ty, val)

    obj = pyapi.from_native_value(ty, val, env_manager)
    with builder.if_else(cgutils.is_not_null(builder, obj),
                         likely=True) as (if_ok, if_error):
        with if_ok:
            pyapi.print_object(obj)
            pyapi.decref(obj)
        with if_error:
            cstr = context.insert_const_string(builder.module,
                                               "the print() function")
            strobj = pyapi.string_from_string(cstr)
            pyapi.err_write_unraisable(strobj)
            pyapi.decref(strobj)

    res = context.get_dummy_value()
    return impl_ret_untracked(context, builder, sig.return_type, res)
示例#4
0
    def raise_error(self, builder, api, status):
        """
        Given a non-ok *status*, raise the corresponding Python exception.
        """
        bbend = builder.function.append_basic_block()

        with builder.if_then(status.is_user_exc):
            # Unserialize user exception.
            # Make sure another error may not interfere.
            api.err_clear()
            exc = api.unserialize(status.excinfoptr)
            with cgutils.if_likely(builder,
                                   cgutils.is_not_null(builder, exc)):
                api.raise_object(exc)  # steals ref
            builder.branch(bbend)

        with builder.if_then(status.is_stop_iteration):
            api.err_set_none("PyExc_StopIteration")
            builder.branch(bbend)

        with builder.if_then(status.is_python_exc):
            # Error already raised => nothing to do
            builder.branch(bbend)

        api.err_set_string("PyExc_SystemError",
                           "unknown error when calling native function")
        builder.branch(bbend)

        builder.position_at_end(bbend)
示例#5
0
def box_set(typ, val, c):
    """
    Convert native set *val* to a set object.
    """
    inst = setobj.SetInstance(c.context, c.builder, typ, val)
    obj = inst.parent
    res = cgutils.alloca_once_value(c.builder, obj)

    with c.builder.if_else(cgutils.is_not_null(c.builder, obj)) as (has_parent,
                                                                    otherwise):
        with has_parent:
            # Set is actually reflected => return the original object
            # (note not all set instances whose *type* is reflected are
            #  actually reflected; see numba.tests.test_sets for an example)
            c.pyapi.incref(obj)

        with otherwise:
            # Build a new Python list and then create a set from that
            payload = inst.payload
            ok, listobj = _native_set_to_python_list(typ, payload, c)
            with c.builder.if_then(ok, likely=True):
                obj = c.pyapi.set_new(listobj)
                c.pyapi.decref(listobj)
                c.builder.store(obj, res)

    # Steal NRT ref
    c.context.nrt.decref(c.builder, typ, val)
    return c.builder.load(res)
示例#6
0
def box_lsttype(typ, val, c):
    context = c.context
    builder = c.builder

    # XXX deduplicate
    ctor = cgutils.create_struct_proxy(typ)
    lstruct = ctor(context, builder, value=val)
    # Returns the plain MemInfo
    boxed_meminfo = c.box(
        types.MemInfoPointer(types.voidptr),
        lstruct.meminfo,
    )

    modname = c.context.insert_const_string(
        c.builder.module, 'numba.typed.typedlist',
    )
    typedlist_mod = c.pyapi.import_module_noblock(modname)
    fmp_fn = c.pyapi.object_getattr_string(typedlist_mod, '_from_meminfo_ptr')

    lsttype_obj = c.pyapi.unserialize(c.pyapi.serialize_object(typ))

    result_var = builder.alloca(c.pyapi.pyobj)
    builder.store(cgutils.get_null_value(c.pyapi.pyobj), result_var)

    with builder.if_then(cgutils.is_not_null(builder, lsttype_obj)):
        res = c.pyapi.call_function_objargs(
            fmp_fn, (boxed_meminfo, lsttype_obj),
        )
        c.pyapi.decref(fmp_fn)
        c.pyapi.decref(typedlist_mod)
        c.pyapi.decref(boxed_meminfo)
        builder.store(res, result_var)
    return builder.load(result_var)
示例#7
0
def unbox_range_index(typ, val, c):
    start_obj = c.pyapi.object_getattr_string(val, "start")
    stop_obj = c.pyapi.object_getattr_string(val, "stop")
    step_obj = c.pyapi.object_getattr_string(val, "step")

    # TODO: support range unboxing with reference to parent in Numba?
    range_index = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    range_index_data = cgutils.create_struct_proxy(RangeIndexDataType)(
        c.context, c.builder)
    range_index_data.start = c.pyapi.long_as_longlong(start_obj)
    range_index_data.stop = c.pyapi.long_as_longlong(stop_obj)
    range_index_data.step = c.pyapi.long_as_longlong(step_obj)
    range_index.data = range_index_data._getvalue()

    if typ.is_named:
        name_obj = c.pyapi.object_getattr_string(val, "name")
        range_index.name = numba.cpython.unicode.unbox_unicode_str(
            types.unicode_type, name_obj, c).value
        c.pyapi.decref(name_obj)

    c.pyapi.decref(start_obj)
    c.pyapi.decref(stop_obj)
    c.pyapi.decref(step_obj)
    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(range_index._getvalue(), is_error=is_error)
示例#8
0
def unbox_set(typ, obj, c):
    """
    Convert set *obj* to a native set.

    If set was previously unboxed, we reuse the existing native set
    to ensure consistency.
    """
    size = c.pyapi.set_size(obj)

    errorptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
    setptr = cgutils.alloca_once(c.builder, c.context.get_value_type(typ))

    # See if the set was previously unboxed, if so, re-use the meminfo.
    ptr = c.pyapi.object_get_private_data(obj)

    with c.builder.if_else(cgutils.is_not_null(c.builder, ptr)) \
        as (has_meminfo, otherwise):

        with has_meminfo:
            # Set was previously unboxed => reuse meminfo
            inst = setobj.SetInstance.from_meminfo(c.context, c.builder, typ, ptr)
            if typ.reflected:
                inst.parent = obj
            c.builder.store(inst.value, setptr)

        with otherwise:
            _python_set_to_native(typ, obj, c, size, setptr, errorptr)

    def cleanup():
        # Clean up the associated pointer, as the meminfo is now invalid.
        c.pyapi.object_reset_private_data(obj)

    return NativeValue(c.builder.load(setptr),
                       is_error=c.builder.load(errorptr),
                       cleanup=cleanup)
示例#9
0
 def unbox_(typ, obj, c):
     ptr_obj = c.pyapi.object_getattr_string(obj, "address")
     ctx = cgutils.create_struct_proxy(typ)(c.context, c.builder)
     ctx.ptr = c.pyapi.long_as_voidptr(ptr_obj)
     c.pyapi.decref(ptr_obj)
     is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
     return NativeValue(ctx._getvalue(), is_error=is_error)
示例#10
0
def unbox_buffer(typ, obj, c):
    """
    Convert a Py_buffer-providing object to a native array structure.
    """
    buf = c.pyapi.alloca_buffer()
    res = c.pyapi.get_buffer(obj, buf)
    is_error = cgutils.is_not_null(c.builder, res)

    nativearycls = c.context.make_array(typ)
    nativeary = nativearycls(c.context, c.builder)
    aryptr = nativeary._getpointer()

    with cgutils.if_likely(c.builder, c.builder.not_(is_error)):
        ptr = c.builder.bitcast(aryptr, c.pyapi.voidptr)
        if c.context.enable_nrt:
            c.pyapi.nrt_adapt_buffer_from_python(buf, ptr)
        else:
            c.pyapi.numba_buffer_adaptor(buf, ptr)

    def cleanup():
        c.pyapi.release_buffer(buf)

    return NativeValue(c.builder.load(aryptr),
                       is_error=is_error,
                       cleanup=cleanup)
def unbox_execution_progress(typ, obj, c):
    """
    Convert a ExecutionProgress object to a native structure.
    """
    output_progress_to_console_obj = c.pyapi.object_getattr_string(
        obj, "output_progress_to_console")
    is_true = c.pyapi.object_istrue(output_progress_to_console_obj)
    zero = ir.Constant(is_true.type, 0)
    lower_bound_obj = c.pyapi.object_getattr_string(obj, "lower_bound")
    number_of_decimal_places_obj = c.pyapi.object_getattr_string(
        obj, "number_of_decimal_places")
    execution_progress = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    execution_progress.output_progress_to_console = c.builder.icmp_signed(
        '!=', is_true, zero)
    execution_progress.lower_bound = c.pyapi.float_as_double(lower_bound_obj)
    ll_type = c.context.get_argument_type(types.intc)
    val = cgutils.alloca_once(c.builder, ll_type)
    longobj = c.pyapi.number_long(number_of_decimal_places_obj)
    with c.pyapi.if_object_ok(longobj):
        llval = c.pyapi.long_as_longlong(longobj)
        c.pyapi.decref(longobj)
        c.builder.store(c.builder.trunc(llval, ll_type), val)
    execution_progress.number_of_decimal_places = c.builder.load(val)
    c.pyapi.decref(lower_bound_obj)
    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(execution_progress._getvalue(), is_error=is_error)
示例#12
0
def unbox_funcptr(typ, obj, c):
    if typ.get_pointer is None:
        raise NotImplementedError(typ)

    # Call get_pointer() on the object to get the raw pointer value
    ptrty = c.context.get_function_pointer_type(typ)
    ret = cgutils.alloca_once_value(c.builder, ir.Constant(ptrty, None), name="fnptr")
    ser = c.pyapi.serialize_object(typ.get_pointer)
    get_pointer = c.pyapi.unserialize(ser)
    with cgutils.if_likely(c.builder, cgutils.is_not_null(c.builder, get_pointer)):
        intobj = c.pyapi.call_function_objargs(get_pointer, (obj,))
        c.pyapi.decref(get_pointer)
        with cgutils.if_likely(c.builder, cgutils.is_not_null(c.builder, intobj)):
            ptr = c.pyapi.long_as_voidptr(intobj)
            c.pyapi.decref(intobj)
            c.builder.store(c.builder.bitcast(ptr, ptrty), ret)
    return NativeValue(c.builder.load(ret), is_error=c.pyapi.c_api_error())
示例#13
0
    def check_occurred(self):
        """
        Return if an exception occurred.
        """
        err_occurred = cgutils.is_not_null(self.builder,
                                           self.pyapi.err_occurred())

        with cgutils.if_unlikely(self.builder, err_occurred):
            self.return_exception_raised()
示例#14
0
def box_dataframe(typ, val, c):
    context = c.context
    builder = c.builder

    n_cols = len(typ.columns)
    col_names = typ.columns
    arr_typs = typ.data
    dtypes = [a.dtype for a in arr_typs]  # TODO: check Categorical

    dataframe = cgutils.create_struct_proxy(typ)(context, builder, value=val)
    col_arrs = [builder.extract_value(dataframe.data, i) for i in range(n_cols)]
    # df unboxed from Python
    has_parent = cgutils.is_not_null(builder, dataframe.parent)

    pyapi = c.pyapi
    # gil_state = pyapi.gil_ensure()  # acquire GIL

    mod_name = context.insert_const_string(c.builder.module, "pandas")
    class_obj = pyapi.import_module_noblock(mod_name)
    df_dict = pyapi.dict_new()

    for i, cname, arr, arr_typ, dtype in zip(range(n_cols), col_names, col_arrs, arr_typs, dtypes):
        # df['cname'] = boxed_arr
        # TODO: datetime.date, DatetimeIndex?
        name_str = context.insert_const_string(c.builder.module, cname)
        cname_obj = pyapi.string_from_string(name_str)

        if dtype == string_type:
            arr_obj = box_str_arr(arr_typ, arr, c)
        elif isinstance(arr_typ, Categorical):
            arr_obj = box_Categorical(arr_typ, arr, c)
            # context.nrt.incref(builder, arr_typ, arr)
        elif dtype == types.List(string_type):
            arr_obj = box_list(list_string_array_type, arr, c)
            # context.nrt.incref(builder, arr_typ, arr)  # TODO required?
            # pyapi.print_object(arr_obj)
        else:
            arr_obj = box_array(arr_typ, arr, c)
            # TODO: is incref required?
            # context.nrt.incref(builder, arr_typ, arr)
        pyapi.dict_setitem(df_dict, cname_obj, arr_obj)

        pyapi.decref(arr_obj)
        pyapi.decref(cname_obj)

    df_obj = pyapi.call_method(class_obj, "DataFrame", (df_dict,))
    pyapi.decref(df_dict)

    # set df.index if necessary
    if typ.index != types.none:
        arr_obj = _box_series_data(typ.index.dtype, typ.index, dataframe.index, c)
        pyapi.object_setattr_string(df_obj, 'index', arr_obj)
        pyapi.decref(arr_obj)

    pyapi.decref(class_obj)
    # pyapi.gil_release(gil_state)    # release GIL
    return df_obj
示例#15
0
def unbox_MultiVector(typ: MultiVectorType, obj: MultiVector, c) -> NativeValue:
    value = c.pyapi.object_getattr_string(obj, "value")
    layout = c.pyapi.object_getattr_string(obj, "layout")
    mv = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    mv.layout = c.unbox(typ.layout_type, layout).value
    mv.value = c.unbox(typ.value_type, value).value
    c.pyapi.decref(value)
    c.pyapi.decref(layout)
    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(mv._getvalue(), is_error=is_error)
示例#16
0
def unbox_random_state(typ, obj, c):
    """Convert a `RandomState` object to a native `RandomStateNumbaModel` structure.

    Note that this will create a 'fake' structure which will just get the
    `RandomState` objects accepted in Numba functions but the actual information
    of the Numba's random state is stored internally and can be accessed
    anytime using ``numba._helperlib.rnd_get_np_state_ptr()``.
    """
    interval = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(interval._getvalue(), is_error=is_error)
示例#17
0
 def store(retval):
     is_ok = cgutils.is_not_null(builder, retval)
     # If an error is raised by the object mode ufunc, it will
     # simply get caught by the Numpy ufunc machinery.
     with builder.if_then(is_ok, likely=True):
         # Unbox
         native = pyapi.to_native_value(signature.return_type, retval)
         assert native.cleanup is None
         # Store
         out.store_direct(native.value, builder.load(store_offset))
         # Release owned reference
         pyapi.decref(retval)
示例#18
0
def unbox_empty_index(typ, val, c):

    index_struct = cgutils.create_struct_proxy(typ)(c.context, c.builder)

    if typ.is_named:
        name_obj = c.pyapi.object_getattr_string(val, "name")
        index_struct.name = numba.cpython.unicode.unbox_unicode_str(
            types.unicode_type, name_obj, c).value
        c.pyapi.decref(name_obj)

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(index_struct._getvalue(), is_error=is_error)
示例#19
0
def unbox_doubledouble(typ, obj, c):
    """
    Convert a DoubleDouble object to a native doubledouble structure.
    """
    x_obj = c.pyapi.object_getattr_string(obj, "x")
    y_obj = c.pyapi.object_getattr_string(obj, "y")
    doubledouble = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    doubledouble.x = c.pyapi.float_as_double(x_obj)
    doubledouble.y = c.pyapi.float_as_double(y_obj)
    c.pyapi.decref(x_obj)
    c.pyapi.decref(y_obj)
    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(doubledouble._getvalue(), is_error=is_error)
示例#20
0
 def unbox_interval(typ, obj, c):
     """
     Convert a Interval object to a native interval structure.
     """
     lo_obj = c.pyapi.object_getattr_string(obj, "lo")
     hi_obj = c.pyapi.object_getattr_string(obj, "hi")
     interval = cgutils.create_struct_proxy(typ)(c.context, c.builder)
     interval.lo = c.pyapi.float_as_double(lo_obj)
     interval.hi = c.pyapi.float_as_double(hi_obj)
     c.pyapi.decref(lo_obj)
     c.pyapi.decref(hi_obj)
     is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
     return NativeValue(interval._getvalue(), is_error=is_error)
示例#21
0
def is_leap_year(builder, year_val):
    """
    Return a predicate indicating whether *year_val* (offset by 1970) is a
    leap year.
    """
    actual_year = builder.add(year_val, Constant(DATETIME64, 1970))
    multiple_of_4 = cgutils.is_null(
        builder, builder.and_(actual_year, Constant(DATETIME64, 3)))
    not_multiple_of_100 = cgutils.is_not_null(
        builder, builder.srem(actual_year, Constant(DATETIME64, 100)))
    multiple_of_400 = cgutils.is_null(
        builder, builder.srem(actual_year, Constant(DATETIME64, 400)))
    return builder.and_(multiple_of_4,
                        builder.or_(not_multiple_of_100, multiple_of_400))
示例#22
0
def unbox_int64_index(typ, val, c):

    # TODO: support index unboxing with reference to parent in Numba?
    int64_index = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    index_data = c.pyapi.object_getattr_string(val, "_data")
    int64_index.data = unbox_array(typ.data, index_data, c).value
    c.pyapi.decref(index_data)

    if typ.is_named:
        name_obj = c.pyapi.object_getattr_string(val, "name")
        int64_index.name = numba.cpython.unicode.unbox_unicode_str(
            types.unicode_type, name_obj, c).value
        c.pyapi.decref(name_obj)

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(int64_index._getvalue(), is_error=is_error)
示例#23
0
def unbox_array(typ, obj, c):
    """
    Convert a Numpy array object to a native array structure.
    """
    # This is necessary because unbox_buffer() does not work on some
    # dtypes, e.g. datetime64 and timedelta64.
    # TODO check matching dtype.
    #      currently, mismatching dtype will still work and causes
    #      potential memory corruption
    nativearycls = c.context.make_array(typ)
    nativeary = nativearycls(c.context, c.builder)
    aryptr = nativeary._getpointer()

    ptr = c.builder.bitcast(aryptr, c.pyapi.voidptr)
    if c.context.enable_nrt:
        errcode = c.pyapi.nrt_adapt_ndarray_from_python(obj, ptr)
    else:
        errcode = c.pyapi.numba_array_adaptor(obj, ptr)

    # TODO: here we have minimal typechecking by the itemsize.
    #       need to do better
    try:
        expected_itemsize = numpy_support.as_dtype(typ.dtype).itemsize
    except NotImplementedError:
        # Don't check types that can't be `as_dtype()`-ed
        itemsize_mismatch = cgutils.false_bit
    else:
        expected_itemsize = nativeary.itemsize.type(expected_itemsize)
        itemsize_mismatch = c.builder.icmp_unsigned(
            '!=',
            nativeary.itemsize,
            expected_itemsize,
        )

    failed = c.builder.or_(
        cgutils.is_not_null(c.builder, errcode),
        itemsize_mismatch,
    )
    # Handle error
    with c.builder.if_then(failed, likely=False):
        c.pyapi.err_set_string(
            "PyExc_TypeError", "can't unbox array from PyObject into "
            "native value.  The object maybe of a "
            "different type")
    return NativeValue(c.builder.load(aryptr), is_error=failed)
示例#24
0
def _native_set_to_python_list(typ, payload, c):
    """
    Create a Python list from a native set's items.
    """
    nitems = payload.used
    listobj = c.pyapi.list_new(nitems)
    ok = cgutils.is_not_null(c.builder, listobj)
    with c.builder.if_then(ok, likely=True):
        index = cgutils.alloca_once_value(c.builder, ir.Constant(nitems.type, 0))
        with payload._iterate() as loop:
            i = c.builder.load(index)
            item = loop.entry.key
            itemobj = c.box(typ.dtype, item)
            c.pyapi.list_setitem(listobj, i, itemobj)
            i = c.builder.add(i, ir.Constant(i.type, 1))
            c.builder.store(i, index)

    return ok, listobj
示例#25
0
def box_charseq(typ, val, c):
    rawptr = cgutils.alloca_once_value(c.builder, value=val)
    strptr = c.builder.bitcast(rawptr, c.pyapi.cstring)
    fullsize = c.context.get_constant(types.intp, typ.count)
    zero = fullsize.type(0)
    one = fullsize.type(1)
    count = cgutils.alloca_once_value(c.builder, zero)

    # Find the length of the string, mimicking Numpy's behaviour:
    # search for the last non-null byte in the underlying storage
    # (e.g. b'A\0\0B\0\0\0' will return the logical string b'A\0\0B')
    with cgutils.loop_nest(c.builder, [fullsize], fullsize.type) as [idx]:
        # Get char at idx
        ch = c.builder.load(c.builder.gep(strptr, [idx]))
        # If the char is a non-null-byte, store the next index as count
        with c.builder.if_then(cgutils.is_not_null(c.builder, ch)):
            c.builder.store(c.builder.add(idx, one), count)

    strlen = c.builder.load(count)
    return c.pyapi.bytes_from_string_and_size(strptr, strlen)
示例#26
0
def unbox_int64_index(typ, val, c):

    nlevels = len(typ.levels)
    levels_types = typ.levels_types
    codes_types = typ.codes_types
    multi_index = cgutils.create_struct_proxy(typ)(c.context, c.builder)

    py_levels_data = c.pyapi.object_getattr_string(val, "levels")
    native_levels_data = []
    for i in range(nlevels):
        idx = c.pyapi.long_from_ulonglong(
            c.context.get_constant(types.int64, i))
        level_data = c.pyapi.object_getitem(py_levels_data, idx)
        native_levels_data.append(
            _unbox_index_data(levels_types[i], level_data, c).value)
        c.pyapi.decref(level_data)
    c.pyapi.decref(py_levels_data)
    multi_index.levels = c.context.make_tuple(c.builder, typ.levels,
                                              native_levels_data)

    py_codes_data = c.pyapi.object_getattr_string(val, "codes")
    native_codes_data = []
    for i in range(nlevels):
        idx = c.pyapi.long_from_ulonglong(
            c.context.get_constant(types.int64, i))
        code_data = c.pyapi.object_getitem(py_codes_data, idx)
        native_codes_data.append(
            unbox_array(codes_types[i], code_data, c).value)
        c.pyapi.decref(code_data)
    c.pyapi.decref(py_codes_data)
    multi_index.codes = c.context.make_tuple(c.builder, typ.codes,
                                             native_codes_data)

    if typ.is_named:
        name_obj = c.pyapi.object_getattr_string(val, "name")
        multi_index.name = numba.cpython.unicode.unbox_unicode_str(
            types.unicode_type, name_obj, c).value
        c.pyapi.decref(name_obj)

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(multi_index._getvalue(), is_error=is_error)
示例#27
0
def box_unicodecharseq(typ, val, c):
    # XXX could kind be determined from strptr?
    unicode_kind = {
        1: c.pyapi.py_unicode_1byte_kind,
        2: c.pyapi.py_unicode_2byte_kind,
        4: c.pyapi.py_unicode_4byte_kind}[numpy_support.sizeof_unicode_char]
    kind = c.context.get_constant(types.int32, unicode_kind)
    rawptr = cgutils.alloca_once_value(c.builder, value=val)
    strptr = c.builder.bitcast(rawptr, c.pyapi.cstring)

    fullsize = c.context.get_constant(types.intp, typ.count)
    zero = fullsize.type(0)
    one = fullsize.type(1)
    step = fullsize.type(numpy_support.sizeof_unicode_char)
    count = cgutils.alloca_once_value(c.builder, zero)
    with cgutils.loop_nest(c.builder, [fullsize], fullsize.type) as [idx]:
        # Get char at idx
        ch = c.builder.load(c.builder.gep(strptr, [c.builder.mul(idx, step)]))
        # If the char is a non-null-byte, store the next index as count
        with c.builder.if_then(cgutils.is_not_null(c.builder, ch)):
            c.builder.store(c.builder.add(idx, one), count)
    strlen = c.builder.load(count)
    return c.pyapi.string_from_kind_and_data(kind, strptr, strlen)
示例#28
0
    def _emit_python_wrapper(self, llvm_module):
        # Figure out the Python C API module creation function, and
        # get a LLVM function for it.
        create_module_fn = llvm_module.add_function(
            *self.module_create_definition)
        create_module_fn.linkage = lc.LINKAGE_EXTERNAL

        # Define a constant string for the module name.
        mod_name_const = self.context.insert_const_string(
            llvm_module, self.module_name)

        mod_def_base_init = lc.Constant.struct((
            lt._pyobject_head_init,  # PyObject_HEAD
            lc.Constant.null(self.m_init_ty),  # m_init
            lc.Constant.null(lt._llvm_py_ssize_t),  # m_index
            lc.Constant.null(lt._pyobject_head_p),  # m_copy
        ))
        mod_def_base = llvm_module.add_global_variable(mod_def_base_init.type,
                                                       '.module_def_base')
        mod_def_base.initializer = mod_def_base_init
        mod_def_base.linkage = lc.LINKAGE_INTERNAL

        method_array = self._emit_method_array(llvm_module)

        mod_def_init = lc.Constant.struct((
            mod_def_base_init,  # m_base
            mod_name_const,  # m_name
            lc.Constant.null(self._char_star),  # m_doc
            lc.Constant.int(lt._llvm_py_ssize_t, -1),  # m_size
            method_array,  # m_methods
            lc.Constant.null(self.inquiry_ty),  # m_reload
            lc.Constant.null(self.traverseproc_ty),  # m_traverse
            lc.Constant.null(self.inquiry_ty),  # m_clear
            lc.Constant.null(self.freefunc_ty)  # m_free
        ))

        # Define a constant string for the module name.
        mod_def = llvm_module.add_global_variable(mod_def_init.type,
                                                  '.module_def')
        mod_def.initializer = mod_def_init
        mod_def.linkage = lc.LINKAGE_INTERNAL

        # Define the module initialization function.
        mod_init_fn = llvm_module.add_function(*self.module_init_definition)
        entry = mod_init_fn.append_basic_block('Entry')
        builder = lc.Builder(entry)
        pyapi = self.context.get_python_api(builder)

        mod = builder.call(
            create_module_fn,
            (mod_def, lc.Constant.int(lt._int32, sys.api_version)))

        # Test if module has been created correctly.
        # (XXX for some reason comparing with the NULL constant fails llvm
        #  with an assertion in pydebug mode)
        with builder.if_then(cgutils.is_null(builder, mod)):
            builder.ret(NULL.bitcast(mod_init_fn.type.pointee.return_type))

        env_array = self._emit_environment_array(llvm_module, builder, pyapi)
        envgv_array = self._emit_envgvs_array(llvm_module, builder, pyapi)
        ret = self._emit_module_init_code(llvm_module, builder, mod,
                                          method_array, env_array, envgv_array)
        if ret is not None:
            with builder.if_then(cgutils.is_not_null(builder, ret)):
                # Init function errored out
                builder.ret(lc.Constant.null(mod.type))

        builder.ret(mod)

        self.dll_exports.append(mod_init_fn.name)
示例#29
0
    def lower_expr(self, expr):
        if expr.op == 'binop':
            return self.lower_binop(expr, expr.fn, inplace=False)
        elif expr.op == 'inplace_binop':
            return self.lower_binop(expr, expr.fn, inplace=True)
        elif expr.op == 'unary':
            value = self.loadvar(expr.value.name)
            if expr.fn == operator.neg:
                res = self.pyapi.number_negative(value)
            elif expr.fn == operator.pos:
                res = self.pyapi.number_positive(value)
            elif expr.fn == operator.not_:
                res = self.pyapi.object_not(value)
                self.check_int_status(res)
                res = self.pyapi.bool_from_bool(res)
            elif expr.fn == operator.invert:
                res = self.pyapi.number_invert(value)
            else:
                raise NotImplementedError(expr)
            self.check_error(res)
            return res
        elif expr.op == 'call':
            argvals = [self.loadvar(a.name) for a in expr.args]
            fn = self.loadvar(expr.func.name)
            args = self.pyapi.tuple_pack(argvals)
            if expr.vararg:
                # Expand *args
                new_args = self.pyapi.number_add(
                    args, self.loadvar(expr.vararg.name))
                self.decref(args)
                args = new_args
            if not expr.kws:
                # No named arguments
                ret = self.pyapi.call(fn, args, None)
            else:
                # Named arguments
                keyvalues = [(k, self.loadvar(v.name)) for k, v in expr.kws]
                kws = self.pyapi.dict_pack(keyvalues)
                ret = self.pyapi.call(fn, args, kws)
                self.decref(kws)
            self.decref(args)
            self.check_error(ret)
            return ret
        elif expr.op == 'getattr':
            obj = self.loadvar(expr.value.name)
            res = self.pyapi.object_getattr(obj,
                                            self._freeze_string(expr.attr))
            self.check_error(res)
            return res
        elif expr.op == 'build_tuple':
            items = [self.loadvar(it.name) for it in expr.items]
            res = self.pyapi.tuple_pack(items)
            self.check_error(res)
            return res
        elif expr.op == 'build_list':
            items = [self.loadvar(it.name) for it in expr.items]
            res = self.pyapi.list_pack(items)
            self.check_error(res)
            return res
        elif expr.op == 'build_map':
            res = self.pyapi.dict_new(expr.size)
            self.check_error(res)
            for k, v in expr.items:
                key = self.loadvar(k.name)
                value = self.loadvar(v.name)
                ok = self.pyapi.dict_setitem(res, key, value)
                self.check_int_status(ok)
            return res
        elif expr.op == 'build_set':
            items = [self.loadvar(it.name) for it in expr.items]
            res = self.pyapi.set_new()
            self.check_error(res)
            for it in items:
                ok = self.pyapi.set_add(res, it)
                self.check_int_status(ok)
            return res
        elif expr.op == 'getiter':
            obj = self.loadvar(expr.value.name)
            res = self.pyapi.object_getiter(obj)
            self.check_error(res)
            return res
        elif expr.op == 'iternext':
            iterobj = self.loadvar(expr.value.name)
            item = self.pyapi.iter_next(iterobj)
            is_valid = cgutils.is_not_null(self.builder, item)
            pair = self.pyapi.tuple_new(2)
            with self.builder.if_else(is_valid) as (then, otherwise):
                with then:
                    self.pyapi.tuple_setitem(pair, 0, item)
                with otherwise:
                    self.check_occurred()
                    # Make the tuple valid by inserting None as dummy
                    # iteration "result" (it will be ignored).
                    self.pyapi.tuple_setitem(pair, 0, self.pyapi.make_none())
            self.pyapi.tuple_setitem(pair, 1,
                                     self.pyapi.bool_from_bool(is_valid))
            return pair
        elif expr.op == 'pair_first':
            pair = self.loadvar(expr.value.name)
            first = self.pyapi.tuple_getitem(pair, 0)
            self.incref(first)
            return first
        elif expr.op == 'pair_second':
            pair = self.loadvar(expr.value.name)
            second = self.pyapi.tuple_getitem(pair, 1)
            self.incref(second)
            return second
        elif expr.op == 'exhaust_iter':
            iterobj = self.loadvar(expr.value.name)
            tup = self.pyapi.sequence_tuple(iterobj)
            self.check_error(tup)
            # Check tuple size is as expected
            tup_size = self.pyapi.tuple_size(tup)
            expected_size = self.context.get_constant(types.intp, expr.count)
            has_wrong_size = self.builder.icmp(lc.ICMP_NE, tup_size,
                                               expected_size)
            with cgutils.if_unlikely(self.builder, has_wrong_size):
                self.return_exception(ValueError)
            return tup
        elif expr.op == 'getitem':
            value = self.loadvar(expr.value.name)
            index = self.loadvar(expr.index.name)
            res = self.pyapi.object_getitem(value, index)
            self.check_error(res)
            return res
        elif expr.op == 'static_getitem':
            value = self.loadvar(expr.value.name)
            index = self.context.get_constant(types.intp, expr.index)
            indexobj = self.pyapi.long_from_ssize_t(index)
            self.check_error(indexobj)
            res = self.pyapi.object_getitem(value, indexobj)
            self.decref(indexobj)
            self.check_error(res)
            return res
        elif expr.op == 'getslice':
            target = self.loadvar(expr.target.name)
            start = self.loadvar(expr.start.name)
            stop = self.loadvar(expr.stop.name)

            slicefn = self.get_builtin_obj("slice")
            sliceobj = self.pyapi.call_function_objargs(slicefn, (start, stop))
            self.decref(slicefn)
            self.check_error(sliceobj)

            res = self.pyapi.object_getitem(target, sliceobj)
            self.check_error(res)

            return res

        elif expr.op == 'cast':
            val = self.loadvar(expr.value.name)
            self.incref(val)
            return val
        elif expr.op == 'phi':
            raise LoweringError("PHI not stripped")

        elif expr.op == 'null':
            # Make null value
            return cgutils.get_null_value(self.pyapi.pyobj)

        else:
            raise NotImplementedError(expr)