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: GCT = lltype.typeOf(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) ## if o.offset: ## yield '... offset', str(o.offset) else: yield name, str(o)
def get_type_id(self, TYPE): try: return self.id_of_type[TYPE] except KeyError: assert self.can_add_new_types assert isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)) # Record the new type_id description as a TYPE_INFO structure. # build the TYPE_INFO structure if not TYPE._is_varsize(): fullinfo = lltype.malloc(GCData.TYPE_INFO, immortal=True, zero=True) info = fullinfo else: fullinfo = lltype.malloc(GCData.VARSIZE_TYPE_INFO, immortal=True, zero=True) info = fullinfo.header if self.can_encode_type_shape: encode_type_shape(self, info, TYPE) else: self._pending_type_shapes.append((info, TYPE)) # store it type_id = self.type_info_group.add_member(fullinfo) self.id_of_type[TYPE] = type_id # store the vtable of the type (if any) immediately thereafter # (note that if gcconfig.removetypeptr is False, lltype2vtable # is empty) vtable = self.lltype2vtable.get(TYPE, None) if vtable is not None: # check that if we have a vtable, we are not varsize assert lltype.typeOf(fullinfo) == GCData.TYPE_INFO_PTR vtable = lltype.normalizeptr(vtable) self.type_info_group.add_member(vtable) return type_id
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 if isinstance(typeOf(value), ootype.Instance): TYPE = ootype.dynamicType(value) else: 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", "ooupcast", "oodowncast") 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] elif op.opname == "new" and op.result is currvar: return op.args[0].value, block.exits[0]
def fishllattr(inst, name, default=_missing): from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype if isinstance(inst, (ootype._instance, ootype._view)): # XXX: we need to call ootypesystem.rclass.mangle, but we # can't because we don't have a config object mangled = 'o' + name if default is _missing: return getattr(inst, mangled) else: return getattr(inst, mangled, default) else: 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 g(vobj): vobj = lltype.normalizeptr(vobj) LLV = lltype.typeOf(vobj).TO ACCESS = LLV.vable_access.TO access = lltype.malloc(ACCESS, immortal=True) access.set_inst_v = lltype.functionptr(ACCESS.set_inst_v.TO, 'setv', _callable=setv) vobj.vable_access = access
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 == 0
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 not res.vable_rti
def g(vobj): vobj = lltype.normalizeptr(vobj) LLV = lltype.typeOf(vobj).TO ACCESS = LLV.ACCESS access = lltype.malloc(ACCESS, immortal=True) fp = lltype.functionptr(ACCESS.parent.get_inst_v0.TO, 'getv0', _callable=getv0) access.parent.get_inst_v0= fp access.get_inst_v1 = lltype.functionptr(ACCESS.get_inst_v1.TO, 'getv1', _callable=getv1) vobj.super.vable_access = access.parent
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 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 g(vobj): vobj = lltype.normalizeptr(vobj) LLV = lltype.typeOf(vobj).TO ACCESS = LLV.ACCESS access = lltype.malloc(ACCESS, immortal=True) fp = lltype.functionptr(ACCESS.parent.get_inst_v0.TO, 'getv0', _callable=getv0) access.parent.get_inst_v0 = fp access.get_inst_v1 = lltype.functionptr(ACCESS.get_inst_v1.TO, 'getv1', _callable=getv1) vobj.super.vable_access = access.parent
def test_simple(): def f(v): vinst = V(v) return vinst, vinst.v res = interpret(f, [42]) assert res.item1 == 42 res = lltype.normalizeptr(res.item0) assert res.inst_v == 42 assert not res.vable_access LLV = lltype.typeOf(res) ACCESS = lltype.typeOf(res.vable_access).TO assert ACCESS.get_inst_v == lltype.Ptr(lltype.FuncType([LLV], lltype.Signed)) assert ACCESS.set_inst_v == lltype.Ptr(lltype.FuncType([LLV, lltype.Signed], lltype.Void))
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 test_simple(): def f(v): vinst = V(v) return vinst, vinst.v res = interpret(f, [42]) assert res.item1 == 42 res = lltype.normalizeptr(res.item0) assert res.inst_v == 42 assert not res.vable_access LLV = lltype.typeOf(res) ACCESS = lltype.typeOf(res.vable_access).TO assert ACCESS.get_inst_v == lltype.Ptr( lltype.FuncType([LLV], lltype.Signed)) assert ACCESS.set_inst_v == lltype.Ptr( lltype.FuncType([LLV, lltype.Signed], lltype.Void))
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 dc_hash(c): "NOT_RPYTHON" # This is called during translation only. Avoid using identityhash(), # to avoid forcing a hash, at least on lltype objects. if not isinstance(c, Const): return hash(c) if isinstance(c.value, Symbolic): return id(c.value) try: if isinstance(c, ConstPtr): p = lltype.normalizeptr(c.value) if p is not None: return hash(p._obj) else: return 0 return c._get_hash_() except lltype.DelayedPointer: return -2 # xxx risk of changing hash...
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 if isinstance(typeOf(value), ootype.Instance): TYPE = ootype.dynamicType(value) else: 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", "ooupcast", "oodowncast") 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] elif op.opname == "new" and op.result is currvar: return op.args[0].value, block.exits[0]
def getv1(vinst): value = lltype.normalizeptr(vinst).inst_v1 witness.append(value) return value
def __init__(self, ptarget): if ptarget is None: self._obref = lambda: None else: obj = lltype.normalizeptr(ptarget)._obj self._obref = weakref.ref(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: GCT = lltype.typeOf(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) ## if o.offset: ## yield '... offset', str(o.offset) else: yield name, str(o)