def allocate_ex(cls, context, builder, list_type, nitems): """ Allocate a ListInstance with its storage. Return a (ok, instance) tuple where *ok* is a LLVM boolean and *instance* is a ListInstance object (the object's contents are only valid when *ok* is true). """ intp_t = context.get_value_type(types.intp) if isinstance(nitems, int): nitems = ir.Constant(intp_t, nitems) payload_type = context.get_data_type(types.ListPayload(list_type)) payload_size = context.get_abi_sizeof(payload_type) itemsize = get_itemsize(context, list_type) # Account for the fact that the payload struct contains one entry payload_size -= itemsize ok = cgutils.alloca_once_value(builder, cgutils.true_bit) self = cls(context, builder, list_type, None) # Total allocation size = <payload header size> + nitems * itemsize allocsize, ovf = cgutils.muladd_with_overflow( builder, nitems, ir.Constant(intp_t, itemsize), ir.Constant(intp_t, payload_size), ) with builder.if_then(ovf, likely=False): builder.store(cgutils.false_bit, ok) with builder.if_then(builder.load(ok), likely=True): meminfo = context.nrt.meminfo_new_varsize_dtor( builder, size=allocsize, dtor=self.get_dtor() ) with builder.if_else(cgutils.is_null(builder, meminfo), likely=False) as ( if_error, if_ok, ): with if_error: builder.store(cgutils.false_bit, ok) with if_ok: self._list.meminfo = meminfo self._list.parent = context.get_constant_null(types.pyobject) self._payload.allocated = nitems self._payload.size = ir.Constant(intp_t, 0) # for safety self._payload.dirty = cgutils.false_bit # Zero the allocated region self.zfill(self.size.type(0), nitems) return builder.load(ok), self
def _payload_realloc(new_allocated): payload_type = context.get_data_type(types.ListPayload(self._ty)) payload_size = context.get_abi_sizeof(payload_type) # Account for the fact that the payload struct contains one entry payload_size -= itemsize allocsize, ovf = cgutils.muladd_with_overflow( builder, new_allocated, ir.Constant(intp_t, itemsize), ir.Constant(intp_t, payload_size)) with builder.if_then(ovf, likely=False): context.call_conv.return_user_exc(builder, MemoryError, ("cannot resize list", )) ptr = context.nrt.meminfo_varsize_realloc_unchecked( builder, self._list.meminfo, size=allocsize) cgutils.guard_memory_error(context, builder, ptr, "cannot resize list") self._payload.allocated = new_allocated