def define_dtor(self): "Define the destructor if not already defined" context = self._context builder = self._builder mod = builder.module # Declare dtor fnty = ir.FunctionType(ir.VoidType(), [cgutils.voidptr_t]) fn = mod.get_or_insert_function(fnty, name='.dtor.list.{}'.format( self.dtype)) if not fn.is_declaration: # End early if the dtor is already defined return fn fn.linkage = 'linkonce_odr' # Populate the dtor builder = ir.IRBuilder(fn.append_basic_block()) base_ptr = fn.args[0] # void* # get payload payload = ListPayloadAccessor(context, builder, self._ty, base_ptr) # Loop over all data to decref intp = payload.size.type with cgutils.for_range_slice(builder, start=intp(0), stop=payload.size, step=intp(1), intp=intp) as (idx, _): val = payload.getitem(idx) context.nrt.decref(builder, self.dtype, val) builder.ret_void() return fn
def delitem_list(context, builder, sig, args): inst = ListInstance(context, builder, sig.args[0], args[0]) slice = context.make_helper(builder, sig.args[1], args[1]) slicing.guard_invalid_slice(context, builder, sig.args[1], slice) inst.fix_slice(slice) slice_len = slicing.get_slice_length(builder, slice) one = ir.Constant(slice_len.type, 1) with builder.if_then(builder.icmp_signed('!=', slice.step, one), likely=False): msg = "unsupported del list[start:stop:step] with step != 1" context.call_conv.return_user_exc(builder, NotImplementedError, (msg, )) # Compute the real stop, e.g. for dest[2:0] start = slice.start real_stop = builder.add(start, slice_len) # Decref the removed range with cgutils.for_range_slice(builder, start, real_stop, start.type(1)) as (idx, _): inst.decref_value(inst.getitem(idx)) # Size of the list tail, after the end of slice tail_size = builder.sub(inst.size, real_stop) inst.move(start, real_stop, tail_size) inst.resize(builder.sub(inst.size, slice_len)) return context.get_dummy_value()
def list_mul(context, builder, sig, args): if isinstance(sig.args[0], types.List): list_idx, int_idx = 0, 1 else: list_idx, int_idx = 1, 0 src = ListInstance(context, builder, sig.args[list_idx], args[list_idx]) src_size = src.size mult = args[int_idx] zero = ir.Constant(mult.type, 0) mult = builder.select(cgutils.is_neg_int(builder, mult), zero, mult) nitems = builder.mul(mult, src_size) dest = ListInstance.allocate(context, builder, sig.return_type, nitems) dest.size = nitems with cgutils.for_range_slice(builder, zero, nitems, src_size, inc=True) as (dest_offset, _): with cgutils.for_range(builder, src_size) as loop: value = src.getitem(loop.index) dest.setitem(builder.add(loop.index, dest_offset), value, incref=True) return impl_ret_new_ref(context, builder, sig.return_type, dest.value)
def list_mul_inplace(context, builder, sig, args): inst = ListInstance(context, builder, sig.args[0], args[0]) src_size = inst.size mult = args[1] zero = ir.Constant(mult.type, 0) mult = builder.select(cgutils.is_neg_int(builder, mult), zero, mult) nitems = builder.mul(mult, src_size) inst.resize(nitems) with cgutils.for_range_slice(builder, src_size, nitems, src_size, inc=True) as (dest_offset, _): with cgutils.for_range(builder, src_size) as loop: value = inst.getitem(loop.index) inst.setitem(builder.add(loop.index, dest_offset), value, incref=True) return impl_ret_borrowed(context, builder, sig.return_type, inst.value)