def test_structcopy(self): X2 = lltype.Struct('X2', ('x', SIGNED)) X1 = lltype.Struct('X1', ('a', SIGNED), ('x2', X2), ('p', lltype.Ptr(X2))) def f(): p2 = make(X2, x=123) p1 = make(X1, a=5, p=p2) p1.x2.x = 456 p1bis = make(X1) p2bis = make(X2) structcopy(p1bis, p1) assert p1bis.a == 5 assert p1bis.x2.x == 456 assert p1bis.p == p2 structcopy(p2bis, p2) res = p2bis.x lltype.free(p2bis, flavor='raw') lltype.free(p1bis, flavor='raw') lltype.free(p2, flavor='raw') lltype.free(p1, flavor='raw') return res assert f() == 123 res = interpret(f, []) assert res == 123
def test_interior_ptr_with_index_and_field(self): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.Struct("T", ('s', S)) U = lltype.GcArray(T) def f(x): u = lltype.malloc(U, 1) u[0].s.x = x return u[0].s.x graph = self.check(f, [int], [42], 42)
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_interior_ptr_with_index_and_field(): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.Struct("T", ('s', S)) U = lltype.GcArray(T) def f(): u = lltype.malloc(U, 1) u[0].s.x = 1 return u[0].s.x res = interpret(f, []) assert res == 1
def test_interior_ptr_with_index_and_field(self): py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.Struct("T", ('s', S)) U = lltype.GcArray(T) def f(x): u = lltype.malloc(U, 1) u[0].s.x = x return u[0].s.x graph = self.check(f, [int], [42], 42)
def test_raw_free_with_hdr(): from rpython.memory.gcheader import GCHeaderBuilder HDR = lltype.Struct('h', ('t', lltype.Signed)) gh = GCHeaderBuilder(HDR).size_gc_header A = lltype.GcArray(lltype.Signed) adr = raw_malloc(gh + sizeof(A, 10)) p_a = cast_adr_to_ptr(adr + gh, lltype.Ptr(A)) p_a[0] = 1 adr = cast_ptr_to_adr(p_a) - gh raw_free(adr) py.test.raises(RuntimeError, "p_a[0]") py.test.raises(RuntimeError, "p_a[0] = 2") repr(adr) str(p_a) S = lltype.GcStruct('S', ('x', lltype.Signed)) adr = raw_malloc(gh + sizeof(S)) p_s = cast_adr_to_ptr(adr + gh, lltype.Ptr(S)) p_s.x = 1 adr = cast_ptr_to_adr(p_s) - gh raw_free(adr) py.test.raises(RuntimeError, "p_s.x") py.test.raises(RuntimeError, "p_s.x = 2") repr(adr) str(p_s) T = lltype.GcStruct('T', ('s', S)) adr = raw_malloc(gh + sizeof(T)) p_s = cast_adr_to_ptr(adr + gh, lltype.Ptr(S)) p_s.x = 1 adr = cast_ptr_to_adr(p_s) - gh raw_free(adr) py.test.raises(RuntimeError, "p_s.x") py.test.raises(RuntimeError, "p_s.x = 2") repr(adr) str(p_s) U = lltype.Struct('U', ('y', lltype.Signed)) T = lltype.GcStruct('T', ('x', lltype.Signed), ('u', U)) adr = raw_malloc(gh + sizeof(T)) p_t = cast_adr_to_ptr(adr + gh, lltype.Ptr(T)) p_u = p_t.u p_u.y = 1 adr = cast_ptr_to_adr(p_t) - gh raw_free(adr) py.test.raises(RuntimeError, "p_u.y") py.test.raises(RuntimeError, "p_u.y = 2") repr(adr) str(p_u)
def test_prebuilt_list_of_addresses(self): from rpython.rtyper.lltypesystem import llmemory TP = lltype.Struct('x', ('y', lltype.Signed)) a = lltype.malloc(TP, flavor='raw', immortal=True) b = lltype.malloc(TP, flavor='raw', immortal=True) c = lltype.malloc(TP, flavor='raw', immortal=True) a_a = llmemory.cast_ptr_to_adr(a) a0 = llmemory.cast_ptr_to_adr(a) assert a_a is not a0 assert a_a == a0 a_b = llmemory.cast_ptr_to_adr(b) a_c = llmemory.cast_ptr_to_adr(c) d = self.newdict() d[a_a] = 3 d[a_b] = 4 d[a_c] = 5 d[a0] = 8 def func(i): if i == 0: ptr = a else: ptr = b return d[llmemory.cast_ptr_to_adr(ptr)] py.test.raises(TypeError, self.interpret, func, [0])
def test_del_basic(self): py.test.skip("xxx fix or kill") S = lltype.GcStruct('S', ('x', lltype.Signed), rtti=True) TRASH = lltype.GcStruct('TRASH', ('x', lltype.Signed)) GLOBAL = lltype.Struct('GLOBAL', ('x', lltype.Signed)) glob = lltype.malloc(GLOBAL, immortal=True) def destructor(s): glob.x = s.x + 1 def type_info_S(s): return lltype.getRuntimeTypeInfo(S) def g(n): s = lltype.malloc(S) s.x = n # now 's' should go away def entrypoint(n): g(n) # llop.gc__collect(lltype.Void) return glob.x t = TranslationContext() t.buildannotator().build_types(entrypoint, [int]) rtyper = t.buildrtyper() destrptr = rtyper.annotate_helper_fn(destructor, [lltype.Ptr(S)]) rtyper.attachRuntimeTypeInfoFunc(S, type_info_S, destrptr=destrptr) rtyper.specialize() fn = self.compile_func(entrypoint, None, t) res = fn(123) assert res == 124
def test_get_size_descr(): c0 = GcCache(False) c1 = GcCache(True) T = lltype.GcStruct('T') S = lltype.GcStruct('S', ('x', lltype.Char), ('y', lltype.Ptr(T))) descr_s = get_size_descr(c0, S) descr_t = get_size_descr(c0, T) assert descr_s.size == symbolic.get_size(S, False) assert descr_t.size == symbolic.get_size(T, False) assert descr_s.is_immutable() == False assert descr_t.is_immutable() == False assert descr_t.gc_fielddescrs == [] assert len(descr_s.gc_fielddescrs) == 1 assert descr_s == get_size_descr(c0, S) assert descr_s != get_size_descr(c1, S) # descr_s = get_size_descr(c1, S) assert isinstance(descr_s.size, Symbolic) assert descr_s.is_immutable() == False PARENT = lltype.Struct('P', ('x', lltype.Ptr(T))) STRUCT = lltype.GcStruct('S', ('parent', PARENT), ('y', lltype.Ptr(T))) descr_struct = get_size_descr(c0, STRUCT) assert len(descr_struct.gc_fielddescrs) == 2
def test_get_call_descr_not_translated(): c0 = GcCache(False) descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char) assert descr1.get_result_size() == rffi.sizeof(lltype.Char) assert descr1.get_result_type() == history.INT assert descr1.arg_classes == "ii" # T = lltype.GcStruct('T') descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T)) assert descr2.get_result_size() == rffi.sizeof(lltype.Ptr(T)) assert descr2.get_result_type() == history.REF assert descr2.arg_classes == "r" # U = lltype.GcStruct('U', ('x', lltype.Signed)) assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U)) # V = lltype.Struct('V', ('x', lltype.Signed)) assert (get_call_descr(c0, [], lltype.Ptr(V)).get_result_type() == history.INT) # assert (get_call_descr(c0, [], lltype.Void).get_result_type() == history.VOID) # descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float) assert descr4.get_result_size() == rffi.sizeof(lltype.Float) assert descr4.get_result_type() == history.FLOAT assert descr4.arg_classes == "ff" # descr5 = get_call_descr(c0, [lltype.SingleFloat], lltype.SingleFloat) assert descr5.get_result_size() == rffi.sizeof(lltype.SingleFloat) assert descr5.get_result_type() == "S" assert descr5.arg_classes == "S"
def prepare_database(db): FUNCPTR = lltype.Ptr(lltype.FuncType([revdb._CMDPTR, lltype.Ptr(rstr.STR)], lltype.Void)) ALLOCFUNCPTR = lltype.Ptr(lltype.FuncType([rffi.LONGLONG, llmemory.GCREF], lltype.Void)) bk = db.translator.annotator.bookkeeper cmds = getattr(db.translator, 'revdb_commands', {}) numcmds = [(num, func) for (num, func) in cmds.items() if isinstance(num, int)] S = lltype.Struct('RPY_REVDB_COMMANDS', ('names', lltype.FixedSizeArray(rffi.INT, len(numcmds) + 1)), ('funcs', lltype.FixedSizeArray(FUNCPTR, len(numcmds))), ('alloc', ALLOCFUNCPTR)) s = lltype.malloc(S, flavor='raw', immortal=True, zero=True) i = 0 for name, func in cmds.items(): fnptr = lltype.getfunctionptr(bk.getdesc(func).getuniquegraph()) if isinstance(name, int): assert name != 0 s.names[i] = rffi.cast(rffi.INT, name) s.funcs[i] = fnptr i += 1 elif name == "ALLOCATING": s.alloc = fnptr else: raise AssertionError("bad tag in register_debug_command(): %r" % (name,)) exports.EXPORTS_obj2name[s._as_obj()] = 'rpy_revdb_commands' db.get(s) db.stack_bottom_funcnames = []
def test_cast_opaque_ptr(): O = lltype.GcOpaqueType('O') Q = lltype.GcOpaqueType('Q') S = lltype.GcStruct('S', ('x', lltype.Signed)) def fn(): s = lltype.malloc(S) o = lltype.cast_opaque_ptr(lltype.Ptr(O), s) q = lltype.cast_opaque_ptr(lltype.Ptr(Q), o) p = lltype.cast_opaque_ptr(lltype.Ptr(S), q) return p == s res = interpret(fn, []) assert res is True O1 = lltype.OpaqueType('O') S1 = lltype.Struct('S1', ('x', lltype.Signed)) s1 = lltype.malloc(S1, immortal=True) def fn1(): o1 = lltype.cast_opaque_ptr(lltype.Ptr(O1), s1) p1 = lltype.cast_opaque_ptr(lltype.Ptr(S1), o1) return p1 == s1 res = interpret(fn1, []) assert res is True
def test_struct_fields(self): longsize = 4 if IS_32_BIT else 8 POINT = lltype.Struct( 'POINT', ('x', rffi.LONG), ('y', rffi.SHORT), ('z', rffi.VOIDP), ) y_ofs = longsize z_ofs = longsize * 2 p = lltype.malloc(POINT, flavor='raw') p.x = 42 p.y = rffi.cast(rffi.SHORT, -1) p.z = rffi.cast(rffi.VOIDP, 0x1234) addr = rffi.cast(rffi.VOIDP, p) assert struct_getfield_int(types.slong, addr, 0) == 42 assert struct_getfield_int(types.sshort, addr, y_ofs) == -1 assert struct_getfield_int(types.pointer, addr, z_ofs) == 0x1234 # struct_setfield_int(types.slong, addr, 0, 43) struct_setfield_int(types.sshort, addr, y_ofs, 0x1234FFFE) # 0x1234 is masked out struct_setfield_int(types.pointer, addr, z_ofs, 0x4321) assert p.x == 43 assert p.y == -2 assert rffi.cast(rffi.LONG, p.z) == 0x4321 # lltype.free(p, flavor='raw')
def test_cast_adr_to_int(): S = lltype.Struct('S') p = lltype.malloc(S, immortal=True) def fn(n): a = llmemory.cast_ptr_to_adr(p) if n == 2: return llmemory.cast_adr_to_int(a, "emulated") elif n == 4: return llmemory.cast_adr_to_int(a, "symbolic") else: return llmemory.cast_adr_to_int(a, "forced") res = interpret(fn, [2]) assert is_valid_int(res) assert res == lltype.cast_ptr_to_int(p) # res = interpret(fn, [4]) assert isinstance(res, llmemory.AddressAsInt) assert llmemory.cast_int_to_adr(res) == llmemory.cast_ptr_to_adr(p) # res = interpret(fn, [6]) assert is_valid_int(res) from rpython.rtyper.lltypesystem import rffi assert res == rffi.cast(lltype.Signed, p)
def test_array_fields(self): POINT = lltype.Struct( "POINT", ("x", lltype.Float), ("y", lltype.Float), ) points = lltype.malloc(rffi.CArray(POINT), 2, flavor="raw") points[0].x = 1.0 points[0].y = 2.0 points[1].x = 3.0 points[1].y = 4.0 points = rffi.cast(rffi.CArrayPtr(lltype.Char), points) assert array_getitem(types.double, 16, points, 0, 0) == 1.0 assert array_getitem(types.double, 16, points, 0, 8) == 2.0 assert array_getitem(types.double, 16, points, 1, 0) == 3.0 assert array_getitem(types.double, 16, points, 1, 8) == 4.0 # array_setitem(types.double, 16, points, 0, 0, 10.0) array_setitem(types.double, 16, points, 0, 8, 20.0) array_setitem(types.double, 16, points, 1, 0, 30.0) array_setitem(types.double, 16, points, 1, 8, 40.0) # assert array_getitem(types.double, 16, points, 0, 0) == 10.0 assert array_getitem(types.double, 16, points, 0, 8) == 20.0 assert array_getitem(types.double, 16, points, 1, 0) == 30.0 assert array_getitem(types.double, 16, points, 1, 8) == 40.0 # lltype.free(points, flavor="raw")
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_interior_ptr_with_index(self): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcArray(S) def f(x): t = lltype.malloc(T, 1) t[0].x = x return t[0].x graph = self.check(f, [int], [42], 42)
def build_weakref(config): revdb = config.translation.reverse_debugger if not revdb: WEAKLINK = lltype.Struct('WEAKLINK', ('addr', llmemory.Address)) else: # keep in sync with 'struct WEAKLINK' in revdb.c WEAKLINK = lltype.Struct('REVDB_WEAKLINK', ('addr', llmemory.Address), ('off_prev', lltype.SignedLongLong)) sizeof_weakreflink = llmemory.sizeof(WEAKLINK) empty_weaklink = lltype.malloc(WEAKLINK, immortal=True, zero=True) def ll_weakref_create(target_gcref): if revdb: plink = llop.revdb_weakref_create(lltype.Ptr(WEAKLINK), target_gcref) else: link = llop.boehm_malloc_atomic(llmemory.Address, sizeof_weakreflink) if not link: raise MemoryError plink = llmemory.cast_adr_to_ptr(link, lltype.Ptr(WEAKLINK)) plink.addr = llmemory.cast_ptr_to_adr(target_gcref) llop.boehm_disappearing_link(lltype.Void, link, target_gcref) return llmemory.cast_ptr_to_weakrefptr(plink) def ll_weakref_deref(wref): plink = llmemory.cast_weakrefptr_to_ptr(lltype.Ptr(WEAKLINK), wref) if revdb: result = llop.revdb_weakref_deref(llmemory.GCREF, plink) else: result = llmemory.cast_adr_to_ptr(plink.addr, llmemory.GCREF) return result def convert_weakref_to(targetptr): # Prebuilt weakrefs don't really need to be weak at all, # but we need to emulate the structure expected by ll_weakref_deref(). # This is essentially the same code as in ll_weakref_create(), but I'm # not sure trying to share it is worth the hassle... if not targetptr: return empty_weaklink else: plink = lltype.malloc(WEAKLINK, immortal=True, zero=True) plink.addr = llmemory.cast_ptr_to_adr(targetptr) return plink return ll_weakref_create, ll_weakref_deref, WEAKLINK, convert_weakref_to
def test_flavored_malloc(): T = lltype.GcStruct('T', ('y', lltype.Signed)) def fn(n): p = lltype.malloc(T, flavor='gc') p.y = n return p.y res = interpret(fn, [232]) assert res == 232 S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): p = lltype.malloc(S, flavor='raw') p.x = n result = p.x lltype.free(p, flavor='raw') return result res = interpret(fn, [23]) assert res == 23 S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): p = lltype.malloc(S, flavor='raw', track_allocation=False) p.x = n result = p.x return result res = interpret(fn, [23]) assert res == 23 S = lltype.Struct('S', ('x', lltype.Signed)) def fn(n): p = lltype.malloc(S, flavor='raw', track_allocation=False) p.x = n result = p.x lltype.free(p, flavor='raw', track_allocation=False) return result res = interpret(fn, [23]) assert res == 23
def test_substruct_not_accessed(self): SMALL = lltype.Struct('SMALL', ('x', lltype.Signed)) BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL)) def fn(): x = lltype.malloc(BIG) while x.z < 10: # makes several blocks x.z += 3 return x.z self.check(fn, [], [], 12)
def create_lowlevel_type(self): entry_methods = { "valid": LLOrderedDict.ll_valid_from_flag, "everused": LLOrderedDict.ll_everused_from_flag, "mark_deleted": LLOrderedDict.ll_mark_deleted_in_flag, "must_clear_key": self._must_clear(self.key_repr.lowleveltype), "must_clear_value": self._must_clear(self.value_repr.lowleveltype), } fields = [ ("key", self.key_repr.lowleveltype), ("value", self.value_repr.lowleveltype), ("next", lltype.Signed), ("prev", lltype.Signed), ("everused", lltype.Bool), ("valid", lltype.Bool), ] fast_hash_func = None if not self.hash_func_repr: fast_hash_func = self.key_repr.get_ll_hash_function() if fast_hash_func is None: fields.append(("hash", lltype.Signed)) entry_methods["hash"] = LLOrderedDict.ll_hash_from_cache else: entry_methods["hash"] = LLOrderedDict.ll_hash_recompute entry_methods["fast_hash_func"] = fast_hash_func DICTENTRY = lltype.Struct("ORDEREDDICTENTRY", *fields) fields = [ ("num_items", lltype.Signed), ("resize_counter", lltype.Signed), ("first_entry", lltype.Signed), ("last_entry", lltype.Signed), ("entries", lltype.Ptr(lltype.GcArray(DICTENTRY, adtmeths=entry_methods))), ] dict_methods = {} if self.eq_func_repr and self.hash_func_repr: dict_methods["paranoia"] = True dict_methods["hashkey"] = LLOrderedDict.ll_hashkey_custom dict_methods["keyeq"] = LLOrderedDict.ll_keyeq_custom dict_methods["r_hashkey"] = self.hash_func_repr dict_methods["r_keyeq"] = self.eq_func_repr fields.append(("hashkey_func", self.hash_func_repr.lowleveltype)) fields.append(("keyeq_func", self.eq_func_repr.lowleveltype)) else: dict_methods["paranoia"] = False dict_methods["hashkey"] = lltype.staticAdtMethod( self.key_repr.get_ll_hash_function()) ll_keyeq = self.key_repr.get_ll_eq_function() if ll_keyeq is not None: ll_keyeq = lltype.staticAdtMethod(ll_keyeq) dict_methods["keyeq"] = ll_keyeq DICT = lltype.GcStruct("ORDEREDDICT", *fields, adtmeths=dict_methods) return lltype.Ptr(DICT)
def test_interior_ptr(self): py.test.skip("fails") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) def f(x): t = lltype.malloc(T) t.s.x = x return t.s.x graph = self.check(f, [int], [42], 42)
def test_recursive_llhelper(): from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype from rpython.rlib.objectmodel import specialize FT = lltype.ForwardReference() FTPTR = lltype.Ptr(FT) STRUCT = lltype.Struct("foo", ("bar", FTPTR)) FT.become(lltype.FuncType([lltype.Ptr(STRUCT)], lltype.Signed)) class A: def __init__(self, func, name): self.func = func self.name = name def _freeze_(self): return True @specialize.memo() def make_func(self): f = getattr(self, "_f", None) if f is not None: return f f = lambda *args: self.func(*args) f.c_name = self.name f.relax_sig_check = True f.__name__ = "WRAP%s" % (self.name, ) self._f = f return f def get_llhelper(self): return llhelper(FTPTR, self.make_func()) def f(s): if s.bar == t.bar: lltype.free(s, flavor="raw") return 1 lltype.free(s, flavor="raw") return 0 def g(x): return 42 def chooser(x): s = lltype.malloc(STRUCT, flavor="raw") if x: s.bar = llhelper(FTPTR, a_f.make_func()) else: s.bar = llhelper(FTPTR, a_g.make_func()) return f(s) a_f = A(f, "f") a_g = A(g, "g") t = lltype.malloc(STRUCT, flavor="raw", immortal=True) t.bar = llhelper(FTPTR, a_f.make_func()) fn = compile(chooser, [bool]) assert fn(True)
def test_fixed_size_malloc(self): TIMEVAL = lltype.Struct('dummy', ('tv_sec', rffi.LONG), ('tv_usec', rffi.LONG)) def f(): p = lltype.malloc(TIMEVAL, flavor='raw') lltype.free(p, flavor='raw') return 42 res = self.interp_operations(f, []) assert res == 42 self.check_operations_history({'call': 2, 'guard_no_exception': 1, 'finish': 1})
def test_interior_ptr_len(): S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('items', lltype.Array(S))) def f(): t = lltype.malloc(T, 1) return len(t.items) res = interpret(f, []) assert res == 1
def test_dont_decref_nongc_pointers(): S = lltype.GcStruct( 'S', ('x', lltype.Ptr(lltype.Struct('T', ('x', lltype.Signed)))), ('y', lltype.Ptr(lltype.GcStruct('Y', ('x', lltype.Signed))))) def f(): pass graph, t = make_deallocator(S) ops = getops(graph) assert len(ops['direct_call']) == 1
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_union(self): py.test.skip("fails because of the interior structure changes") UNION = lltype.Struct('UNION', ('a', lltype.Signed), ('b', lltype.Signed), hints = {'union': True}) BIG = lltype.GcStruct('BIG', ('u1', UNION), ('u2', UNION)) def fn(): x = lltype.malloc(BIG) x.u1.a = 3 x.u2.b = 6 return x.u1.b * x.u2.a self.check(fn, [], [], Ellipsis)
def test_interior_ptr(self): py.test.skip("llptr support not really useful any more") S = lltype.Struct("S", ('x', lltype.Signed)) T = lltype.GcStruct("T", ('s', S)) def f(x): t = lltype.malloc(T) t.s.x = x return t.s.x graph = self.check(f, [int], [42], 42)
def test_const_ptr_subops(self): x = """ [p0] guard_class(p0, ConstClass(vtable)) [] """ S = lltype.Struct('S') vtable = lltype.nullptr(S) loop = self.parse(x, None, locals()) assert len(loop.operations) == 1 assert loop.operations[0].getdescr() assert loop.operations[0].getfailargs() == []