[pypy-svn] r51603 - in pypy/branch/unified-rtti/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test rpython/test
arigo at codespeak.net
arigo at codespeak.net
Mon Feb 18 20:34:39 CET 2008
Author: arigo
Date: Mon Feb 18 20:34:37 2008
New Revision: 51603
Modified:
pypy/branch/unified-rtti/pypy/annotation/builtin.py
pypy/branch/unified-rtti/pypy/rpython/llinterp.py
pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py
pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py
pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py
pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py
pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py
pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py
pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py
pypy/branch/unified-rtti/pypy/rpython/rtyper.py
pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py
Log:
In-progress: fixing lltypesystem.rclass.
Modified: pypy/branch/unified-rtti/pypy/annotation/builtin.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/annotation/builtin.py (original)
+++ pypy/branch/unified-rtti/pypy/annotation/builtin.py Mon Feb 18 20:34:37 2008
@@ -455,6 +455,12 @@
cast_p = lltype.cast_opaque_ptr(PtrT.const, s_p.ll_ptrtype._defl())
return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
+def runtime_type_info(s_p):
+ assert isinstance(s_p, SomePtr), ("runtime_type_info of non-pointer: %r" %
+ s_p)
+ res_p = lltype.runtime_type_info(s_p.ll_ptrtype._example())
+ return SomePtr(ll_ptrtype=lltype.typeOf(res_p))
+
def direct_fieldptr(s_p, s_fieldname):
assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
assert s_fieldname.is_constant()
@@ -479,14 +485,6 @@
assert PtrT.is_constant()
return SomePtr(ll_ptrtype=PtrT.const)
-def getRuntimeTypeInfo(T):
- assert T.is_constant()
- return immutablevalue(lltype.getRuntimeTypeInfo(T.const))
-
-def runtime_type_info(s_p):
- assert isinstance(s_p, SomePtr), "runtime_type_info of non-pointer: %r" % s_p
- return SomePtr(lltype.typeOf(lltype.runtime_type_info(s_p.ll_ptrtype._example())))
-
def constPtr(T):
assert T.is_constant()
return immutablevalue(lltype.Ptr(T.const))
@@ -498,13 +496,12 @@
BUILTIN_ANALYZERS[lltype.nullptr] = nullptr
BUILTIN_ANALYZERS[lltype.cast_pointer] = cast_pointer
BUILTIN_ANALYZERS[lltype.cast_opaque_ptr] = cast_opaque_ptr
+BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
BUILTIN_ANALYZERS[lltype.direct_fieldptr] = direct_fieldptr
BUILTIN_ANALYZERS[lltype.direct_arrayitems] = direct_arrayitems
BUILTIN_ANALYZERS[lltype.direct_ptradd] = direct_ptradd
BUILTIN_ANALYZERS[lltype.cast_ptr_to_int] = cast_ptr_to_int
BUILTIN_ANALYZERS[lltype.cast_int_to_ptr] = cast_int_to_ptr
-BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
-BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
BUILTIN_ANALYZERS[lltype.Ptr] = constPtr
# ootype
Modified: pypy/branch/unified-rtti/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/llinterp.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/llinterp.py Mon Feb 18 20:34:37 2008
@@ -764,12 +764,6 @@
def op_gc_restore_exception(self, exc):
raise NotImplementedError("gc_restore_exception")
- def op_gc_call_rtti_destructor(self, rtti, addr):
- if hasattr(rtti._obj, 'destructor_funcptr'):
- d = rtti._obj.destructor_funcptr
- obptr = addr.ref()
- return self.op_direct_call(d, obptr)
-
def op_gc_deallocate(self, TYPE, addr):
raise NotImplementedError("gc_deallocate")
Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/exceptiondata.py Mon Feb 18 20:34:37 2008
@@ -53,11 +53,8 @@
#else:
# assert cls.__module__ != 'exceptions', (
# "built-in exceptions should not grow attributes")
- r_inst = rclass.getinstancerepr(rtyper, None)
- r_inst.setup()
default_excinst = malloc(self.lltype_of_exception_value.TO,
immortal=True)
- default_excinst.typeptr = r_inst.rclass.getvtable()
# build the table in order base classes first, subclasses last
sortedtable = []
Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lloperation.py Mon Feb 18 20:34:37 2008
@@ -390,7 +390,7 @@
'gc_free': LLOp(),
'gc_fetch_exception': LLOp(),
'gc_restore_exception': LLOp(),
- 'gc_call_rtti_destructor': LLOp(),
+ 'gc_runtime_type_info': LLOp(canfold=True),
'gc_deallocate': LLOp(),
'gc_push_alive_pyobj': LLOp(),
'gc_pop_alive_pyobj': LLOp(),
Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/lltype.py Mon Feb 18 20:34:37 2008
@@ -988,6 +988,8 @@
return adtmeth
else:
return getter(self)
+ if self._T == RuntimeTypeInfo:
+ return self._obj._getattr(field_name)
raise AttributeError("%r instance has no field %r" % (self._T,
field_name))
@@ -1003,6 +1005,9 @@
"expects %r\n"
" got %r" % (self._T, field_name, T1, T2))
return
+ if self._T == RuntimeTypeInfo:
+ self._obj._setattr(field_name, val)
+ return
raise AttributeError("%r instance has no field %r" % (self._T,
field_name))
@@ -1644,6 +1649,7 @@
class _rtti(_parentable):
_kind = "rtti"
+ destructor_funcptr = None
def __init__(self, initialization=None, parent=None, parentindex=None):
_parentable.__init__(self, RuntimeTypeInfo)
@@ -1656,7 +1662,23 @@
if GCTYPE._gckind != 'gc':
raise TypeError("non-GC type %r cannot have an rtti" % (GCTYPE,))
self._GCTYPE = GCTYPE
- self.destructor_funcptr = nullptr(FuncType([Ptr(GCTYPE)], Void))
+
+ def _getattr(self, name):
+ if name == 'destructor_funcptr':
+ return self.destructor_funcptr
+ else:
+ raise AttributeError(name)
+
+ def _setattr(self, name, value):
+ if name == 'destructor_funcptr':
+ T = typeOf(value).TO
+ if (not isinstance(T, FuncType) or len(T.ARGS) != 1
+ or T.RESULT != Void or not isinstance(T.ARGS[0], Ptr)
+ or castable(T.ARGS[0], Ptr(self._GCTYPE)) < 0):
+ raise TypeError("bad type for destructor: %r" % (T,))
+ self.destructor_funcptr = value
+ else:
+ raise AttributeError(name)
class _opaque(_parentable):
@@ -1782,16 +1804,15 @@
return _ptr(PTRTYPE, oddint, solid=True)
def getRuntimeTypeInfo(TYPE, cache=None):
- """Return the runtime_type_info attached to the GcStruct TYPE.
- This is typically of type != Ptr(RuntimeTypeInfo) but castable
- to Ptr(RuntimeTypeInfo). This raises TypeError if the TYPE has
+ """Return the runtime_type_info attached to the GcStruct TYPE,
+ as a Ptr(RuntimeTypeInfo). This raises TypeError if the TYPE has
no runtime_type_info, unless 'cache' is specified; in that case,
TYPE can be any GC type and a runtime_type_info is created for
it if it has none and stored in the cache to avoid mutating
the TYPE.
"""
if isinstance(TYPE, GcStruct) and hasattr(TYPE, '_rtti'):
- return top_container(TYPE._rtti)._as_ptr()
+ return TYPE._rtti._as_ptr()
if cache is None:
raise TypeError("%r has no runtime_type_info" % (TYPE,))
try:
@@ -1801,6 +1822,7 @@
rttiptr._obj._set_gctype(TYPE)
cache[TYPE] = rttiptr
return rttiptr
+getRuntimeTypeInfo._annspecialcase_ = 'specialize:memo'
def _install_rtti(STRUCT, runtime_type_info):
if not isinstance(STRUCT, GcStruct):
Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/opimpl.py Mon Feb 18 20:34:37 2008
@@ -313,6 +313,9 @@
## assert type(x) is int
## return llmemory.cast_int_to_adr(x)
+def op_gc_runtime_type_info(gcptr):
+ return lltype.runtime_type_info(gcptr)
+
def op_unichar_eq(x, y):
assert isinstance(x, unicode) and len(x) == 1
Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/rclass.py Mon Feb 18 20:34:37 2008
@@ -12,8 +12,7 @@
from pypy.rpython.lltypesystem.lltype import \
Ptr, Struct, GcStruct, malloc, \
cast_pointer, cast_ptr_to_int, castable, nullptr, \
- RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, \
- Array, Char, Void, attachRuntimeTypeInfo, \
+ typeOf, Array, Char, Void, \
FuncType, Bool, Signed, functionptr, FuncType, PyObject
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.robject import PyObjRepr, pyobj_repr
@@ -27,8 +26,7 @@
# A root class "object" has:
#
# struct object_vtable {
-# // struct object_vtable* parenttypeptr; not used any more
-# RuntimeTypeInfo * rtti;
+# RuntimeTypeInfo rtti; //GC-specific information
# Signed subclassrange_min; //this is also the id of the class itself
# Signed subclassrange_max;
# array { char } * name;
@@ -45,7 +43,7 @@
# The type of the instances is:
#
# struct object { // for the root class
-# struct object_vtable* typeptr;
+# some GC-specific fields including a ptr to the vtable
# }
#
# struct X {
@@ -55,22 +53,32 @@
#
# there's also a nongcobject
-OBJECT_VTABLE = lltype.ForwardReference()
-CLASSTYPE = Ptr(OBJECT_VTABLE)
-OBJECT = GcStruct('object', ('typeptr', CLASSTYPE),
- hints = {'immutable': True, 'shouldntbenull': True})
+def ll_gettypeptr(p):
+ rtti = lltype.runtime_type_info(p)
+ return cast_pointer(CLASSTYPE, rtti)
+
+def ll_gettypeptr_nongc(p):
+ return p.typeptr
+
+OBJECT = lltype.GcForwardReference()
OBJECTPTR = Ptr(OBJECT)
-OBJECT_VTABLE.become(Struct('object_vtable',
- #('parenttypeptr', CLASSTYPE),
+OBJECT_VTABLE = Struct('object_vtable',
+ ('rtti', lltype.RuntimeTypeInfo),
('subclassrange_min', Signed),
('subclassrange_max', Signed),
- ('rtti', Ptr(RuntimeTypeInfo)),
('name', Ptr(Array(Char))),
('instantiate', Ptr(FuncType([], OBJECTPTR))),
- hints = {'immutable': True}))
+ hints = {'immutable': True})
+CLASSTYPE = Ptr(OBJECT_VTABLE)
+OBJECT.become(GcStruct('object',
+ runtime_type_info = malloc(OBJECT_VTABLE,
+ immortal=True),
+ adtmeths = {'gettypeptr': ll_gettypeptr}))
+
# non-gc case
-NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE))
-NONGCOBJECTPTR = Ptr(OBJECT)
+NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE),
+ adtmeths = {'gettypeptr': ll_gettypeptr_nongc})
+NONGCOBJECTPTR = Ptr(NONGCOBJECT)
OBJECT_BY_FLAVOR = {'gc': OBJECT,
'raw': NONGCOBJECT}
@@ -80,12 +88,6 @@
'stack': 'raw',
}
-def cast_vtable_to_typeptr(vtable):
- while typeOf(vtable).TO != OBJECT_VTABLE:
- vtable = vtable.super
- return vtable
-
-
class ClassRepr(AbstractClassRepr):
def __init__(self, rtyper, classdef):
AbstractClassRepr.__init__(self, rtyper, classdef)
@@ -140,32 +142,15 @@
self.clsfields = clsfields
self.pbcfields = pbcfields
self.allmethods = allmethods
- self.vtable = None
-
-# def convert_const(self, value):
-# if not isinstance(value, (type, types.ClassType)):
-# raise TyperError("not a class: %r" % (value,))
-# try:
-# subclassdef = self.rtyper.annotator.getuserclasses()[value]
-# except KeyError:
-# raise TyperError("no classdef: %r" % (value,))
-# if self.classdef is not None:
-# if self.classdef.commonbase(subclassdef) != self.classdef:
-# raise TyperError("not a subclass of %r: %r" % (
-# self.classdef.cls, value))
-# #
-# return getclassrepr(self.rtyper, subclassdef).getvtable()
+ self.vtable = malloc(self.vtable_type, immortal=True)
+ self.vtable_filled = False
- def getvtable(self, cast_to_typeptr=True):
+ def getvtable(self):
"""Return a ptr to the vtable of this type."""
- if self.vtable is None:
- self.vtable = malloc(self.vtable_type, immortal=True)
+ if not self.vtable_filled:
self.setup_vtable(self.vtable, self)
- #
- vtable = self.vtable
- if cast_to_typeptr:
- vtable = cast_vtable_to_typeptr(vtable)
- return vtable
+ self.vtable_filled = True
+ return cast_pointer(CLASSTYPE, self.vtable)
getruntime = getvtable
def setup_vtable(self, vtable, rsubcls):
@@ -174,7 +159,6 @@
if self.classdef is None:
# initialize the 'subclassrange_*' and 'name' fields
if rsubcls.classdef is not None:
- #vtable.parenttypeptr = rsubcls.rbase.getvtable()
vtable.subclassrange_min = rsubcls.classdef.minid
vtable.subclassrange_max = rsubcls.classdef.maxid
else: #for the root class
@@ -182,8 +166,6 @@
vtable.subclassrange_max = sys.maxint
rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
rinstance.setup()
- if rinstance.gcflavor == 'gc':
- vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
if rsubcls.classdef is None:
name = 'object'
else:
@@ -232,7 +214,9 @@
# to self's vtable type."""
def fromtypeptr(self, vcls, llops):
- """Return the type pointer cast to self's vtable type."""
+ """Return a RuntimeTypeInfo or Ptr(OBJECT_VTABLE) cast
+ to self's vtable type.
+ """
self.setup()
castable(self.lowleveltype, vcls.concretetype) # sanity check
return llops.genop('cast_pointer', [vcls],
@@ -296,15 +280,15 @@
class InstanceRepr(AbstractInstanceRepr):
def __init__(self, rtyper, classdef, gcflavor='gc'):
AbstractInstanceRepr.__init__(self, rtyper, classdef)
+ self.gcflavor = gcflavor
if classdef is None:
- self.object_type = OBJECT_BY_FLAVOR[LLFLAVOR[gcflavor]]
+ self.object_type = self.get_base_object_type()
else:
ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]]
self.object_type = ForwardRef()
self.prebuiltinstances = {} # { id(x): (x, _ptr) }
self.lowleveltype = Ptr(self.object_type)
- self.gcflavor = gcflavor
def _setup_repr(self, llfields=None, hints=None, adtmeths=None):
# NOTE: don't store mutable objects like the dicts below on 'self'
@@ -315,7 +299,7 @@
fields = {}
allinstancefields = {}
if self.classdef is None:
- fields['__class__'] = 'typeptr', get_type_repr(self.rtyper)
+ pass
else:
# instance attributes
if llfields is None:
@@ -347,18 +331,18 @@
if '_immutable_' in self.classdef.classdesc.classdict:
hints = hints.copy()
hints['immutable'] = True
+ kwds = {'hints': hints,
+ 'adtmeths': adtmeths}
+ if self.gcflavor == 'gc':
+ kwds['runtime_type_info'] = self.rclass.vtable
object_type = MkStruct(self.classdef.name,
('super', self.rbase.object_type),
- hints=hints,
- adtmeths=adtmeths,
- *llfields)
+ *llfields, **kwds)
self.object_type.become(object_type)
allinstancefields.update(self.rbase.allinstancefields)
allinstancefields.update(fields)
self.fields = fields
self.allinstancefields = allinstancefields
- if self.gcflavor == 'gc':
- attachRuntimeTypeInfo(self.object_type)
def _setup_repr_final(self):
if self.gcflavor == 'gc':
@@ -375,12 +359,14 @@
destrptr = functionptr(FUNCTYPE, graph.name,
graph=graph,
_callable=graph.func)
- else:
- destrptr = None
- OBJECT = OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
- self.rtyper.attachRuntimeTypeInfoFunc(self.object_type,
- ll_runtime_type_info,
- OBJECT, destrptr)
+ rtti = lltype.getRuntimeTypeInfo(self.object_type)
+ rtti = cast_pointer(Ptr(lltype.RuntimeTypeInfo), rtti)
+ rtti.destructor_funcptr = destrptr
+
+ def get_base_object_type(self):
+ return OBJECT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
+ get_base_object_type._annspecialcase_ = 'specialize:memo'
+
def common_repr(self): # -> object or nongcobject reprs
return getinstancerepr(self.rtyper, None, self.gcflavor)
@@ -391,6 +377,7 @@
return cast_pointer(self.lowleveltype, result)
def create_instance(self):
+ self.rclass.getvtable() # force it to be filled
return malloc(self.object_type, flavor=self.gcflavor)
def get_ll_hash_function(self):
@@ -434,9 +421,23 @@
llattrvalue = r.convert_const(attrvalue)
setattr(result, mangled_name, llattrvalue)
else:
- # OBJECT part
- rclass = getclassrepr(self.rtyper, classdef)
- result.typeptr = rclass.getvtable()
+ # OBJECT part: nothing to fill, unless we are a non-GC instance
+ if self.gcflavor != 'gc':
+ rclass = getclassrepr(self.rtyper, classdef)
+ result.typeptr = rclass.getvtable()
+
+ def gettypeptr(self, vinst, llops):
+ if self.gcflavor == 'gc':
+ v_rtti = llops.genop('gc_runtime_type_info', [vinst],
+ resulttype = Ptr(lltype.RuntimeTypeInfo))
+ return llops.genop('cast_pointer', [v_rtti],
+ resulttype = CLASSTYPE)
+ else:
+ v_base = llops.genop('cast_pointer', [vinst],
+ resulttype = NONGCOBJECTPTR)
+ c_typeptr = inputconst(Void, 'typeptr')
+ return llops.genop('getfield', [v_base, c_typeptr],
+ resulttype = CLASSTYPE)
def getfieldrepr(self, attr):
"""Return the repr used for the given attribute."""
@@ -458,13 +459,16 @@
return llops.genop('getfield', [vinst, cname], resulttype=r)
else:
if self.classdef is None:
- raise MissingRTypeAttribute(attr)
+ if attr == '__class__':
+ return self.gettypeptr(vinst, llops)
+ else:
+ raise MissingRTypeAttribute(attr)
return self.rbase.getfield(vinst, attr, llops, force_cast=True,
flags=flags)
def setfield(self, vinst, attr, vvalue, llops, force_cast=False,
flags={}):
- """Write the given attribute (or __class__ for the type) of 'vinst'."""
+ """Write the given attribute of 'vinst'."""
if attr in self.fields:
mangled_name, r = self.fields[attr]
cname = inputconst(Void, mangled_name)
@@ -484,17 +488,14 @@
ctype = inputconst(Void, self.object_type)
cflags = inputconst(Void, flags)
vlist = [ctype, cflags]
+ self.rclass.getvtable() # force it to be filled
vptr = llops.genop('malloc', vlist,
resulttype = Ptr(self.object_type))
- ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable())
- self.setfield(vptr, '__class__', ctypeptr, llops)
# initialize instance attributes from their defaults from the class
if self.classdef is not None:
flds = self.allinstancefields.keys()
flds.sort()
for fldname in flds:
- if fldname == '__class__':
- continue
mangled_name, r = self.allinstancefields[fldname]
if r.lowleveltype is Void:
continue
@@ -522,10 +523,13 @@
def rtype_getattr(self, hop):
attr = hop.args_s[1].const
vinst, vattr = hop.inputargs(self, Void)
- if attr == '__class__' and hop.r_result.lowleveltype is Void:
- # special case for when the result of '.__class__' is a constant
- [desc] = hop.s_result.descriptions
- return hop.inputconst(Void, desc.pyobj)
+ if attr == '__class__':
+ if hop.r_result.lowleveltype is Void:
+ # special case for when the result of '.__class__' is a const
+ [desc] = hop.s_result.descriptions
+ return hop.inputconst(Void, desc.pyobj)
+ else:
+ return self.getfield(vinst, '__class__', hop.llops)
if attr in self.allinstancefields:
return self.getfield(vinst, attr, hop.llops,
flags=hop.args_s[0].flags)
@@ -549,19 +553,21 @@
vinst, = hop.inputargs(self)
return hop.genop('ptr_nonzero', [vinst], resulttype=Bool)
- def ll_str(self, i): # doesn't work for non-gc classes!
+ def ll_str(self, i):
from pypy.rpython.lltypesystem import rstr
from pypy.rpython.lltypesystem.ll_str import ll_int2hex
from pypy.rlib.rarithmetic import r_uint
if not i:
return rstr.null_str
- instance = cast_pointer(OBJECTPTR, i)
+ BASEPTR = Ptr(self.get_base_object_type())
+ instance = cast_pointer(BASEPTR, i)
+ vtable = instance.gettypeptr()
uid = r_uint(cast_ptr_to_int(i))
- nameLen = len(instance.typeptr.name)
+ nameLen = len(vtable.name)
nameString = rstr.mallocstr(nameLen-1)
i = 0
while i < nameLen - 1:
- nameString.chars[i] = instance.typeptr.name[i]
+ nameString.chars[i] = vtable.name[i]
i += 1
res = rstr.instance_str_prefix
res = rstr.ll_strconcat(res, nameString)
@@ -667,7 +673,7 @@
# doesn't work for non-gc stuff!
def ll_type(obj):
- return cast_pointer(OBJECTPTR, obj).typeptr
+ return cast_pointer(OBJECTPTR, obj).gettypeptr()
def ll_issubclass(subcls, cls):
return cls.subclassrange_min <= subcls.subclassrange_min <= cls.subclassrange_max
@@ -679,23 +685,20 @@
def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT
if not obj:
return False
- obj_cls = obj.typeptr
+ obj_cls = obj.gettypeptr()
return ll_issubclass(obj_cls, cls)
def ll_isinstance_const(obj, minid, maxid):
if not obj:
return False
- return ll_issubclass_const(obj.typeptr, minid, maxid)
+ return ll_issubclass_const(obj.gettypeptr(), minid, maxid)
def ll_isinstance_exact(obj, cls):
if not obj:
return False
- obj_cls = obj.typeptr
+ obj_cls = obj.gettypeptr()
return obj_cls == cls
-def ll_runtime_type_info(obj):
- return obj.typeptr.rtti
-
def ll_inst_hash(ins):
if not ins:
return 0 # for None
@@ -710,10 +713,10 @@
def ll_inst_type(obj):
if obj:
- return obj.typeptr
+ return obj.gettypeptr()
else:
# type(None) -> NULL (for now)
- return nullptr(typeOf(obj).TO.typeptr.TO)
+ return nullptr(CLASSTYPE.TO)
def ll_both_none(ins1, ins2):
return not ins1 and not ins2
Modified: pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/lltypesystem/test/test_lltype.py Mon Feb 18 20:34:37 2008
@@ -373,8 +373,8 @@
t2.v = 33
S2 = GcStruct('S2', ('parent', S1), ('y', Signed), runtime_type_info=t2)
- assert getRuntimeTypeInfo(S1) == t1
- assert getRuntimeTypeInfo(S2) == t2
+ assert getRuntimeTypeInfo(S1) == t1.base
+ assert getRuntimeTypeInfo(S2) == t2.base.base
x1 = malloc(S1)
x2 = malloc(S2)
@@ -388,7 +388,7 @@
py.test.raises(TypeError, getRuntimeTypeInfo, S1bis)
cache = {}
- assert getRuntimeTypeInfo(S1, cache=cache) == t1
+ assert getRuntimeTypeInfo(S1, cache=cache) == t1.base
t1bis = getRuntimeTypeInfo(S1bis, cache=cache)
assert t1bis != t1.base
assert getRuntimeTypeInfo(S1bis, cache=cache) == t1bis
@@ -402,9 +402,16 @@
"destructor_funcptr",
_callable=f)
pinf = getRuntimeTypeInfo(S)
- assert pinf._obj.destructor_funcptr == nullptr(FuncType([Ptr(S)], Void))
- pinf._obj.destructor_funcptr = dp
- assert pinf._obj.destructor_funcptr == dp
+ assert pinf.destructor_funcptr is None
+ pinf.destructor_funcptr = dp
+ assert pinf.destructor_funcptr == dp
+
+ S1 = GcStruct('s1', ('super', S),
+ runtime_type_info=malloc(RuntimeTypeInfo, immortal=True))
+ pinf1 = getRuntimeTypeInfo(S1)
+ assert pinf1.destructor_funcptr is None
+ pinf1.destructor_funcptr = dp
+ assert pinf1.destructor_funcptr == dp
def test_flavor_malloc():
def isweak(p, T):
Modified: pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/rbuiltin.py Mon Feb 18 20:34:37 2008
@@ -476,7 +476,7 @@
def rtype_runtime_type_info(hop):
assert isinstance(hop.args_r[0], rptr.PtrRepr)
vlist = hop.inputargs(hop.args_r[0])
- return hop.genop('runtime_type_info', vlist,
+ return hop.genop('gc_runtime_type_info', vlist,
resulttype = hop.r_result.lowleveltype)
BUILTIN_TYPER[lltype.malloc] = rtype_malloc
@@ -484,6 +484,7 @@
BUILTIN_TYPER[lltype.cast_primitive] = rtype_cast_primitive
BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer
BUILTIN_TYPER[lltype.cast_opaque_ptr] = rtype_cast_opaque_ptr
+BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info
BUILTIN_TYPER[lltype.direct_fieldptr] = rtype_direct_fieldptr
BUILTIN_TYPER[lltype.direct_arrayitems] = rtype_direct_arrayitems
BUILTIN_TYPER[lltype.direct_ptradd] = rtype_direct_ptradd
@@ -491,9 +492,7 @@
BUILTIN_TYPER[lltype.cast_int_to_ptr] = rtype_cast_int_to_ptr
BUILTIN_TYPER[lltype.typeOf] = rtype_const_result
BUILTIN_TYPER[lltype.nullptr] = rtype_const_result
-BUILTIN_TYPER[lltype.getRuntimeTypeInfo] = rtype_const_result
BUILTIN_TYPER[lltype.Ptr] = rtype_const_result
-BUILTIN_TYPER[lltype.runtime_type_info] = rtype_runtime_type_info
BUILTIN_TYPER[rarithmetic.intmask] = rtype_intmask
BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated
Modified: pypy/branch/unified-rtti/pypy/rpython/rtyper.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/rtyper.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/rtyper.py Mon Feb 18 20:34:37 2008
@@ -21,8 +21,8 @@
from pypy.rpython.lltypesystem.lltype import \
Signed, Unsigned, Float, Char, Bool, Void, \
LowLevelType, Ptr, ContainerType, \
- FuncType, functionptr, typeOf, RuntimeTypeInfo, \
- attachRuntimeTypeInfo, Primitive, Number
+ FuncType, functionptr, typeOf, \
+ Primitive, Number
from pypy.rpython.ootypesystem import ootype
from pypy.translator.unsimplify import insert_empty_block
from pypy.rpython.error import TyperError
@@ -648,21 +648,6 @@
graph = self.annotate_helper(ll_function, argtypes)
return self.getcallable(graph)
- def attachRuntimeTypeInfoFunc(self, GCSTRUCT, func, ARG_GCSTRUCT=None,
- destrptr=None):
- self.call_all_setups() # compute ForwardReferences now
- if ARG_GCSTRUCT is None:
- ARG_GCSTRUCT = GCSTRUCT
- args_s = [annmodel.SomePtr(Ptr(ARG_GCSTRUCT))]
- graph = self.annotate_helper(func, args_s)
- s = self.annotator.binding(graph.getreturnvar())
- if (not isinstance(s, annmodel.SomePtr) or
- s.ll_ptrtype != Ptr(RuntimeTypeInfo)):
- raise TyperError("runtime type info function %r returns %r, "
- "excepted Ptr(RuntimeTypeInfo)" % (func, s))
- funcptr = self.getcallable(graph)
- attachRuntimeTypeInfo(GCSTRUCT, funcptr, destrptr)
-
# register operations from annotation model
RPythonTyper._registeroperations(annmodel)
Modified: pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py
==============================================================================
--- pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py (original)
+++ pypy/branch/unified-rtti/pypy/rpython/test/test_rclass.py Mon Feb 18 20:34:37 2008
@@ -650,8 +650,7 @@
graph = graphof(t, f)
TYPE = graph.startblock.operations[0].args[0].value
RTTI = getRuntimeTypeInfo(TYPE)
- queryptr = RTTI._obj.query_funcptr # should not raise
- destrptr = RTTI._obj.destructor_funcptr
+ destrptr = RTTI.destructor_funcptr
assert destrptr is not None
def test_del_inheritance(self):
@@ -681,19 +680,18 @@
t = TranslationContext()
t.buildannotator().build_types(f, [])
t.buildrtyper().specialize()
- graph = graphof(t, f)
- TYPEA = graph.startblock.operations[0].args[0].value
+
+ from pypy.rpython.rclass import getinstancerepr
+ getcdef = t.annotator.bookkeeper.getuniqueclassdef
+ TYPEA = getinstancerepr(t.rtyper, getcdef(A)).lowleveltype.TO
RTTIA = getRuntimeTypeInfo(TYPEA)
- TYPEB = graph.startblock.operations[3].args[0].value
+ TYPEB = getinstancerepr(t.rtyper, getcdef(B)).lowleveltype.TO
RTTIB = getRuntimeTypeInfo(TYPEB)
- TYPEC = graph.startblock.operations[6].args[0].value
+ TYPEC = getinstancerepr(t.rtyper, getcdef(C)).lowleveltype.TO
RTTIC = getRuntimeTypeInfo(TYPEC)
- queryptra = RTTIA._obj.query_funcptr # should not raise
- queryptrb = RTTIB._obj.query_funcptr # should not raise
- queryptrc = RTTIC._obj.query_funcptr # should not raise
- destrptra = RTTIA._obj.destructor_funcptr
- destrptrb = RTTIB._obj.destructor_funcptr
- destrptrc = RTTIC._obj.destructor_funcptr
+ destrptra = RTTIA.destructor_funcptr
+ destrptrb = RTTIB.destructor_funcptr
+ destrptrc = RTTIC.destructor_funcptr
assert destrptra == destrptrc
assert typeOf(destrptra).TO.ARGS[0] != typeOf(destrptrb).TO.ARGS[0]
assert destrptra is not None
More information about the Pypy-commit
mailing list