[pypy-svn] r32081 - in pypy/branch/more-gckinds/pypy: annotation rpython rpython/lltypesystem

mwh at codespeak.net mwh at codespeak.net
Fri Sep 8 13:45:05 CEST 2006


Author: mwh
Date: Fri Sep  8 13:45:02 2006
New Revision: 32081

Modified:
   pypy/branch/more-gckinds/pypy/annotation/model.py
   pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py
   pypy/branch/more-gckinds/pypy/rpython/lltypesystem/rclass.py
   pypy/branch/more-gckinds/pypy/rpython/rptr.py
Log:
add annotation and lltype support for special handling of interior pointers.
no rtyping support at all yet, so lots of tests fail.


Modified: pypy/branch/more-gckinds/pypy/annotation/model.py
==============================================================================
--- pypy/branch/more-gckinds/pypy/annotation/model.py	(original)
+++ pypy/branch/more-gckinds/pypy/annotation/model.py	Fri Sep  8 13:45:02 2006
@@ -515,6 +515,11 @@
     def can_be_none(self):
         return False
 
+class SomeInteriorPtr(SomePtr):
+    def __init__(self, ll_ptrtype):
+        assert isinstance(ll_ptrtype, lltype.InteriorPtr)
+        self.ll_ptrtype = ll_ptrtype
+        
 class SomeLLADTMeth(SomeObject):
     immutable = True
     def __init__(self, ll_ptrtype, func):
@@ -596,6 +601,8 @@
             return SomeOOClass(ootype.ROOT)
         elif isinstance(T, ExternalType):
             return SomeExternalBuiltin(T)
+        elif isinstance(T, lltype.InteriorPtr):
+            return SomeInteriorPtr(T)
         else:
             return SomePtr(T)
     else:

Modified: pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py	Fri Sep  8 13:45:02 2006
@@ -619,6 +619,23 @@
         o = self.TO._container_example()
         return _ptr(self, o, solid=True)
 
+class InteriorPtr(LowLevelType):
+    def __init__(self, PARENTTYPE, TO, offsets):
+        self.PARENTTYPE = PARENTTYPE
+        self.TO = TO
+        self.offsets = tuple(offsets)
+    def __str__(self):
+        return '%s (%s).%s'%(self.__class__.__name__,
+                             self.PARENTTYPE._short_name(),
+                             '.'.join(map(str, self.offsets)))
+    def _example(self):
+        ob = self.PARENTTYPE._container_example()
+        for o in self.offsets:
+            if isinstance(o, str):
+                ob = ob._getattr(o)
+            else:
+                ob = ob.getitem(0)
+        return ob
 
 # ____________________________________________________________
 
@@ -824,13 +841,6 @@
     parent, base = parentlink(ptr._obj)
     return _subarray._makeptr(parent, base + n, ptr._solid)
 
-def _expose(val, solid=False):
-    """XXX A nice docstring here"""
-    T = typeOf(val)
-    if isinstance(T, ContainerType):
-        val = _ptr(Ptr(T), val, solid=solid)
-    return val
-
 def parentlink(container):
     parent = container._parentstructure()
     if parent is not None:
@@ -877,26 +887,14 @@
 class UninitializedMemoryAccess(Exception):
     pass
 
-class _ptr(object):
-    __slots__ = ('_TYPE', '_T', 
-                 '_weak', '_solid',
-                 '_obj0', '__weakref__')
+class _abstract_ptr(object):
+    __slots__ = ('_T',)
 
-    def _set_TYPE(self, TYPE):
-        _ptr._TYPE.__set__(self, TYPE)
+    # assumes one can access _TYPE, _expose and _obj
 
     def _set_T(self, T):
         _ptr._T.__set__(self, T)
 
-    def _set_weak(self, weak):
-        _ptr._weak.__set__(self, weak)
-
-    def _set_solid(self, solid):
-        _ptr._solid.__set__(self, solid)
-
-    def _set_obj0(self, obj):
-        _ptr._obj0.__set__(self, obj)
-
     def _togckind(self):
         return self._T._gckind
 
@@ -904,19 +902,8 @@
         # XXX deprecated interface
         return self._TYPE._needsgc() # xxx other rules?
 
-    def __init__(self, TYPE, pointing_to, solid=False):
-        self._set_TYPE(TYPE)
-        self._set_T(TYPE.TO)
-        self._set_weak(False)
-        self._setobj(pointing_to, solid)
-
-    def _become(self, other):
-        assert self._TYPE == other._TYPE
-        assert not self._weak
-        self._setobj(other._obj, other._solid)
-
     def __eq__(self, other):
-        if not isinstance(other, _ptr):
+        if type(self) is not type(other):
             raise TypeError("comparing pointer with %r object" % (
                 type(other).__name__,))
         if self._TYPE != other._TYPE:
@@ -938,40 +925,11 @@
         except DelayedPointer:
             return True    # assume it's not a delayed null
 
-    # _setobj, _getobj and _obj0 are really _internal_ implementations details of _ptr,
-    # use _obj if necessary instead !
-    def _setobj(self, pointing_to, solid=False):        
-        if pointing_to is None:
-            obj0 = None
-        elif (solid or self._T._gckind != 'raw' or
-              isinstance(self._T, FuncType)):
-            obj0 = pointing_to
-        else:
-            self._set_weak(True)
-            obj0 = pickleable_weakref(pointing_to)
-        self._set_solid(solid)
-        self._set_obj0(obj0)
-        
-    def _getobj(self):
-        obj = self._obj0
-        if obj is not None:
-            if self._weak:
-                obj = obj()
-                if obj is None:
-                    raise RuntimeError("accessing already garbage collected %r"
-                                   % (self._T,))
-            if isinstance(obj, _container):
-                obj._check()
-            elif isinstance(obj, str) and obj.startswith("delayed!"):
-                raise DelayedPointer
-        return obj
-    _obj = property(_getobj)
-
     def __getattr__(self, field_name): # ! can only return basic or ptr !
         if isinstance(self._T, Struct):
             if field_name in self._T._flds:
                 o = self._obj._getattr(field_name)
-                return _expose(o, self._solid)
+                return self._expose(field_name, o)
         if isinstance(self._T, ContainerType):
             try:
                 adtmeth = self._T._adtmeths[field_name]
@@ -987,20 +945,6 @@
         raise AttributeError("%r instance has no field %r" % (self._T,
                                                               field_name))
 
-    #def _setfirst(self, p):
-    #    if isinstance(self._T, Struct) and self._T._names:
-    #        if not isinstance(p, _ptr) or not isinstance(p._obj, _struct):
-    #            raise InvalidCast(typeOf(p), typeOf(self))
-    #        field_name = self._T._names[0]
-    #        T1 = self._T._flds[field_name]
-    #        T2 = typeOf(p._obj)
-    #        if T1 != T2:
-    #            raise InvalidCast(typeOf(p), typeOf(self))
-    #        setattr(self._obj, field_name, p._obj)
-    #        p._obj._setparentstructure(self._obj, 0)
-    #        return
-    #    raise TypeError("%r instance has no first field" % (self._T,))
-
     def __setattr__(self, field_name, val):
         if isinstance(self._T, Struct):
             if field_name in self._T._flds:
@@ -1024,7 +968,7 @@
                     raise TypeError("array slicing not supported")
                 raise IndexError("array index out of bounds")
             o = self._obj.getitem(i)
-            return _expose(o, self._solid)
+            return self._expose(i, o)
         raise TypeError("%r instance is not an array" % (self._T,))
 
     def __setitem__(self, i, val):
@@ -1087,6 +1031,64 @@
     __getstate__ = getstate_with_slots
     __setstate__ = setstate_with_slots
 
+class _ptr(_abstract_ptr):
+    __slots__ = ('_TYPE', 
+                 '_weak', '_solid',
+                 '_obj0', '__weakref__')
+
+    def _set_TYPE(self, TYPE):
+        _ptr._TYPE.__set__(self, TYPE)
+
+    def _set_weak(self, weak):
+        _ptr._weak.__set__(self, weak)
+
+    def _set_solid(self, solid):
+        _ptr._solid.__set__(self, solid)
+
+    def _set_obj0(self, obj):
+        _ptr._obj0.__set__(self, obj)
+
+    def __init__(self, TYPE, pointing_to, solid=False):
+        self._set_TYPE(TYPE)
+        self._set_T(TYPE.TO)
+        self._set_weak(False)
+        self._setobj(pointing_to, solid)
+
+    def _become(self, other):
+        assert self._TYPE == other._TYPE
+        assert not self._weak
+        self._setobj(other._obj, other._solid)
+
+
+    # _setobj, _getobj and _obj0 are really _internal_ implementations details of _ptr,
+    # use _obj if necessary instead !
+    def _setobj(self, pointing_to, solid=False):        
+        if pointing_to is None:
+            obj0 = None
+        elif (solid or self._T._gckind != 'raw' or
+              isinstance(self._T, FuncType)):
+            obj0 = pointing_to
+        else:
+            self._set_weak(True)
+            obj0 = pickleable_weakref(pointing_to)
+        self._set_solid(solid)
+        self._set_obj0(obj0)
+        
+    def _getobj(self):
+        obj = self._obj0
+        if obj is not None:
+            if self._weak:
+                obj = obj()
+                if obj is None:
+                    raise RuntimeError("accessing already garbage collected %r"
+                                   % (self._T,))
+            if isinstance(obj, _container):
+                obj._check()
+            elif isinstance(obj, str) and obj.startswith("delayed!"):
+                raise DelayedPointer
+        return obj
+    _obj = property(_getobj)
+
     def _cast_to(self, PTRTYPE):
         CURTYPE = self._TYPE
         down_or_up = castable(PTRTYPE, CURTYPE)
@@ -1148,8 +1150,66 @@
     def _as_obj(self):
         return self._obj
 
+    def _expose(self, offset, val):
+        """XXX A nice docstring here"""
+        T = typeOf(val)
+        if isinstance(T, ContainerType):
+            if T._gckind == 'raw':
+                val = _interior_ptr(T, self._obj, [offset])
+            else:
+                val = _ptr(Ptr(T), val, solid=self._solid)
+        return val
+
 assert not '__dict__' in dir(_ptr)
 
+class _interior_ptr(_abstract_ptr):
+    __slots__ = ('_parent', '_offsets')
+    def _set_parent(self, _parent):
+        _interior_ptr._parent.__set__(self, _parent)
+    def _set_offsets(self, _offsets):
+        _interior_ptr._offsets.__set__(self, _offsets)
+
+    def __init__(self, _T, _parent, _offsets):
+        self._set_T(_T)
+        #self._set_parent(weakref.ref(_parent))
+        self._set_parent(_parent)
+        self._set_offsets(_offsets)
+
+    def _get_obj(self):
+        ob = self._parent
+        if ob is None:
+            raise RuntimeError
+        for o in self._offsets:
+            if isinstance(o, int):
+                ob = ob.getitem(o)
+            elif isinstance(o, str):
+                ob = ob._getattr(o)
+            else:
+                1/0
+        return ob
+    _obj = property(_get_obj)
+
+    def _get_TYPE(self):
+        ob = self._parent
+        if ob is None:
+            raise RuntimeError
+        return InteriorPtr(typeOf(ob), self._T, self._offsets)
+    _TYPE = property(_get_TYPE)
+
+    def _expose(self, offset, val):
+        """XXX A nice docstring here"""
+        T = typeOf(val)
+        if isinstance(T, ContainerType):
+            if T._gckind == 'raw':
+                val = _interior_ptr(T, self._parent, self._offsets + [offset])
+            else:
+                1/0
+        return val
+    
+    
+        
+assert not '__dict__' in dir(_interior_ptr)
+
 class _container(object):
     __slots__ = ()
     def _parentstructure(self):

Modified: pypy/branch/more-gckinds/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/more-gckinds/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/branch/more-gckinds/pypy/rpython/lltypesystem/rclass.py	Fri Sep  8 13:45:02 2006
@@ -55,11 +55,11 @@
 #
 # there's also a nongcobject 
 
-OBJECT_VTABLE = lltype.ForwardReference()
+OBJECT_VTABLE = lltype.GcForwardReference()
 CLASSTYPE = Ptr(OBJECT_VTABLE)
 OBJECT = GcStruct('object', ('typeptr', CLASSTYPE))
 OBJECTPTR = Ptr(OBJECT)
-OBJECT_VTABLE.become(Struct('object_vtable',
+OBJECT_VTABLE.become(GcStruct('object_vtable',
                             ('parenttypeptr', CLASSTYPE),
                             ('subclassrange_min', Signed),
                             ('subclassrange_max', Signed),
@@ -100,7 +100,7 @@
             # 'object' root type
             self.vtable_type = OBJECT_VTABLE
         else:
-            self.vtable_type = lltype.ForwardReference()
+            self.vtable_type = lltype.GcForwardReference()
         self.lowleveltype = Ptr(self.vtable_type)
 
     def _setup_repr(self):
@@ -139,7 +139,7 @@
             self.rbase = getclassrepr(self.rtyper, self.classdef.basedef)
             self.rbase.setup()
             kwds = {'hints': {'immutable': True}}
-            vtable_type = Struct('%s_vtable' % self.classdef.name,
+            vtable_type = GcStruct('%s_vtable' % self.classdef.name,
                                  ('super', self.rbase.vtable_type),
                                  *llfields, **kwds)
             self.vtable_type.become(vtable_type)

Modified: pypy/branch/more-gckinds/pypy/rpython/rptr.py
==============================================================================
--- pypy/branch/more-gckinds/pypy/rpython/rptr.py	(original)
+++ pypy/branch/more-gckinds/pypy/rpython/rptr.py	Fri Sep  8 13:45:02 2006
@@ -19,6 +19,12 @@
 ##        else:
         return self.__class__, self.ll_ptrtype
 
+class __extend__(annmodel.SomeInteriorPtr):
+    def rtyper_makerepr(self, rtyper):
+##        if self.is_constant() and not self.const:   # constant NULL
+##            return nullptr_repr
+##        else:
+        return InteriorPtrRepr(self.ll_ptrtype)
 
 class PtrRepr(Repr):
 



More information about the Pypy-commit mailing list