def test_traceback(self, space, api): w_traceback = space.appexec([], """(): import sys try: 1/0 except: return sys.exc_info()[2] """) py_obj = make_ref(space, w_traceback) py_traceback = rffi.cast(PyTracebackObject, py_obj) assert (from_ref(space, rffi.cast(PyObject, py_traceback.c_ob_type)) is space.gettypeobject(PyTraceback.typedef)) traceback = space.interp_w(PyTraceback, w_traceback) assert traceback.lasti == py_traceback.c_tb_lasti assert traceback.get_lineno() == py_traceback.c_tb_lineno assert space.eq_w(space.getattr(w_traceback, space.wrap("tb_lasti")), space.wrap(py_traceback.c_tb_lasti)) assert space.is_w(space.getattr(w_traceback, space.wrap("tb_frame")), from_ref(space, rffi.cast(PyObject, py_traceback.c_tb_frame))) while not space.is_w(w_traceback, space.w_None): assert space.is_w( w_traceback, from_ref(space, rffi.cast(PyObject, py_traceback))) w_traceback = space.getattr(w_traceback, space.wrap("tb_next")) py_traceback = py_traceback.c_tb_next assert lltype.normalizeptr(py_traceback) is None api.Py_DecRef(py_obj)
def get_actual_typeid(self, gcptr): """Fetch the actual typeid of the given gcptr, as an integer. Only usable in the llgraph backend, or after translation of a real backend. (Here in the llgraph backend, returns a TypeIDSymbolic instead of a real integer.)""" ptr = lltype.normalizeptr(gcptr._obj.container._as_ptr()) return TypeIDSymbolic(lltype.typeOf(ptr).TO)
def check_is_object(self, gcptr): """Check if the given, non-null gcptr refers to an rclass.OBJECT or not at all (an unrelated GcStruct or a GcArray). Only usable in the llgraph backend, or after translation of a real backend.""" ptr = lltype.normalizeptr(gcptr._obj.container._as_ptr()) T = lltype.typeOf(ptr).TO return heaptracker.has_gcstruct_a_vtable(T) or T is rclass.OBJECT
def test_traceback(self, space, api): w_traceback = space.appexec( [], """(): import sys try: 1/0 except: return sys.exc_info()[2] """, ) py_obj = make_ref(space, w_traceback) py_traceback = rffi.cast(PyTracebackObject, py_obj) assert from_ref(space, rffi.cast(PyObject, py_traceback.c_ob_type)) is space.gettypeobject(PyTraceback.typedef) traceback = space.interp_w(PyTraceback, w_traceback) assert traceback.lasti == py_traceback.c_tb_lasti assert traceback.get_lineno() == py_traceback.c_tb_lineno assert space.eq_w(space.getattr(w_traceback, space.wrap("tb_lasti")), space.wrap(py_traceback.c_tb_lasti)) assert space.is_w( space.getattr(w_traceback, space.wrap("tb_frame")), from_ref(space, rffi.cast(PyObject, py_traceback.c_tb_frame)), ) while not space.is_w(w_traceback, space.w_None): assert space.is_w(w_traceback, from_ref(space, rffi.cast(PyObject, py_traceback))) w_traceback = space.getattr(w_traceback, space.wrap("tb_next")) py_traceback = py_traceback.c_tb_next assert lltype.normalizeptr(py_traceback) is None api.Py_DecRef(py_obj)
def enum_content(self, o, name='', with_header=True): # XXX clean up T = lltype.typeOf(o) if (self.size_gc_header is not None and with_header and isinstance(T, lltype.ContainerType) and T._gckind == 'gc'): adr = llmemory.cast_ptr_to_adr(o._as_ptr()) adr -= self.size_gc_header o = adr.get()._obj T = lltype.typeOf(o) if isinstance(T, lltype.Struct): try: gcobjptr = header2obj[o] fmt = '(%s)' except KeyError: gcobjptr = None fmt = '%s' for name in T._names: for name, value in self.enum_content(getattr(o, name), name, with_header=False): yield fmt % (name, ), value if gcobjptr: if self.size_gc_header is not None: for sub in self.enum_content(gcobjptr._obj, with_header=False): yield sub else: # display as a link to avoid the same data showing up # twice in the graph yield 'header of', gcobjptr._obj elif isinstance(T, lltype.Array): for index, o1 in enumerate(o.items): for sub in self.enum_content(o1, str(index)): yield sub elif isinstance(T, lltype.Ptr): if not o: yield name, 'null' else: yield name, self.normalize(lltype.normalizeptr(o)._obj) elif isinstance(T, lltype.OpaqueType) and hasattr(o, 'container'): T = lltype.typeOf(o.container) yield 'container', '<%s>' % (shorttypename(T), ) for sub in self.enum_content(o.container, name, with_header=False): yield sub elif T == llmemory.Address: if not o: yield name, 'NULL' else: addrof = o.ref() T1 = lltype.typeOf(addrof) if (isinstance(T1, lltype.Ptr) and isinstance(T1.TO, lltype.Struct) and addrof._obj in header2obj): yield name + ' @hdr', self.normalize(addrof._obj) else: yield name + ' @', self.normalize(o.ptr._obj) else: yield name, str(o)
def test_simple(self): def f(v): vinst = V(v) return vinst, vinst.v res = self.interpret(f, [42]) assert res.item1 == 42 res = lltype.normalizeptr(res.item0) assert res.inst_v == 42 assert res.vable_token == lltype.nullptr(llmemory.GCREF.TO)
def enum_content(self, o, name='', with_header=True): # XXX clean up T = lltype.typeOf(o) if (self.size_gc_header is not None and with_header and isinstance(T, lltype.ContainerType) and T._gckind == 'gc'): adr = llmemory.cast_ptr_to_adr(o._as_ptr()) adr -= self.size_gc_header o = adr.get()._obj T = lltype.typeOf(o) if isinstance(T, lltype.Struct): try: gcobjptr = header2obj[o] fmt = '(%s)' except KeyError: gcobjptr = None fmt = '%s' for name in T._names: for name, value in self.enum_content(getattr(o, name), name, with_header=False): yield fmt % (name,), value if gcobjptr: if self.size_gc_header is not None: for sub in self.enum_content(gcobjptr._obj, with_header=False): yield sub else: # display as a link to avoid the same data showing up # twice in the graph yield 'header of', gcobjptr._obj elif isinstance(T, lltype.Array): for index, o1 in enumerate(o.items): for sub in self.enum_content(o1, str(index)): yield sub elif isinstance(T, lltype.Ptr): if not o: yield name, 'null' else: yield name, self.normalize(lltype.normalizeptr(o)._obj) elif isinstance(T, lltype.OpaqueType) and hasattr(o, 'container'): T = lltype.typeOf(o.container) yield 'container', '<%s>' % (shorttypename(T),) for sub in self.enum_content(o.container, name, with_header=False): yield sub elif T == llmemory.Address: if not o: yield name, 'NULL' else: addrof = o.ref() T1 = lltype.typeOf(addrof) if (isinstance(T1, lltype.Ptr) and isinstance(T1.TO, lltype.Struct) and addrof._obj in header2obj): yield name + ' @hdr', self.normalize(addrof._obj) else: yield name + ' @', self.normalize(o.ptr._obj) else: yield name, str(o)
def feedllattr(inst, name, llvalue): p = widest = lltype.normalizeptr(inst) while True: try: return setattr(p, 'inst_' + name, llvalue) except AttributeError: pass try: p = p.super except AttributeError: break raise AttributeError("%s has no field %s" % (lltype.typeOf(widest), name))
def fishllattr(inst, name, default=_missing): p = widest = lltype.normalizeptr(inst) while True: try: return getattr(p, 'inst_' + name) except AttributeError: pass try: p = p.super except AttributeError: break if default is _missing: raise AttributeError("%s has no field %s" % (lltype.typeOf(widest), name)) return default
def add_vtable_after_typeinfo(self, TYPE): # if gcremovetypeptr is False, then lltype2vtable is None and it # means that we don't have to store the vtables in type_info_group. if self.lltype2vtable is None: return # does the type have a vtable? vtable = self.lltype2vtable.get(TYPE, None) if vtable is not None: # yes. check that in this case, we are not varsize assert not TYPE._is_varsize() vtable = lltype.normalizeptr(vtable) self.type_info_group.add_member(vtable) else: # no vtable from lltype2vtable -- double-check to be sure # that it's not a subclass of OBJECT. assert not is_subclass_of_object(TYPE)
def _find_exception_type(block): #XXX slightly brittle: find the exception type for simple cases #(e.g. if you do only raise XXXError) by doing pattern matching currvar = block.exits[0].args[1] ops = block.operations i = len(ops) - 1 while True: if isinstance(currvar, Constant): value = currvar.value TYPE = typeOf(normalizeptr(value)) return TYPE, block.exits[0] if i < 0: return None, None op = ops[i] i -= 1 if op.opname in ("same_as", "cast_pointer") and op.result is currvar: currvar = op.args[0] elif op.opname == "malloc" and op.result is currvar: return Ptr(op.args[0].value), block.exits[0]
def test_traceback(self, space, api): src = """(): import sys try: 1/0 except: return sys.exc_info()[2] """ w_traceback = space.appexec([], src) py_obj = make_ref(space, w_traceback) py_traceback = rffi.cast(PyTracebackObject, py_obj) assert (from_ref(space, rffi.cast(PyObject, py_traceback.c_ob_type)) is space.gettypeobject(PyTraceback.typedef)) traceback = space.interp_w(PyTraceback, w_traceback) assert traceback.lasti == py_traceback.c_tb_lasti assert traceback.get_lineno() == py_traceback.c_tb_lineno assert space.eq_w(space.getattr(w_traceback, space.wrap("tb_lasti")), space.wrap(py_traceback.c_tb_lasti)) assert space.is_w( space.getattr(w_traceback, space.wrap("tb_frame")), from_ref(space, rffi.cast(PyObject, py_traceback.c_tb_frame))) while not space.is_w(w_traceback, space.w_None): assert space.is_w( w_traceback, from_ref(space, rffi.cast(PyObject, py_traceback))) w_traceback = space.getattr(w_traceback, space.wrap("tb_next")) py_traceback = py_traceback.c_tb_next assert lltype.normalizeptr(py_traceback) is None decref(space, py_obj) # hack to allow the code object to be freed del space.fromcache(AppExecCache).content[src]
def __init__(self, ptarget): if ptarget is None: self._obref = lambda: None else: obj = lltype.normalizeptr(ptarget)._obj self._obref = weakref.ref(obj)