def ll_join(s, length, items): s_chars = s.chars s_len = len(s_chars) num_items = length if num_items == 0: return s.empty() itemslen = 0 i = 0 while i < num_items: try: itemslen = ovfcheck(itemslen + len(items[i].chars)) except OverflowError: raise MemoryError i += 1 try: seplen = ovfcheck(s_len * (num_items - 1)) except OverflowError: raise MemoryError # a single '+' at the end is allowed to overflow: it gets # a negative result, and the gc will complain result = s.malloc(itemslen + seplen) res_index = len(items[0].chars) s.copy_contents(items[0], result, 0, 0, res_index) i = 1 while i < num_items: s.copy_contents(s, result, 0, res_index, s_len) res_index += s_len lgt = len(items[i].chars) s.copy_contents(items[i], result, 0, res_index, lgt) res_index += lgt i += 1 return result
def realloc(self, ptr, newlength, fixedsize, itemsize, lengthofs, grow): size_gc_header = self.size_gc_header() addr = llmemory.cast_ptr_to_adr(ptr) tid = self.get_type_id(addr) nonvarsize = size_gc_header + fixedsize try: varsize = ovfcheck(itemsize * newlength) tot_size = ovfcheck(nonvarsize + varsize) except OverflowError: raise MemoryError() oldlength = (addr + lengthofs).signed[0] old_tot_size = size_gc_header + fixedsize + oldlength * itemsize source_addr = addr - size_gc_header self.gen2_resizable_objects.remove(addr) if grow: result = llop.raw_realloc_grow(llmemory.Address, source_addr, old_tot_size, tot_size) else: result = llop.raw_realloc_shrink(llmemory.Address, source_addr, old_tot_size, tot_size) if not result: self.gen2_resizable_objects.append(addr) raise MemoryError() if grow: self.gen2_resizable_objects.append(result + size_gc_header) else: self.gen2_rawmalloced_objects.append(result + size_gc_header) self._check_rawsize_alloced(raw_malloc_usage(tot_size) - raw_malloc_usage(old_tot_size), can_collect = not grow) (result + size_gc_header + lengthofs).signed[0] = newlength return llmemory.cast_adr_to_ptr(result + size_gc_header, llmemory.GCREF)
def malloc_varsize_clear(self, typeid16, length, size, itemsize, offset_to_length, can_collect): if can_collect: self.maybe_collect() size_gc_header = self.gcheaderbuilder.size_gc_header try: fixsize = size_gc_header + size varsize = ovfcheck(itemsize * length) tot_size = ovfcheck(fixsize + varsize) usage = raw_malloc_usage(tot_size) bytes_malloced = ovfcheck(self.bytes_malloced+usage) ovfcheck(self.heap_usage + bytes_malloced) except OverflowError: raise memoryError result = raw_malloc(tot_size) if not result: raise memoryError raw_memclear(result, tot_size) (result + size_gc_header + offset_to_length).signed[0] = length hdr = llmemory.cast_adr_to_ptr(result, self.HDRPTR) hdr.typeid16 = typeid16 hdr.mark = False hdr.flags = '\x00' hdr.next = self.malloced_objects self.malloced_objects = hdr self.bytes_malloced = bytes_malloced result += size_gc_header #llop.debug_print(lltype.Void, 'malloc_varsize length', length, # 'typeid', typeid16, # '->', llmemory.cast_adr_to_int(result)) self.write_malloc_statistics(typeid16, tot_size, result, True) return llmemory.cast_adr_to_ptr(result, llmemory.GCREF)
def handle_new_array(self, arraydescr, op): v_length = op.getarg(0) total_size = -1 if isinstance(v_length, ConstInt): num_elem = v_length.getint() self.known_lengths[op.result] = num_elem try: var_size = ovfcheck(arraydescr.itemsize * num_elem) total_size = ovfcheck(arraydescr.basesize + var_size) except OverflowError: pass # total_size is still -1 elif arraydescr.itemsize == 0: total_size = arraydescr.basesize if (total_size >= 0 and self.gen_malloc_nursery(total_size, op.result)): self.gen_initialize_tid(op.result, arraydescr.tid) self.gen_initialize_len(op.result, v_length, arraydescr.lendescr) elif self.gc_ll_descr.kind == 'boehm': self.gen_boehm_malloc_array(arraydescr, v_length, op.result) else: opnum = op.getopnum() if opnum == rop.NEW_ARRAY: self.gen_malloc_array(arraydescr, v_length, op.result) elif opnum == rop.NEWSTR: self.gen_malloc_str(v_length, op.result) elif opnum == rop.NEWUNICODE: self.gen_malloc_unicode(v_length, op.result) else: raise NotImplementedError(op.getopname())
def _ll_compute_size(length, size, itemsize): try: varsize = ovfcheck(itemsize * length) tot_size = ovfcheck(size + varsize) except OverflowError: raise MemoryError() return tot_size
def unicode_expandtabs__Unicode_ANY(space, w_self, w_tabsize): self = w_self._value tabsize = space.int_w(w_tabsize) parts = _split_with(self, u'\t') result = [parts[0]] prevsize = 0 for ch in parts[0]: prevsize += 1 if ch == u"\n" or ch == u"\r": prevsize = 0 totalsize = prevsize for i in range(1, len(parts)): pad = tabsize - prevsize % tabsize nextpart = parts[i] try: totalsize = ovfcheck(totalsize + pad) totalsize = ovfcheck(totalsize + len(nextpart)) result.append(u' ' * pad) except OverflowError: raise OperationError(space.w_OverflowError, space.wrap('new string is too long')) result.append(nextpart) prevsize = 0 for ch in nextpart: prevsize += 1 if ch in (u"\n", u"\r"): prevsize = 0 return space.wrap(u''.join(result))
def _impl_int_int_pow(space, iv, iw, iz): if iw < 0: if iz != 0: raise OperationError(space.w_TypeError, space.wrap("pow() 2nd argument " "cannot be negative when 3rd argument specified")) ## bounce it, since it always returns float raise FailedToImplementArgs(space.w_ValueError, space.wrap("integer exponentiation")) temp = iv ix = 1 try: while iw > 0: if iw & 1: ix = ovfcheck(ix*temp) iw >>= 1 #/* Shift exponent down by 1 bit */ if iw==0: break temp = ovfcheck(temp*temp) #/* Square the value of temp */ if iz: #/* If we did a multiplication, perform a modulo */ ix = ix % iz; temp = temp % iz; if iz: ix = ix % iz except OverflowError: raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer exponentiation")) return ix
def malloc_fixedsize(self, typeid16, size, can_collect, has_finalizer=False, contains_weakptr=False): if can_collect: self.maybe_collect() size_gc_header = self.gcheaderbuilder.size_gc_header try: tot_size = size_gc_header + size usage = raw_malloc_usage(tot_size) bytes_malloced = ovfcheck(self.bytes_malloced+usage) ovfcheck(self.heap_usage + bytes_malloced) except OverflowError: raise memoryError result = raw_malloc(tot_size) if not result: raise memoryError hdr = llmemory.cast_adr_to_ptr(result, self.HDRPTR) hdr.typeid16 = typeid16 hdr.mark = False hdr.flags = '\x00' if has_finalizer: hdr.next = self.malloced_objects_with_finalizer self.malloced_objects_with_finalizer = hdr elif contains_weakptr: hdr.next = self.objects_with_weak_pointers self.objects_with_weak_pointers = hdr else: hdr.next = self.malloced_objects self.malloced_objects = hdr self.bytes_malloced = bytes_malloced result += size_gc_header #llop.debug_print(lltype.Void, 'malloc typeid', typeid16, # '->', llmemory.cast_adr_to_int(result)) self.write_malloc_statistics(typeid16, tot_size, result, False) return llmemory.cast_adr_to_ptr(result, llmemory.GCREF)
def malloc_varsize_slowpath(self, typeid, length, force_nonmovable=False): # For objects that are too large, or when the nursery is exhausted. # In order to keep malloc_varsize_clear() as compact as possible, # we recompute what we need in this slow path instead of passing # it all as function arguments. size_gc_header = self.gcheaderbuilder.size_gc_header nonvarsize = size_gc_header + self.fixed_size(typeid) itemsize = self.varsize_item_sizes(typeid) offset_to_length = self.varsize_offset_to_length(typeid) try: varsize = ovfcheck(itemsize * length) totalsize = ovfcheck(nonvarsize + varsize) except OverflowError: raise MemoryError() if self.has_gcptr_in_varsize(typeid): nonlarge_max = self.nonlarge_gcptrs_max else: nonlarge_max = self.nonlarge_max if force_nonmovable or raw_malloc_usage(totalsize) > nonlarge_max: result = self.malloc_varsize_marknsweep(totalsize) flags = self.GCFLAGS_FOR_NEW_EXTERNAL_OBJECTS | GCFLAG_UNVISITED else: result = self.malloc_varsize_collecting_nursery(totalsize) flags = self.GCFLAGS_FOR_NEW_YOUNG_OBJECTS self.init_gc_object(result, typeid, flags) (result + size_gc_header + offset_to_length).signed[0] = length return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
def can_inline_malloc_varsize(self, arraydescr, num_elem): assert isinstance(arraydescr, BaseArrayDescr) basesize = arraydescr.get_base_size(self.translate_support_code) itemsize = arraydescr.get_item_size(self.translate_support_code) try: size = ovfcheck(basesize + ovfcheck(itemsize * num_elem)) return size < self.max_size_of_young_obj except OverflowError: return False
def malloc_array(basesize, num_elem, itemsize, ofs_length): try: totalsize = ovfcheck(basesize + ovfcheck(itemsize * num_elem)) except OverflowError: return lltype.nullptr(llmemory.GCREF.TO) res = self.malloc_fn_ptr(totalsize) if res: arrayptr = rffi.cast(rffi.CArrayPtr(lltype.Signed), res) arrayptr[ofs_length/WORD] = num_elem return res
def ll_malloc_varsize_no_length(length, size, itemsize): try: varsize = ovfcheck(itemsize * length) tot_size = ovfcheck(size + varsize) except OverflowError: raise memoryError result = llop.boehm_malloc(llmemory.Address, tot_size) if not result: raise memoryError return result
def malloc_array(basesize, itemsize, ofs_length, num_elem): try: size = ovfcheck(basesize + ovfcheck(itemsize * num_elem)) except OverflowError: return lltype.nullptr(llmemory.GCREF.TO) res = self.funcptr_for_new(size) if not res: return res rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem return res
def f(x): try: a = ovfcheck(x + 50) except OverflowError: return 0 try: a += ovfcheck(100 + x) except OverflowError: return 1 return a
def ll_malloc_varsize_no_length(length, size, itemsize): try: fixsize = gc_header_offset + size varsize = ovfcheck(itemsize * length) tot_size = ovfcheck(fixsize + varsize) except OverflowError: raise MemoryError() result = mh._ll_malloc_fixedsize(tot_size) llmemory.raw_memclear(result, tot_size) result += gc_header_offset return result
def fn(x, y): res = -42 try: res = ovfcheck(x+y) except OverflowError: res = 0 try: res += ovfcheck(x+y) except OverflowError: res += 1 return res
def add(self, offset): res = self.clone() try: res.lower = ovfcheck(res.lower + offset) except OverflowError: res.has_lower = False try: res.upper = ovfcheck(res.upper + offset) except OverflowError: res.has_upper = False return res
def ll_malloc_varsize_no_length(length, size, itemsize): try: fixsize = gc_header_offset + size varsize = ovfcheck(itemsize * length) tot_size = ovfcheck(fixsize + varsize) except OverflowError: raise memoryError result = lladdress.raw_malloc(tot_size) if not result: raise memoryError lladdress.raw_memclear(result, tot_size) result += gc_header_offset return result
def f(x, y, n): m = 0 while n < 100: myjitdriver.can_enter_jit(n=n, x=x, y=y, m=m) myjitdriver.jit_merge_point(n=n, x=x, y=y, m=m) y += 1 y &= (LONG_BIT-1) try: ovfcheck(x<<y) except OverflowError: m += 1 n += 1 return m
def f(y, n): m = 0 while n < 115: myjitdriver.can_enter_jit(n=n, y=y, m=m) myjitdriver.jit_merge_point(n=n, y=y, m=m) y -= 1 try: ovfcheck(-y) except OverflowError: m += 1 y += 1 n += 1 return m
def mul_bound(self, other): if self.has_upper and self.has_lower and \ other.has_upper and other.has_lower: try: vals = (ovfcheck(self.upper * other.upper), ovfcheck(self.upper * other.lower), ovfcheck(self.lower * other.upper), ovfcheck(self.lower * other.lower)) return IntBound(min4(vals), max4(vals)) except OverflowError: return IntUnbounded() else: return IntUnbounded()
def f(x, y): i = 0 while i < 10: myjitdriver.can_enter_jit(x=x, y=y, i=i) myjitdriver.jit_merge_point(x=x, y=y, i=i) try: ovfcheck(i%x) i += 1 except ZeroDivisionError: i += 1 except OverflowError: i += 2 return 0
def div_bound(self, other): if self.has_upper and self.has_lower and \ other.has_upper and other.has_lower and \ not other.contains(0): try: vals = (ovfcheck(self.upper / other.upper), ovfcheck(self.upper / other.lower), ovfcheck(self.lower / other.upper), ovfcheck(self.lower / other.lower)) return IntBound(min4(vals), max4(vals)) except OverflowError: return IntUnbounded() else: return IntUnbounded()
def _unicode_replace(space, w_self, old, new, w_maxsplit): if len(old): parts = _split_with(w_self._value, old, space.int_w(w_maxsplit)) else: self = w_self._value maxsplit = space.int_w(w_maxsplit) parts = _split_into_chars(self, maxsplit) try: one = ovfcheck(len(parts) * len(new)) ovfcheck(one + len(w_self._value)) except OverflowError: raise OperationError(space.w_OverflowError, space.wrap("replace string is too long")) return W_UnicodeObject(new.join(parts))
def stringbuilder_grow(ll_builder, needed): allocated = ll_builder.allocated #if allocated < GROW_FAST_UNTIL: # new_allocated = allocated << 1 #else: extra_size = allocated >> 2 try: new_allocated = ovfcheck(allocated + extra_size) new_allocated = ovfcheck(new_allocated + needed) except OverflowError: raise MemoryError newbuf = mallocfn(new_allocated) copycontentsfn(ll_builder.buf, newbuf, 0, 0, ll_builder.allocated) ll_builder.buf = newbuf ll_builder.allocated = new_allocated
def lshift_bound(self, other): if self.has_upper and self.has_lower and \ other.has_upper and other.has_lower and \ other.known_ge(IntBound(0, 0)) and \ other.known_lt(IntBound(LONG_BIT, LONG_BIT)): try: vals = (ovfcheck(self.upper << other.upper), ovfcheck(self.upper << other.lower), ovfcheck(self.lower << other.upper), ovfcheck(self.lower << other.lower)) return IntBound(min4(vals), max4(vals)) except (OverflowError, ValueError): return IntUnbounded() else: return IntUnbounded()
def b2a_base64(space, bin): "Base64-code line of data." newlength = (len(bin) + 2) // 3 try: newlength = ovfcheck(newlength * 4) except OverflowError: raise OperationError(space.w_MemoryError, space.w_None) newlength += 1 res = StringBuilder(newlength) leftchar = 0 leftbits = 0 for c in bin: # Shift into our buffer, and output any 6bits ready leftchar = (leftchar << 8) | ord(c) leftbits += 8 res.append(table_b2a_base64[(leftchar >> (leftbits-6)) & 0x3f]) leftbits -= 6 if leftbits >= 6: res.append(table_b2a_base64[(leftchar >> (leftbits-6)) & 0x3f]) leftbits -= 6 # if leftbits == 2: res.append(table_b2a_base64[(leftchar & 3) << 4]) res.append(PAD) res.append(PAD) elif leftbits == 4: res.append(table_b2a_base64[(leftchar & 0xf) << 2]) res.append(PAD) res.append('\n') return space.wrap(res.build())
def mod_ovf_zer(x, y): try: return ovfcheck(x%y) except OverflowError: return 42 except ZeroDivisionError: return 84
def fn(x, y): try: return ovfcheck(x % y) except OverflowError: return -1 except ZeroDivisionError: return -2
def mod_func(i=numtype): try: return ovfcheck((-maxint-1) % i) except OverflowError: raise except ZeroDivisionError: raise
def div_ovf(x, y): try: return ovfcheck(x // y) except OverflowError: return 42
def abs_ovf(x): return ovfcheck(abs(x))
def func(interp, receiver, argument): try: res = rarithmetic.ovfcheck(op(receiver, argument)) except OverflowError: raise PrimitiveFailedError() return interp.space.wrap_int(res)
def g(x): try: return ovfcheck(abs(x)) except OverflowError: return 42
def f(x): try: return ovfcheck(sys.maxint + x) except OverflowError: return 1
def fn(x, y): try: return ovfcheck(x << y) except OverflowError: return 42
def f(x, y): try: return ovfcheck(x + y) except OverflowError: return -42
def unary_func(i=numtype): try: return ovfcheck(-i), ovfcheck(abs(i - 1)) except: raise
str = "".join([s[start + i*step] for i in range(sl)]) return wrapstr(space, str) def mul_string_times(space, w_str, w_times): try: mul = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement raise if mul <= 0: return W_StringObject.EMPTY input = w_str._value input_len = len(input) try: buflen = ovfcheck(mul * input_len) except OverflowError: raise OperationError( space.w_OverflowError, space.wrap("repeated string is too long: %d %d" % (input_len, mul))) # XXX maybe only do this when input has a big length return joined(space, [input] * mul) def mul__String_ANY(space, w_str, w_times): return mul_string_times(space, w_str, w_times) def mul__ANY_String(space, w_times, w_str): return mul_string_times(space, w_str, w_times) def add__String_String(space, w_left, w_right): right = w_right._value
def mod_ovf(x, y): try: return ovfcheck(x % y) except OverflowError: return 42
def f(x): try: return ovfcheck(op(x)) except OverflowError: return 0
def gallop(self, key, a, hint, rightmost): assert 0 <= hint < a.len if rightmost: lower = self.le # search for the largest k for which a[k] <= key else: lower = self.lt # search for the largest k for which a[k] < key p = a.base + hint lastofs = 0 ofs = 1 if lower(a.list[p], key): # a[hint] < key -- gallop right, until # a[hint + lastofs] < key <= a[hint + ofs] maxofs = a.len - hint # a[a.len-1] is highest while ofs < maxofs: if lower(a.list[p + ofs], key): lastofs = ofs try: ofs = ovfcheck(ofs << 1) except OverflowError: ofs = maxofs else: ofs = ofs + 1 else: # key <= a[hint + ofs] break if ofs > maxofs: ofs = maxofs # Translate back to offsets relative to a. lastofs += hint ofs += hint else: # key <= a[hint] -- gallop left, until # a[hint - ofs] < key <= a[hint - lastofs] maxofs = hint + 1 # a[0] is lowest while ofs < maxofs: if lower(a.list[p - ofs], key): break else: # key <= a[hint - ofs] lastofs = ofs try: ofs = ovfcheck(ofs << 1) except OverflowError: ofs = maxofs else: ofs = ofs + 1 if ofs > maxofs: ofs = maxofs # Translate back to positive offsets relative to a. lastofs, ofs = hint - ofs, hint - lastofs assert -1 <= lastofs < ofs <= a.len # Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the # right of lastofs but no farther right than ofs. Do a binary # search, with invariant a[lastofs-1] < key <= a[ofs]. lastofs += 1 while lastofs < ofs: m = lastofs + ((ofs - lastofs) >> 1) if lower(a.list[a.base + m], key): lastofs = m + 1 # a[m] < key else: ofs = m # key <= a[m] assert lastofs == ofs # so a[ofs-1] < key <= a[ofs] return ofs
def add_ovf(x, y): return ovfcheck(x + y)
def f2(n): try: return ovfcheck(n+1) except OverflowError: raise
def neg_ovf(x): return ovfcheck(-x)
def neg_int_ovf(n): try: r = ovfcheck(-n) except OverflowError: return 123 return r
def lshift_ovf(x, y): return ovfcheck(x << y)
def test_protected_div_mod(self): def div_unpro(x, y): return x // y def div_ovf(x, y): try: return ovfcheck(x // y) except OverflowError: return 42 def div_zer(x, y): try: return x // y except ZeroDivisionError: return 84 def div_ovf_zer(x, y): try: return ovfcheck(x // y) except OverflowError: return 42 except ZeroDivisionError: return 84 def mod_unpro(x, y): return x % y def mod_ovf(x, y): try: return ovfcheck(x % y) except OverflowError: return 42 def mod_zer(x, y): try: return x % y except ZeroDivisionError: return 84 def mod_ovf_zer(x, y): try: return ovfcheck(x % y) except OverflowError: return 42 except ZeroDivisionError: return 84 for inttype in (int, r_int64): args = [(5, 2), (-5, 2), (5, -2), (-5, -2), (6, 2), (-6, 2), (6, -2), (-6, -2), (-sys.maxint, -1), (4, 0)] funcs = [ div_unpro, div_ovf, div_zer, div_ovf_zer, mod_unpro, mod_ovf, mod_zer, mod_ovf_zer ] for func in funcs: print func if 'ovf' in func.func_name and inttype is r_longlong: continue # don't have many llong_*_ovf operations... for x, y in args: x, y = inttype(x), inttype(y) try: res1 = func(x, y) if isinstance(res1, int): res1 = ovfcheck(res1) except (OverflowError, ZeroDivisionError): continue res2 = self.interpret(func, [x, y]) assert res1 == res2
def abs_int_ovf(n): try: r = ovfcheck(abs(n)) except OverflowError: return 123 return r
def mod_ovf(x, y): return ovfcheck(x % y)
def sub_func(i): try: return ovfcheck(i - 1) except OverflowError: return 123
def div_ovf(x, y): return ovfcheck(operator.div(x, y))
def add_func(i): try: return ovfcheck(i + 1) except OverflowError: return 123
def floordiv_ovf(x, y): return ovfcheck(operator.floordiv(x, y))
def g(i, j): return ovfcheck(i + j)
def mul_ovf(x, y): return ovfcheck(x * y)
def f(i, j): try: return ovfcheck(i + j) except OverflowError: return 42
def sub_ovf(x, y): return ovfcheck(x - y)
def fn(x): try: return ovfcheck(x + 1) # special 'int_add_nonneg_ovf' operation except OverflowError: return 42
r = u"".join([uni[start + i*step] for i in range(sl)]) return W_UnicodeObject(r) def mul__Unicode_ANY(space, w_uni, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): raise FailedToImplement raise uni = w_uni._value length = len(uni) if times <= 0 or length == 0: return W_UnicodeObject.EMPTY try: result_size = ovfcheck(length * times) result = u''.join([uni] * times) except (OverflowError, MemoryError): raise OperationError(space.w_OverflowError, space.wrap('repeated string is too long')) return W_UnicodeObject(result) def mul__ANY_Unicode(space, w_times, w_uni): return mul__Unicode_ANY(space, w_uni, w_times) def _isspace(uchar): return unicodedb.isspace(ord(uchar)) def make_generic(funcname): def func(space, w_self): v = w_self._value if len(v) == 0: