def test_forced_ptr_cast(self): import array A = lltype.Array(lltype.Signed, hints={'nolength': True}) B = lltype.Array(lltype.Char, hints={'nolength': True}) a = lltype.malloc(A, 10, flavor='raw') for i in range(10): a[i] = i * i b = rffi.cast(lltype.Ptr(B), a) checker = array.array('l') for i in range(10): checker.append(i * i) expected = checker.tostring() for i in range(len(expected)): assert b[i] == expected[i] c = rffi.cast(rffi.VOIDP, a) addr = lltype2ctypes(c) #assert addr == ctypes.addressof(a._obj._ctypes_storage) d = ctypes2lltype(rffi.VOIDP, addr) assert lltype.typeOf(d) == rffi.VOIDP assert c == d e = rffi.cast(lltype.Ptr(A), d) for i in range(10): assert e[i] == i * i c = lltype.nullptr(rffi.VOIDP.TO) addr = rffi.cast(lltype.Signed, c) assert addr == 0 lltype.free(a, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
def finish_tables(self): table = self.layoutbuilder.flatten_table() log.info("assigned %s typeids" % (len(table), )) log.info("added %s push/pop stack root instructions" % (self.num_pushs, )) if self.write_barrier_ptr: log.info("inserted %s write barrier calls" % (self.write_barrier_calls, )) # replace the type_info_table pointer in gcdata -- at this point, # the database is in principle complete, so it has already seen # the delayed pointer. We need to force it to consider the new # array now. self.gcdata.type_info_table._become(table) # XXX because we call inputconst already in replace_malloc, we can't # modify the instance, we have to modify the 'rtyped instance' # instead. horrors. is there a better way? s_gcdata = self.translator.annotator.bookkeeper.immutablevalue( self.gcdata) r_gcdata = self.translator.rtyper.getrepr(s_gcdata) ll_instance = rmodel.inputconst(r_gcdata, self.gcdata).value addresses_of_static_ptrs = ( self.layoutbuilder.addresses_of_static_ptrs_in_nongc + self.layoutbuilder.addresses_of_static_ptrs) log.info("found %s static roots" % (len(addresses_of_static_ptrs), )) additional_ptrs = self.layoutbuilder.additional_roots_sources log.info("additional %d potential static roots" % additional_ptrs) ll_static_roots_inside = lltype.malloc(lltype.Array(llmemory.Address), len(addresses_of_static_ptrs) + additional_ptrs, immortal=True) for i in range(len(addresses_of_static_ptrs)): ll_static_roots_inside[i] = addresses_of_static_ptrs[i] ll_instance.inst_static_root_start = llmemory.cast_ptr_to_adr( ll_static_roots_inside) + llmemory.ArrayItemsOffset( lltype.Array(llmemory.Address)) ll_instance.inst_static_root_nongcend = ll_instance.inst_static_root_start + llmemory.sizeof( llmemory.Address) * len( self.layoutbuilder.addresses_of_static_ptrs_in_nongc) ll_instance.inst_static_root_end = ll_instance.inst_static_root_start + llmemory.sizeof( llmemory.Address) * len(addresses_of_static_ptrs) newgcdependencies = [] newgcdependencies.append(ll_static_roots_inside) self.write_typeid_list() return newgcdependencies
def test_array_type_bug(self): A = lltype.Array(lltype.Signed) a1 = lltype.malloc(A, 0, flavor='raw') a2 = lltype.malloc(A, 0, flavor='raw') c1 = lltype2ctypes(a1) c2 = lltype2ctypes(a2) assert type(c1) is type(c2)
def test_arrayofstruct(self): S1 = lltype.Struct('S1', ('x', lltype.Signed)) A = lltype.Array(S1, hints={'nolength': True}) a = lltype.malloc(A, 5, flavor='raw') a[0].x = 100 a[1].x = 101 a[2].x = 102 a[3].x = 103 a[4].x = 104 ac = lltype2ctypes(a, normalize=False) assert ac.contents.items[0].x == 100 assert ac.contents.items[2].x == 102 ac.contents.items[3].x += 500 assert a[3].x == 603 a[4].x += 600 assert ac.contents.items[4].x == 704 a1 = ctypes2lltype(lltype.Ptr(A), ac) assert a1 == a assert a1[2].x == 102 aitem1 = ctypes2lltype(lltype.Ptr(S1), ctypes.pointer(ac.contents.items[1])) assert aitem1.x == 101 assert aitem1 == a1[1] lltype.free(a, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
def define_hash_preservation(cls): from pypy.rlib.objectmodel import compute_hash from pypy.rlib.objectmodel import compute_identity_hash from pypy.rlib.objectmodel import current_object_addr_as_int class C: pass class D(C): pass c = C() d = D() h_d = compute_hash(d) # force to be cached on 'd', but not on 'c' h_t = compute_hash(("Hi", None, (7.5, 2, d))) S = lltype.GcStruct('S', ('x', lltype.Signed), ('a', lltype.Array(lltype.Signed))) s = lltype.malloc(S, 15, zero=True) h_s = compute_identity_hash(s) # varsized: hash not saved/restored # def f(): if compute_hash(c) != compute_identity_hash(c): return 12 if compute_hash(d) != h_d: return 13 if compute_hash(("Hi", None, (7.5, 2, d))) != h_t: return 14 c2 = C() h_c2 = compute_hash(c2) if compute_hash(c2) != h_c2: return 15 if compute_identity_hash(s) == h_s: return 16 # unlikely i = 0 while i < 6: rgc.collect() if compute_hash(c2) != h_c2: return i i += 1 return 42 return f
def __init__(self, hrtyper): self.hrtyper = hrtyper RGenOp = hrtyper.RGenOp rtyper = hrtyper.rtyper bk = rtyper.annotator.bookkeeper s_w_bool = annmodel.unionof(bk.immutablevalue(W_BoolObject.w_False), bk.immutablevalue(W_BoolObject.w_True)) r_w_bool = rtyper.getrepr(s_w_bool) self.ll_False = r_w_bool.convert_const(W_BoolObject.w_False) self.ll_True = r_w_bool.convert_const(W_BoolObject.w_True) A = lltype.Array(lltype.typeOf(self.ll_False)) self.ll_bools = lltype.malloc(A, 2, immortal=True) self.ll_bools[0] = self.ll_False self.ll_bools[1] = self.ll_True self.gv_bools = RGenOp.constPrebuiltGlobal(self.ll_bools) self.boolsToken = RGenOp.arrayToken(A) self.bools_gv = [ RGenOp.constPrebuiltGlobal(self.ll_False), RGenOp.constPrebuiltGlobal(self.ll_True) ] self.ptrkind = RGenOp.kindToken(r_w_bool.lowleveltype) self.boolkind = RGenOp.kindToken(lltype.Bool) ll_BoolObject = r_w_bool.rclass.getvtable() self.BoolObjectBox = rvalue.redbox_from_prebuilt_value( RGenOp, ll_BoolObject) self.Falsebox = rvalue.redbox_from_prebuilt_value(RGenOp, False) self.Truebox = rvalue.redbox_from_prebuilt_value(RGenOp, True) self.boolboxes = [self.Falsebox, self.Truebox]
def define_cloning_varsize(cls): B = lltype.GcStruct('B', ('x', lltype.Signed)) A = lltype.GcStruct('A', ('b', lltype.Ptr(B)), ('more', lltype.Array(lltype.Ptr(B)))) def make(n): b = lltype.malloc(B) b.x = n a = lltype.malloc(A, 2) a.b = b a.more[0] = lltype.malloc(B) a.more[0].x = n*10 a.more[1] = lltype.malloc(B) a.more[1].x = n*10+1 return a def func(): oldpool = llop.gc_x_swap_pool(X_POOL_PTR, lltype.nullptr(X_POOL)) a2 = make(22) newpool = llop.gc_x_swap_pool(X_POOL_PTR, oldpool) # clone a2 a2ref = lltype.cast_opaque_ptr(llmemory.GCREF, a2) clonedata = lltype.malloc(X_CLONE) clonedata.gcobjectptr = a2ref clonedata.pool = newpool llop.gc_x_clone(lltype.Void, clonedata) a2copyref = clonedata.gcobjectptr a2copy = lltype.cast_opaque_ptr(lltype.Ptr(A), a2copyref) a2copy.b.x = 44 a2copy.more[0].x = 440 a2copy.more[1].x = 441 return a2.b.x * 1000000 + a2.more[0].x * 1000 + a2.more[1].x return func
def test_carray_to_ll(self): A = lltype.Array(lltype.Signed, hints={'nolength': True}) a = lltype.malloc(A, 10, flavor='raw') a2 = lltype.malloc(A, 10, flavor='raw') a[0] = 100 a[1] = 101 a[2] = 110 ac = lltype2ctypes(a) b = ctypes2lltype(lltype.Ptr(A), ac) assert lltype.typeOf(b) == lltype.Ptr(A) assert b == a assert not (b != a) assert a == b assert not (a != b) assert b != lltype.nullptr(A) assert not (b == lltype.nullptr(A)) assert lltype.nullptr(A) != b assert not (lltype.nullptr(A) == b) assert b != a2 assert not (b == a2) assert a2 != b assert not (a2 == b) assert b[2] == 110 b[2] *= 2 assert a[2] == 220 a[2] *= 3 assert b[2] == 660 lltype.free(a, flavor='raw') lltype.free(a2, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
def test_qsort(self): CMPFUNC = lltype.FuncType([rffi.VOIDP, rffi.VOIDP], rffi.INT) qsort = rffi.llexternal( 'qsort', [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, lltype.Ptr(CMPFUNC)], lltype.Void) lst = [23, 43, 24, 324, 242, 34, 78, 5, 3, 10] A = lltype.Array(lltype.Signed, hints={'nolength': True}) a = lltype.malloc(A, 10, flavor='raw') for i in range(10): a[i] = lst[i] SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1)) def my_compar(p1, p2): p1 = rffi.cast(SIGNEDPTR, p1) p2 = rffi.cast(SIGNEDPTR, p2) print 'my_compar:', p1[0], p2[0] return rffi.cast(rffi.INT, cmp(p1[0], p2[0])) qsort(rffi.cast(rffi.VOIDP, a), rffi.cast(rffi.SIZE_T, 10), rffi.cast(rffi.SIZE_T, llmemory.sizeof(lltype.Signed)), llhelper(lltype.Ptr(CMPFUNC), my_compar)) for i in range(10): print a[i], print lst.sort() for i in range(10): assert a[i] == lst[i] lltype.free(a, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
class StringBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(STRINGBUILDER) basetp = STR mallocfn = staticmethod(rstr.mallocstr) string_repr = string_repr char_repr = char_repr raw_ptr_repr = PtrRepr( lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True})))
class UnicodeBuilderRepr(BaseStringBuilderRepr): lowleveltype = lltype.Ptr(UNICODEBUILDER) basetp = UNICODE mallocfn = staticmethod(rstr.mallocunicode) string_repr = unicode_repr char_repr = unichar_repr raw_ptr_repr = PtrRepr( lltype.Ptr(lltype.Array(lltype.UniChar, hints={'nolength': True})))
def test_interior_ptr_with_field_and_index(self): py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(x): t = lltype.malloc(T, 1) t.items[0].x = x return t.items[0].x graph = self.check(f, [int], [42], 42)
def test_sizeof_array_with_no_length(): A = lltype.Array(lltype.Signed, hints={'nolength': True}) arraysize = llmemory.sizeof(A, 10) signedsize = llmemory.sizeof(lltype.Signed) def f(): return arraysize-signedsize*10 fn, t = getcompiled(f, []) res = fn() assert res == 0
def define_hash_varsized(self): S = lltype.GcStruct('S', ('abc', lltype.Signed), ('def', lltype.Array(lltype.Signed))) s = lltype.malloc(S, 3, zero=True) h_s = lltype.identityhash(s) def f(): return lltype.identityhash(s) - h_s # != 0 (so far), # because S is a varsized structure. return f
def test_varsized_struct(self): STR = lltype.Struct( 'rpy_string', ('hash', lltype.Signed), ('chars', lltype.Array(lltype.Char, hints={'immutable': True}))) s = lltype.malloc(STR, 3, flavor='raw') one = force_cast(rffi.VOIDP, s) # sanity check #assert lltype2ctypes(one).contents.items._length_ > 0 two = force_cast(lltype.Ptr(STR), one) assert s == two
def test_array_type_bug(self): A = lltype.Array(lltype.Signed) a1 = lltype.malloc(A, 0, flavor='raw') a2 = lltype.malloc(A, 0, flavor='raw') c1 = lltype2ctypes(a1) c2 = lltype2ctypes(a2) assert type(c1) is type(c2) lltype.free(a1, flavor='raw') lltype.free(a2, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
def test_interior_ptr_with_field_and_index(self): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(x): t = lltype.malloc(T, 1) t.items[0].x = x return t.items[0].x graph = self.check(f, [int], [42], 42)
def test_realloc(): A = lltype.Array(lltype.Float) adr = raw_malloc(sizeof(A, 10)) ptr = cast_adr_to_ptr(adr, lltype.Ptr(A)) for i in range(10): ptr[i] = float(i) adr2 = raw_realloc_shrink(adr, sizeof(A, 10), sizeof(A, 5)) ptr2 = cast_adr_to_ptr(adr2, lltype.Ptr(A)) assert len(ptr2) == 5 assert ptr2[3] == 3.0 assert ptr2[1] == 1.0
def test_addr_keeps_object_alive(): A = lltype.Array(Address) ptr = lltype.malloc(A, 10, immortal=True) adr = cast_ptr_to_adr(ptr) + ArrayItemsOffset(A) del ptr import gc gc.collect() gc.collect() # the following line crashes if the array is dead ptr1 = cast_adr_to_ptr(adr, lltype.Ptr(lltype.FixedSizeArray(Address, 1))) ptr1[0] = NULL
def test_varsized_struct_size(): S1 = lltype.GcStruct('S1', ('parent', S), ('extra', lltype.Signed), ('chars', lltype.Array(lltype.Char))) size_parent = get_size(S, False) ofs_extra, size_extra = get_field_token(S1, 'extra', False) basesize, itemsize, ofs_length = get_array_token(S1, False) assert size_parent == ofs_extra assert size_extra == WORD assert ofs_length == ofs_extra + WORD assert basesize == ofs_length + WORD assert itemsize == 1
def test_sizeof(): # this is mostly an "assert not raises" sort of test array = lltype.Array(lltype.Signed) struct = lltype.Struct("S", ('x', lltype.Signed)) varstruct = lltype.Struct("S", ('x', lltype.Signed), ('y', array)) sizeof(struct) sizeof(lltype.Signed) py.test.raises(AssertionError, "sizeof(array)") py.test.raises(AssertionError, "sizeof(varstruct)") sizeof(array, 1) sizeof(varstruct, 2)
def test_wrong_args(self): # so far the test passes but for the wrong reason :-), i.e. because # .arg() only supports integers and floats chain = ArgChain() x = lltype.malloc(lltype.GcStruct('xxx')) y = lltype.malloc(lltype.GcArray(rffi.SIGNED), 3) z = lltype.malloc(lltype.Array(rffi.SIGNED), 4, flavor='raw') py.test.raises(TypeError, "chain.arg(x)") py.test.raises(TypeError, "chain.arg(y)") py.test.raises(TypeError, "chain.arg(z)") lltype.free(z, flavor='raw')
def test_shrink_obj(): from pypy.rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('HDR', ('h', lltype.Signed)) gcheaderbuilder = GCHeaderBuilder(HDR) size_gc_header = gcheaderbuilder.size_gc_header S = lltype.GcStruct('S', ('x', lltype.Signed), ('a', lltype.Array(lltype.Signed))) myarenasize = 200 a = arena_malloc(myarenasize, False) arena_reserve(a, size_gc_header + llmemory.sizeof(S, 10)) arena_shrink_obj(a, size_gc_header + llmemory.sizeof(S, 5)) arena_reset(a, size_gc_header + llmemory.sizeof(S, 5), False)
def test_ll_shrink_array_2(): S = lltype.GcStruct('S', ('x', lltype.Signed), ('vars', lltype.Array(lltype.Signed))) s1 = lltype.malloc(S, 5) s1.x = 1234 for i in range(5): s1.vars[i] = 50 + i s2 = rgc.ll_shrink_array(s1, 3) assert lltype.typeOf(s2) == lltype.Ptr(S) assert s2.x == 1234 assert len(s2.vars) == 3 for i in range(3): assert s2.vars[i] == 50 + i
def test_array_inside_struct(self): # like rstr.STR, but not Gc STR = lltype.Struct('STR', ('x', lltype.Signed), ('y', lltype.Array(lltype.Char))) a = lltype.malloc(STR, 3, flavor='raw') a.y[0] = 'x' a.y[1] = 'y' a.y[2] = 'z' ac = lltype2ctypes(a) assert ac.contents.y.length == 3 assert ac.contents.y.items[2] == ord('z') lltype.free(a, flavor='raw') assert not ALLOCATED
def test_cast_void_ptr(self): TP = lltype.Array(lltype.Float, hints={"nolength": True}) VOID_TP = lltype.Array(lltype.Void, hints={ "nolength": True, "uncast_on_llgraph": True }) class A(object): def __init__(self, x): self.storage = rffi.cast(lltype.Ptr(VOID_TP), x) def f(n): x = lltype.malloc(TP, n, flavor="raw", zero=True) a = A(x) s = 0.0 rffi.cast(lltype.Ptr(TP), a.storage)[0] = 1.0 s += rffi.cast(lltype.Ptr(TP), a.storage)[0] lltype.free(x, flavor="raw") return s res = self.interp_operations(f, [10])
def test_wrong_args(self): libc = CDLL('libc.so.6') # XXX assume time_t is long ctime = libc.getpointer('time', [ffi_type_pointer], ffi_type_ulong) x = lltype.malloc(lltype.GcStruct('xxx')) y = lltype.malloc(lltype.GcArray(rffi.LONG), 3) z = lltype.malloc(lltype.Array(rffi.LONG), 4, flavor='raw') py.test.raises(ValueError, "ctime.push_arg(x)") py.test.raises(ValueError, "ctime.push_arg(y)") py.test.raises(ValueError, "ctime.push_arg(z)") del ctime del libc lltype.free(z, flavor='raw')
def setup(): """ creates necessary c-level types """ names = populate_inttypes() result = [] for name in names: tp = platform.types[name.upper()] globals()['r_' + name] = platform.numbertype_to_rclass[tp] globals()[name.upper()] = tp tpp = lltype.Ptr(lltype.Array(tp, hints={'nolength': True})) globals()[name.upper()+'P'] = tpp result.append(tp) return result
def test_raw_malloc_varsize(): A = lltype.Array(lltype.Signed) S = lltype.Struct('S', ('x', lltype.Signed), ('y', A)) adr = raw_malloc(offsetof(S, 'y') + itemoffsetof(A, 10)) length_adr = adr + offsetof(S, 'y') + ArrayLengthOffset(A) length_adr.signed[0] = 10 p = cast_adr_to_ptr(adr, lltype.Ptr(S)) p.y[7] = 5 assert (adr + offsetof(S, 'y') + itemoffsetof(A, 7)).signed[0] == 5 (adr + offsetof(S, 'y') + itemoffsetof(A, 7)).signed[0] = 18187 assert p.y[7] == 18187 py.test.raises(IndexError, "(adr + offsetof(S, 'y') + itemoffsetof(A, 10)).signed[0]")
def test_realloc_struct(): S = lltype.Struct('x', ('one', lltype.Signed), ('a', lltype.Array(lltype.Float))) adr = raw_malloc(sizeof(S, 5)) ptr = cast_adr_to_ptr(adr, lltype.Ptr(S)) for i in range(5): ptr.a[i] = float(i) ptr.one = 3 adr2 = raw_realloc_grow(adr, sizeof(S, 5), sizeof(S, 10)) ptr2 = cast_adr_to_ptr(adr2, lltype.Ptr(S)) assert len(ptr2.a) == 10 assert ptr2.a[3] == 3.0 assert ptr2.a[0] == 0.0 assert ptr2.one == 3