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)
def reflect_list(typ, val, c): """ Reflect the native list's contents into the Python object. """ if not typ.reflected: return if typ.dtype.reflected: msg = "cannot reflect element of reflected container: {}\n".format(typ) raise TypeError(msg) list = listobj.ListInstance(c.context, c.builder, typ, val) with c.builder.if_then(list.dirty, likely=False): obj = list.parent size = c.pyapi.list_size(obj) new_size = list.size diff = c.builder.sub(new_size, size) diff_gt_0 = c.builder.icmp_signed('>=', diff, ir.Constant(diff.type, 0)) with c.builder.if_else(diff_gt_0) as (if_grow, if_shrink): # XXX no error checking below with if_grow: # First overwrite existing items with cgutils.for_range(c.builder, size) 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) # Then add missing items with cgutils.for_range(c.builder, diff) as loop: idx = c.builder.add(size, loop.index) item = list.getitem(idx) list.incref_value(item) itemobj = c.box(typ.dtype, item) c.pyapi.list_append(obj, itemobj) c.pyapi.decref(itemobj) with if_shrink: # First delete list tail c.pyapi.list_setslice(obj, new_size, size, None) # Then overwrite remaining items with cgutils.for_range(c.builder, new_size) 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) # Mark the list clean, in case it is reflected twice list.set_dirty(False)
def list_ctypes(context, builder, typ, value): inst = listobj.ListInstance(context, builder, typ, value) return builder.bitcast(inst.data, ll_void_p)
def list_size(context, builder, typ, value): inst = listobj.ListInstance(context, builder, typ, value) return inst.size