예제 #1
0
파일: callconv.py 프로젝트: EGQM/numba
    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)
예제 #2
0
    def codegen(context, builder, signature, args):
        instance, = args

        # TODO: probably a more general way to do this
        second_element = builder.extract_value(instance, [1])
        result = cgutils.is_not_null(builder, second_element)
        return result
예제 #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)

    if context.enable_nrt:
        context.nrt_incref(builder, ty, val)
    # XXX unfortunately, we don't have access to the env manager from here
    obj = pyapi.from_native_value(ty, val)
    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 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()
예제 #5
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)

    if context.enable_nrt:
        context.nrt.incref(builder, ty, val)
    # XXX unfortunately, we don't have access to the env manager from here
    obj = pyapi.from_native_value(ty, val)
    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)
예제 #6
0
    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()
예제 #7
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)
예제 #8
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)
예제 #9
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_obj = pyapi.call_method(class_obj, "DataFrame", ())

    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(dtype, PDCategoricalDtype):
            arr_obj = box_categorical_array(arr_typ, arr, c)
            # context.nrt.incref(builder, arr_typ, arr)
        elif arr_typ == string_array_split_view_type:
            arr_obj = box_str_arr_split_view(arr_typ, arr, c)
        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.object_setitem(df_obj, cname_obj, arr_obj)

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

    # 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(class_obj)
    # pyapi.gil_release(gil_state)    # release GIL
    return df_obj
예제 #10
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()
예제 #11
0
 def list_pack(self, items):
     n = len(items)
     seq = self.list_new(self.context.get_constant(types.intp, n))
     not_null = cgutils.is_not_null(self.builder, seq)
     with cgutils.if_likely(self.builder, not_null):
         for i in range(n):
             idx = self.context.get_constant(types.intp, i)
             self.incref(items[i])
             self.list_setitem(seq, idx, items[i])
     return seq
예제 #12
0
 def list_pack(self, items):
     n = len(items)
     seq = self.list_new(self.context.get_constant(types.intp, n))
     not_null = cgutils.is_not_null(self.builder, seq)
     with cgutils.if_likely(self.builder, not_null):
         for i in range(n):
             idx = self.context.get_constant(types.intp, i)
             self.incref(items[i])
             self.list_setitem(seq, idx, items[i])
     return seq
예제 #13
0
def check_lapack_return(context, builder, res):
    """
    Check the integer error return from one of the LAPACK wrappers in
    _helperlib.c.
    """
    with builder.if_then(cgutils.is_not_null(builder, res), likely=False):
        # Those errors shouldn't happen, it's easier to just abort the process
        pyapi = context.get_python_api(builder)
        pyapi.gil_ensure()
        pyapi.fatal_error("LAPACK wrapper returned with an error")
예제 #14
0
파일: pythonapi.py 프로젝트: molodiuc/numba
 def to_native_array(self, ary, typ):
     # TODO check matching dtype.
     #      currently, mismatching dtype will still work and causes
     #      potential memory corruption
     nativearycls = self.context.make_array(typ)
     nativeary = nativearycls(self.context, self.builder)
     aryptr = nativeary._getpointer()
     ptr = self.builder.bitcast(aryptr, self.voidptr)
     errcode = self.numba_array_adaptor(ary, ptr)
     failed = cgutils.is_not_null(self.builder, errcode)
     return self.builder.load(aryptr), failed
예제 #15
0
파일: wrappers.py 프로젝트: rxist525/numba
 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)
예제 #16
0
 def dict_pack(self, keyvalues):
     """
     Args
     -----
     keyvalues: iterable of (str, llvm.Value of PyObject*)
     """
     dictobj = self.dict_new()
     not_null = cgutils.is_not_null(self.builder, dictobj)
     with cgutils.if_likely(self.builder, not_null):
         for k, v in keyvalues:
             self.dict_setitem_string(dictobj, k, v)
     return dictobj
예제 #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 dict_pack(self, keyvalues):
     """
     Args
     -----
     keyvalues: iterable of (str, llvm.Value of PyObject*)
     """
     dictobj = self.dict_new()
     not_null = cgutils.is_not_null(self.builder, dictobj)
     with cgutils.if_likely(self.builder, not_null):
         for k, v in keyvalues:
             self.dict_setitem_string(dictobj, k, v)
     return dictobj
예제 #19
0
파일: npdatetime.py 프로젝트: genba/numba
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.int(DATETIME64, 1970))
    multiple_of_4 = cgutils.is_null(
        builder, builder.and_(actual_year, Constant.int(DATETIME64, 3)))
    not_multiple_of_100 = cgutils.is_not_null(
        builder, builder.srem(actual_year, Constant.int(DATETIME64, 100)))
    multiple_of_400 = cgutils.is_null(
        builder, builder.srem(actual_year, Constant.int(DATETIME64, 400)))
    return builder.and_(multiple_of_4,
                        builder.or_(not_multiple_of_100, multiple_of_400))
예제 #20
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.int(DATETIME64, 1970))
    multiple_of_4 = cgutils.is_null(
        builder, builder.and_(actual_year, Constant.int(DATETIME64, 3)))
    not_multiple_of_100 = cgutils.is_not_null(
        builder, builder.srem(actual_year, Constant.int(DATETIME64, 100)))
    multiple_of_400 = cgutils.is_null(
        builder, builder.srem(actual_year, Constant.int(DATETIME64, 400)))
    return builder.and_(multiple_of_4,
                        builder.or_(not_multiple_of_100, multiple_of_400))
예제 #21
0
    def make_exception_switch(self, api, builder, status):
        """
        Handle user exceptions.  Unserialize the exception info and raise it.
        """
        code = status.code
        # Handle user exceptions
        with cgutils.ifthen(builder, status.is_user_exc):
            exc = api.unserialize(status.excinfoptr)
            with cgutils.if_likely(builder,
                                   cgutils.is_not_null(builder, exc)):
                api.raise_object(exc)  # steals ref
            builder.ret(api.get_null_object())

        msg = "unknown error in native function: %s" % self.fndesc.mangled_name
        api.err_set_string("PyExc_SystemError", msg)
예제 #22
0
 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)
예제 #23
0
 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)
예제 #24
0
def unbox_datetime_date_array(typ, val, c):
    #
    n = object_length(c, val)
    #cgutils.printf(c.builder, "len %d\n", n)
    arr_typ = types.Array(types.intp, 1, 'C')
    out_arr = _empty_nd_impl(c.context, c.builder, arr_typ, [n])

    with cgutils.for_range(c.builder, n) as loop:
        dt_date = sequence_getitem(c, val, loop.index)
        int_date = unbox_datetime_date(datetime_date_type, dt_date, c).value
        dataptr, shapes, strides = basic_indexing(
            c.context, c.builder, arr_typ, out_arr, (types.intp,), (loop.index,))
        store_item(c.context, c.builder, arr_typ, int_date, dataptr)

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(out_arr._getvalue(), is_error=is_error)
예제 #25
0
def unbox_unicode_str(typ, obj, c):
    """
    Convert a unicode str object to a native unicode structure.
    """
    ok, data, length, kind = c.pyapi.string_as_string_size_and_kind(obj)
    uni_str = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    uni_str.data = data
    uni_str.length = length
    uni_str.kind = kind
    uni_str.meminfo = c.pyapi.nrt_meminfo_new_from_pyobject(
        data,  # the borrowed data pointer
        obj,   # the owner pyobject; the call will incref it.
    )
    uni_str.parent = obj

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(uni_str._getvalue(), is_error=is_error)
예제 #26
0
def unbox_str_series(typ, val, c):
    """
    Unbox a Pandas String Series. We just redirect to StringArray implementation.
    """
    dtype = StringArrayPayloadType()
    payload = cgutils.create_struct_proxy(dtype)(c.context, c.builder)
    string_array = c.context.make_helper(c.builder, typ)

    # function signature of string_array_from_sequence
    # we use void* instead of PyObject*
    fnty = lir.FunctionType(lir.VoidType(), [
        lir.IntType(8).as_pointer(),
        lir.IntType(64).as_pointer(),
        lir.IntType(32).as_pointer().as_pointer(),
        lir.IntType(8).as_pointer().as_pointer(),
        lir.IntType(8).as_pointer().as_pointer(),
    ])
    fn = c.builder.module.get_or_insert_function(
        fnty, name="string_array_from_sequence")
    c.builder.call(fn, [
        val,
        string_array._get_ptr_by_name('num_items'),
        payload._get_ptr_by_name('offsets'),
        payload._get_ptr_by_name('data'),
        payload._get_ptr_by_name('null_bitmap'),
    ])

    # the raw data is now copied to payload
    # The native representation is a proxy to the payload, we need to
    # get a proxy and attach the payload and meminfo
    meminfo, meminfo_data_ptr = construct_string_array(c.context, c.builder)
    c.builder.store(payload._getvalue(), meminfo_data_ptr)

    string_array.meminfo = meminfo
    string_array.offsets = payload.offsets
    string_array.data = payload.data
    string_array.null_bitmap = payload.null_bitmap
    string_array.num_total_chars = c.builder.zext(
        c.builder.load(
            c.builder.gep(string_array.offsets, [string_array.num_items])),
        lir.IntType(64))

    # FIXME how to check that the returned size is > 0?
    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(string_array._getvalue(), is_error=is_error)
예제 #27
0
파일: unicode.py 프로젝트: esc/numba
def unbox_unicode_str(typ, obj, c):
    """
    Convert a unicode str object to a native unicode structure.
    """
    ok, data, length, kind, hashv = c.pyapi.string_as_string_size_and_kind(obj)
    uni_str = cgutils.create_struct_proxy(typ)(c.context, c.builder)
    uni_str.data = data
    uni_str.length = length
    uni_str.kind = kind
    uni_str.hash = hashv
    uni_str.meminfo = c.pyapi.nrt_meminfo_new_from_pyobject(
        data,  # the borrowed data pointer
        obj,   # the owner pyobject; the call will incref it.
    )
    uni_str.parent = obj

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(uni_str._getvalue(), is_error=is_error)
예제 #28
0
파일: pythonapi.py 프로젝트: molodiuc/numba
    def to_native_buffer(self, obj, typ):
        buf = self.alloca_buffer()
        res = self.get_buffer(obj, buf)
        is_error = cgutils.is_not_null(self.builder, res)

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

        with cgutils.if_likely(self.builder, self.builder.not_(is_error)):
            ptr = self.builder.bitcast(aryptr, self.voidptr)
            self.numba_buffer_adaptor(buf, ptr)

        def cleanup():
            self.release_buffer(buf)

        return NativeValue(self.builder.load(aryptr), is_error=is_error,
                           cleanup=cleanup)
예제 #29
0
    def make_exception_switch(self, api, builder, status):
        """
        Handle user exceptions.  Unserialize the exception info and raise it.
        """
        code = status.code
        # Handle user exceptions
        with builder.if_then(status.is_user_exc):
            exc = api.unserialize(status.excinfoptr)
            with cgutils.if_likely(builder, cgutils.is_not_null(builder, exc)):
                api.raise_object(exc)  # steals ref
            builder.ret(api.get_null_object())

        with builder.if_then(status.is_stop_iteration):
            api.err_set_none("PyExc_StopIteration")
            builder.ret(api.get_null_object())

        msg = "unknown error in native function: %s" % self.fndesc.mangled_name
        api.err_set_string("PyExc_SystemError", msg)
예제 #30
0
def unbox_datetime_date(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")

    yll = c.pyapi.long_as_longlong(year_obj)
    mll = c.pyapi.long_as_longlong(month_obj)
    dll = c.pyapi.long_as_longlong(day_obj)

    nopython_date = c.builder.add(dll,
                                  c.builder.add(c.builder.shl(yll, lir.Constant(lir.IntType(64), 32)),
                                                c.builder.shl(mll, lir.Constant(lir.IntType(64), 16))))

    c.pyapi.decref(year_obj)
    c.pyapi.decref(month_obj)
    c.pyapi.decref(day_obj)

    is_error = cgutils.is_not_null(c.builder, c.pyapi.err_occurred())
    return NativeValue(nopython_date, is_error=is_error)
예제 #31
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.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)
예제 #32
0
파일: pythonapi.py 프로젝트: molodiuc/numba
    def to_native_value(self, obj, typ):
        builder = self.builder
        def c_api_error():
            return cgutils.is_not_null(builder, self.err_occurred())

        if isinstance(typ, types.Object) or typ == types.pyobject:
            return NativeValue(obj)

        elif typ == types.boolean:
            istrue = self.object_istrue(obj)
            zero = Constant.null(istrue.type)
            val = builder.icmp(lc.ICMP_NE, istrue, zero)
            return NativeValue(val, is_error=c_api_error())

        elif isinstance(typ, types.Integer):
            val = self.to_native_int(obj, typ)
            return NativeValue(val, is_error=c_api_error())

        elif typ == types.float32:
            fobj = self.number_float(obj)
            fval = self.float_as_double(fobj)
            self.decref(fobj)
            val = builder.fptrunc(fval,
                                  self.context.get_argument_type(typ))
            return NativeValue(val, is_error=c_api_error())

        elif typ == types.float64:
            fobj = self.number_float(obj)
            val = self.float_as_double(fobj)
            self.decref(fobj)
            return NativeValue(val, is_error=c_api_error())

        elif typ in (types.complex128, types.complex64):
            cplxcls = self.context.make_complex(types.complex128)
            cplx = cplxcls(self.context, builder)
            pcplx = cplx._getpointer()
            ok = self.complex_adaptor(obj, pcplx)
            failed = cgutils.is_false(builder, ok)

            with cgutils.if_unlikely(builder, failed):
                self.err_set_string("PyExc_TypeError",
                                    "conversion to %s failed" % (typ,))

            if typ == types.complex64:
                c64cls = self.context.make_complex(typ)
                c64 = c64cls(self.context, builder)
                freal = self.context.cast(builder, cplx.real,
                                          types.float64, types.float32)
                fimag = self.context.cast(builder, cplx.imag,
                                          types.float64, types.float32)
                c64.real = freal
                c64.imag = fimag
                return NativeValue(c64._getvalue(), is_error=failed)
            else:
                return NativeValue(cplx._getvalue(), is_error=failed)

        elif isinstance(typ, types.NPDatetime):
            val = self.extract_np_datetime(obj)
            return NativeValue(val, is_error=c_api_error())

        elif isinstance(typ, types.NPTimedelta):
            val = self.extract_np_timedelta(obj)
            return NativeValue(val, is_error=c_api_error())

        elif isinstance(typ, types.Record):
            buf = self.alloca_buffer()
            ptr = self.extract_record_data(obj, buf)
            is_error = cgutils.is_null(self.builder, ptr)

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

            def cleanup():
                self.release_buffer(buf)
            return NativeValue(val, cleanup=cleanup, is_error=is_error)

        elif isinstance(typ, types.Array):
            val, failed = self.to_native_array(obj, typ)
            return NativeValue(val, is_error=failed)

        elif isinstance(typ, types.Buffer):
            return self.to_native_buffer(obj, typ)

        elif isinstance(typ, types.Optional):
            return self.to_native_optional(obj, typ)

        elif isinstance(typ, (types.Tuple, types.UniTuple)):
            return self.to_native_tuple(obj, typ)

        elif isinstance(typ, types.Generator):
            return self.to_native_generator(obj, typ)

        elif isinstance(typ, types.ExternalFunctionPointer):
            if typ.get_pointer is not None:
                # Call get_pointer() on the object to get the raw pointer value
                ptrty = self.context.get_function_pointer_type(typ)
                ret = cgutils.alloca_once_value(builder,
                                                Constant.null(ptrty),
                                                name='fnptr')
                ser = self.serialize_object(typ.get_pointer)
                get_pointer = self.unserialize(ser)
                with cgutils.if_likely(builder,
                                       cgutils.is_not_null(builder, get_pointer)):
                    intobj = self.call_function_objargs(get_pointer, (obj,))
                    self.decref(get_pointer)
                    with cgutils.if_likely(builder,
                                           cgutils.is_not_null(builder, intobj)):
                        ptr = self.long_as_voidptr(intobj)
                        self.decref(intobj)
                        builder.store(builder.bitcast(ptr, ptrty), ret)
                return NativeValue(builder.load(ret), is_error=c_api_error())

        raise NotImplementedError("cannot convert %s to native value" % (typ,))
예제 #33
0
def box_str_arr_split_view(typ, val, c):
    context = c.context
    builder = c.builder
    sp_view = context.make_helper(builder, string_array_split_view_type, val)

    # create array of objects with num_items shape
    mod_name = c.context.insert_const_string(c.builder.module, "numpy")
    np_class_obj = c.pyapi.import_module_noblock(mod_name)
    dtype = c.pyapi.object_getattr_string(np_class_obj, 'object_')
    l_num_items = builder.sext(sp_view.num_items, c.pyapi.longlong)
    num_items_obj = c.pyapi.long_from_longlong(l_num_items)
    out_arr = c.pyapi.call_method(np_class_obj, "ndarray",
                                  (num_items_obj, dtype))

    # Array setitem call
    arr_get_fnty = LLType.function(
        lir.IntType(8).as_pointer(), [c.pyapi.pyobj, c.pyapi.py_ssize_t])
    arr_get_fn = c.pyapi._get_function(arr_get_fnty, name="array_getptr1")
    arr_setitem_fnty = LLType.function(
        lir.VoidType(),
        [c.pyapi.pyobj,
         lir.IntType(8).as_pointer(), c.pyapi.pyobj])
    arr_setitem_fn = c.pyapi._get_function(arr_setitem_fnty,
                                           name="array_setitem")

    # for each string
    with cgutils.for_range(builder, sp_view.num_items) as loop:
        str_ind = loop.index
        # start and end offset of string's list in index_offsets
        # sp_view.index_offsets[str_ind]
        list_start_offset = builder.sext(
            builder.load(builder.gep(sp_view.index_offsets, [str_ind])),
            lir.IntType(64))
        # sp_view.index_offsets[str_ind+1]
        list_end_offset = builder.sext(
            builder.load(
                builder.gep(sp_view.index_offsets,
                            [builder.add(str_ind, str_ind.type(1))])),
            lir.IntType(64))
        # cgutils.printf(builder, "%d %d\n", list_start, list_end)

        # Build a new Python list
        nitems = builder.sub(list_end_offset, list_start_offset)
        nitems = builder.sub(nitems, nitems.type(1))
        # cgutils.printf(builder, "str %lld n %lld\n", str_ind, nitems)
        list_obj = c.pyapi.list_new(nitems)
        with c.builder.if_then(cgutils.is_not_null(c.builder, list_obj),
                               likely=True):
            with cgutils.for_range(c.builder, nitems) as loop:
                # data_offsets of current list
                start_index = builder.add(list_start_offset, loop.index)
                data_start = builder.load(
                    builder.gep(sp_view.data_offsets, [start_index]))
                # add 1 since starts from -1
                data_start = builder.add(data_start, data_start.type(1))
                data_end = builder.load(
                    builder.gep(
                        sp_view.data_offsets,
                        [builder.add(start_index, start_index.type(1))]))
                # cgutils.printf(builder, "ind %lld %lld\n", data_start, data_end)
                data_ptr = builder.gep(builder.extract_value(sp_view.data, 0),
                                       [data_start])
                str_size = builder.sext(builder.sub(data_end, data_start),
                                        lir.IntType(64))
                str_obj = c.pyapi.string_from_string_and_size(
                    data_ptr, str_size)
                c.pyapi.list_setitem(list_obj, loop.index, str_obj)

        arr_ptr = builder.call(arr_get_fn, [out_arr, str_ind])
        builder.call(arr_setitem_fn, [out_arr, arr_ptr, list_obj])

    c.pyapi.decref(np_class_obj)
    return out_arr
예제 #34
0
파일: compiler.py 프로젝트: yuguen/numba
    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)
        ret = self._emit_module_init_code(llvm_module, builder, mod,
                                          method_array, env_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)
예제 #35
0
 def c_api_error(self):
     return cgutils.is_not_null(self.builder, self.err_occurred())
예제 #36
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):
            self.return_exception_raised()
예제 #37
0
 def if_object_ok(self, obj):
     with cgutils.if_likely(self.builder,
                            cgutils.is_not_null(self.builder, obj)):
         yield
예제 #38
0
    def lower_expr(self, expr):
        if expr.op == 'binop':
            return self.lower_binop(expr, inplace=False)
        elif expr.op == 'inplace_binop':
            return self.lower_binop(expr, inplace=True)
        elif expr.op == 'unary':
            value = self.loadvar(expr.value.name)
            if expr.fn == '-':
                res = self.pyapi.number_negative(value)
            elif expr.fn == '+':
                res = self.pyapi.number_positive(value)
            elif expr.fn == 'not':
                res = self.pyapi.object_not(value)
                self.check_int_status(res)

                longval = self.builder.zext(res, self.pyapi.long)
                res = self.pyapi.bool_from_long(longval)
            elif expr.fn == '~':
                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)
            if not expr.kws:
                # No keyword
                ret = self.pyapi.call_function_objargs(fn, argvals)
            else:
                # Have Keywords
                keyvalues = [(k, self.loadvar(v.name)) for k, v in expr.kws]
                args = self.pyapi.tuple_pack(argvals)
                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)
            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 cgutils.ifelse(self.builder, 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):
                excid = self.add_exception(ValueError)
                self.context.return_user_exc(self.builder, excid)
            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

        else:
            raise NotImplementedError(expr)
예제 #39
0
    def lower_expr(self, expr):
        if expr.op == 'binop':
            return self.lower_binop(expr, inplace=False)
        elif expr.op == 'inplace_binop':
            return self.lower_binop(expr, inplace=True)
        elif expr.op == 'unary':
            value = self.loadvar(expr.value.name)
            if expr.fn == '-':
                res = self.pyapi.number_negative(value)
            elif expr.fn == '+':
                res = self.pyapi.number_positive(value)
            elif expr.fn == 'not':
                res = self.pyapi.object_not(value)
                self.check_int_status(res)

                longval = self.builder.zext(res, self.pyapi.long)
                res = self.pyapi.bool_from_long(longval)
            elif expr.fn == '~':
                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)
            if not expr.kws:
                # No keyword
                ret = self.pyapi.call_function_objargs(fn, argvals)
            else:
                # Have Keywords
                keyvalues = [(k, self.loadvar(v.name)) for k, v in expr.kws]
                args = self.pyapi.tuple_pack(argvals)
                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_string(obj, 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)
            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 cgutils.ifelse(self.builder, 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):
                excid = self.add_exception(ValueError)
                self.context.return_user_exc(self.builder, excid)
            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

        else:
            raise NotImplementedError(expr)
예제 #40
0
파일: pythonapi.py 프로젝트: ibtawfik/numba
 def if_object_ok(self, obj):
     with cgutils.if_likely(self.builder,
                            cgutils.is_not_null(self.builder, obj)):
         yield
예제 #41
0
파일: pythonapi.py 프로젝트: ibtawfik/numba
 def c_api_error(self):
     return cgutils.is_not_null(self.builder, self.err_occurred())
예제 #42
0
def check_blas_return(context, builder, res):
    with builder.if_then(cgutils.is_not_null(builder, res), likely=False):
        # Those errors shouldn't happen, it's easier to just abort the process
        pyapi = context.get_python_api(builder)
        pyapi.gil_ensure()
        pyapi.fatal_error("BLAS wrapper returned with an error")
예제 #43
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):
            self.return_exception_raised()
예제 #44
0
파일: compiler.py 프로젝트: zxsted/numba
    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)
        ret = self._emit_module_init_code(llvm_module, builder, mod,
                                          method_array, env_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)