def unicode_to_unicode_charseq(context, builder, fromty, toty, val): uni_str = cgutils.create_struct_proxy(fromty)(context, builder, value=val) src1 = builder.bitcast(uni_str.data, ir.IntType(8).as_pointer()) src2 = builder.bitcast(uni_str.data, ir.IntType(16).as_pointer()) src4 = builder.bitcast(uni_str.data, ir.IntType(32).as_pointer()) kind1 = builder.icmp_unsigned('==', uni_str.kind, ir.Constant(uni_str.kind.type, 1)) kind2 = builder.icmp_unsigned('==', uni_str.kind, ir.Constant(uni_str.kind.type, 2)) kind4 = builder.icmp_unsigned('==', uni_str.kind, ir.Constant(uni_str.kind.type, 4)) src_length = uni_str.length lty = context.get_value_type(toty) dstint_t = ir.IntType(8 * unicode_byte_width) dst_ptr = cgutils.alloca_once(builder, lty) dst = builder.bitcast(dst_ptr, dstint_t.as_pointer()) dst_length = ir.Constant(src_length.type, toty.count) is_shorter_value = builder.icmp_unsigned('<', src_length, dst_length) count = builder.select(is_shorter_value, src_length, dst_length) with builder.if_then(is_shorter_value): cgutils.memset(builder, dst, ir.Constant(src_length.type, toty.count * unicode_byte_width), 0) with builder.if_then(kind1): with cgutils.for_range(builder, count) as loop: in_ptr = builder.gep(src1, [loop.index]) in_val = builder.zext(builder.load(in_ptr), dstint_t) builder.store(in_val, builder.gep(dst, [loop.index])) with builder.if_then(kind2): if unicode_byte_width >= 2: with cgutils.for_range(builder, count) as loop: in_ptr = builder.gep(src2, [loop.index]) in_val = builder.zext(builder.load(in_ptr), dstint_t) builder.store(in_val, builder.gep(dst, [loop.index])) else: context.call_conv.return_user_exc( builder, ValueError, ("cannot cast 16-bit unicode_type to %s-bit %s" % (unicode_byte_width * 8, toty))) with builder.if_then(kind4): if unicode_byte_width >= 4: with cgutils.for_range(builder, count) as loop: in_ptr = builder.gep(src4, [loop.index]) in_val = builder.zext(builder.load(in_ptr), dstint_t) builder.store(in_val, builder.gep(dst, [loop.index])) else: context.call_conv.return_user_exc( builder, ValueError, ("cannot cast 32-bit unicode_type to %s-bit %s" % (unicode_byte_width * 8, toty))) return builder.load(dst_ptr)
def codegen(context, builder, sig, args): in_str_arr, = args string_array = context.make_helper(builder, string_array_type, in_str_arr) # n_bytes = (num_strings+sizeof(uint8_t)-1)/sizeof(uint8_t); n_bytes = builder.udiv( builder.add(string_array.num_items, lir.Constant(lir.IntType(64), 7)), lir.Constant(lir.IntType(64), 8)) cgutils.memset(builder, string_array.null_bitmap, n_bytes, -1) return context.get_dummy_value()
def zfill(self, start, stop): """Zero-fill the memory at index *start* to *stop* *stop* MUST not be smaller than *start*. """ builder = self._builder base = self._gep(start) end = self._gep(stop) intaddr_t = self._context.get_value_type(types.intp) size = builder.sub(builder.ptrtoint(end, intaddr_t), builder.ptrtoint(base, intaddr_t)) cgutils.memset(builder, base, size, ir.IntType(8)(0))
def bytes_to_charseq(context, builder, fromty, toty, val): barr = cgutils.create_struct_proxy(fromty)(context, builder, value=val) src = builder.bitcast(barr.data, ir.IntType(8).as_pointer()) src_length = barr.nitems lty = context.get_value_type(toty) dstint_t = ir.IntType(8) dst_ptr = cgutils.alloca_once(builder, lty) dst = builder.bitcast(dst_ptr, dstint_t.as_pointer()) dst_length = ir.Constant(src_length.type, toty.count) is_shorter_value = builder.icmp_unsigned('<', src_length, dst_length) count = builder.select(is_shorter_value, src_length, dst_length) with builder.if_then(is_shorter_value): cgutils.memset(builder, dst, ir.Constant(src_length.type, toty.count), 0) with cgutils.for_range(builder, count) as loop: in_ptr = builder.gep(src, [loop.index]) in_val = builder.zext(builder.load(in_ptr), dstint_t) builder.store(in_val, builder.gep(dst, [loop.index])) return builder.load(dst_ptr)
def _allocate_payload(self, nentries, realloc=False): """ Allocate and initialize payload for the given number of entries. If *realloc* is True, the existing meminfo is reused. CAUTION: *nentries* must be a power of 2! """ context = self._context builder = self._builder ok = cgutils.alloca_once_value(builder, cgutils.true_bit) intp_t = context.get_value_type(types.intp) zero = ir.Constant(intp_t, 0) one = ir.Constant(intp_t, 1) payload_type = context.get_data_type(types.SetPayload(self._ty)) payload_size = context.get_abi_sizeof(payload_type) entry_size = self._entrysize # Account for the fact that the payload struct already contains an entry payload_size -= entry_size # Total allocation size = <payload header size> + nentries * entry_size allocsize, ovf = cgutils.muladd_with_overflow(builder, nentries, ir.Constant(intp_t, entry_size), 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): if realloc: meminfo = self._set.meminfo ptr = context.nrt.meminfo_varsize_alloc(builder, meminfo, size=allocsize) alloc_ok = cgutils.is_null(builder, ptr) else: meminfo = context.nrt.meminfo_new_varsize(builder, size=allocsize) alloc_ok = cgutils.is_null(builder, meminfo) 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: if not realloc: self._set.meminfo = meminfo self._set.parent = context.get_constant_null(types.pyobject) payload = self.payload # Initialize entries to 0xff (EMPTY) cgutils.memset(builder, payload.ptr, allocsize, 0xFF) payload.used = zero payload.fill = zero payload.finger = zero new_mask = builder.sub(nentries, one) payload.mask = new_mask if DEBUG_ALLOCS: context.printf(builder, "allocated %zd bytes for set at %p: mask = %zd\n", allocsize, payload.ptr, new_mask) return builder.load(ok)
def _allocate_payload(self, nentries, realloc=False): """ Allocate and initialize payload for the given number of entries. If *realloc* is True, the existing meminfo is reused. CAUTION: *nentries* must be a power of 2! """ context = self._context builder = self._builder ok = cgutils.alloca_once_value(builder, cgutils.true_bit) intp_t = context.get_value_type(types.intp) zero = ir.Constant(intp_t, 0) one = ir.Constant(intp_t, 1) payload_type = context.get_data_type(types.SetPayload(self._ty)) payload_size = context.get_abi_sizeof(payload_type) entry_size = self._entrysize # Account for the fact that the payload struct already contains an entry payload_size -= entry_size # Total allocation size = <payload header size> + nentries * entry_size allocsize, ovf = cgutils.muladd_with_overflow( builder, nentries, ir.Constant(intp_t, entry_size), 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): if realloc: meminfo = self._set.meminfo ptr = context.nrt.meminfo_varsize_alloc(builder, meminfo, size=allocsize) alloc_ok = cgutils.is_null(builder, ptr) else: meminfo = context.nrt.meminfo_new_varsize(builder, size=allocsize) alloc_ok = cgutils.is_null(builder, meminfo) 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: if not realloc: self._set.meminfo = meminfo self._set.parent = context.get_constant_null( types.pyobject) payload = self.payload # Initialize entries to 0xff (EMPTY) cgutils.memset(builder, payload.ptr, allocsize, 0xFF) payload.used = zero payload.fill = zero payload.finger = zero new_mask = builder.sub(nentries, one) payload.mask = new_mask if DEBUG_ALLOCS: context.printf( builder, "allocated %zd bytes for set at %p: mask = %zd\n", allocsize, payload.ptr, new_mask) return builder.load(ok)