[pypy-svn] r37225 - in pypy/dist/pypy: jit/timeshifter jit/timeshifter/test rpython/lltypesystem rpython/lltypesystem/test

pedronis at codespeak.net pedronis at codespeak.net
Tue Jan 23 19:19:23 CET 2007


Author: pedronis
Date: Tue Jan 23 19:19:21 2007
New Revision: 37225

Modified:
   pypy/dist/pypy/jit/timeshifter/hrtyper.py
   pypy/dist/pypy/jit/timeshifter/rcontainer.py
   pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
   pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py
Log:
(arre, pedronis) start support virtualizables structs corresponding to class hierarchies, with simple test.

The code starts to really need some refactoring.



Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py	Tue Jan 23 19:19:21 2007
@@ -1634,6 +1634,13 @@
 class RedStructRepr(RedRepr):
     typedesc = None
 
+    def residual_args_collector(self):
+        typedesc = self.gettypedesc()
+        if typedesc.virtualizable:
+            return typedesc.collect_residual_args
+        else:
+            return self.collect_residual_args
+
     def build_portal_arg_helpers(self):
         T = self.original_concretetype.TO
         if not T._hints.get('virtualizable', False):
@@ -1644,14 +1651,6 @@
         names = unrolling_iterable([(fielddesc.fieldname, j)
                                     for (fielddesc, j) in typedesc.redirected_fielddescs])
 
-        def collect_residual_args(v): 
-            t = (v,)
-            assert not v.vable_access
-            for name, _ in names:
-                t = t + (getattr(v, name),) # xxx need to use access ?
-            return t
-        self.collect_residual_args = collect_residual_args
-
         TYPE = self.original_concretetype
         kind = self.hrtyper.RGenOp.kindToken(TYPE)
         boxcls = rvalue.ll_redboxcls(TYPE)
@@ -1693,7 +1692,7 @@
             getredrepr = self.hrtyper.getredrepr
             typedesc = self.gettypedesc()
             for fielddesc, _ in typedesc.redirected_fielddescs:
-                FIELDTYPE = getattr(T, fielddesc.fieldname)
+                FIELDTYPE = fielddesc.RESTYPE
                 argtypes += getredrepr(FIELDTYPE).residual_argtypes()
         return argtypes
 

Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py	Tue Jan 23 19:19:21 2007
@@ -51,8 +51,9 @@
                  gv_access_is_null_ptr access_is_null_token
               """.split()
 
+    firstsubstructdesc = None
     materialize = None
-    
+   
     def __init__(self, hrtyper, TYPE):
         RGenOp = hrtyper.RGenOp
         self.TYPE = TYPE
@@ -106,16 +107,33 @@
         self.null = self.PTRTYPE._defl()
         self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
 
+
+        if self.immutable and self.noidentity:
+            
+            def materialize(rgenop, boxes):
+                s = lltype.malloc(TYPE)
+                i = 0
+                for desc in descs:
+                    v = rvalue.ll_getvalue(boxes[i], desc.RESTYPE)
+                    setattr(s, desc.fieldname, v)
+                    i = i + 1
+                return rgenop.genconst(s)
+
+            self.materialize = materialize
+
         self.virtualizable = TYPE._hints.get('virtualizable', False)
         if self.virtualizable:
             self.VStructCls = VirtualizableStruct
             self.base_desc = self.getfielddesc('vable_base')
             self.info_desc = self.getfielddesc('vable_info')
             self.access_desc = self.getfielddesc('vable_access')
-            ACCESS = TYPE.vable_access.TO
+            ACCESS = TYPE.ACCESS
             redirected_fields = ACCESS.redirected_fields
+            print self.PTRTYPE, redirected_fields
             access = lltype.malloc(ACCESS, immortal=True)
             self.gv_access = RGenOp.constPrebuiltGlobal(access)
+            TOPPTR = self.access_desc.PTRTYPE
+            s_structtype = annmodel.lltype_to_annotation(TOPPTR)
             annhelper = hrtyper.annhelper
             j = 0
             def make_get_field(T, j):
@@ -126,15 +144,20 @@
                     return vable_info.read_field(fielddesc,
                                                  struc.vable_base, j)
                 return get_field
-            s_structtype = annmodel.lltype_to_annotation(self.PTRTYPE)
+            
             self.redirected_fielddescs = redirected_fieldescs = []
             i = -1
+            my_redirected_names = []
+            self.my_redirected_getters = {}
             for fielddesc in fielddescs:
                 i += 1
                 name = fielddesc.fieldname
                 if name not in redirected_fields:
-                   continue
+                    continue
                 redirected_fieldescs.append((fielddesc, i))
+                if fielddesc.PTRTYPE != self.PTRTYPE:
+                    continue
+                my_redirected_names.append(name)
                 get_field = make_get_field(fielddesc, j)
                 j += 1
                 s_lltype = annmodel.lltype_to_annotation(fielddesc.RESTYPE)
@@ -142,7 +165,10 @@
                                                           [s_structtype],
                                                           s_lltype,
                                                           needtype = True)
-                setattr(access, 'get_'+name, get_field_ptr)
+                self.my_redirected_getters[name] = get_field_ptr
+
+            self.fill_access(access)
+
             def access_is_null(struc):
                 assert not struc.vable_access
             access_is_null_ptr = annhelper.delayedfunction(access_is_null,
@@ -154,21 +180,32 @@
             self.access_is_null_token =  RGenOp.sigToken(
                                      lltype.typeOf(access_is_null_ptr).TO)
 
-        else:
-            self.VStructCls = VirtualStruct
+            my_redirected_names = unrolling_iterable(my_redirected_names)
 
-        if self.immutable and self.noidentity:
-            
-            def materialize(rgenop, boxes):
-                s = lltype.malloc(TYPE)
-                i = 0
-                for desc in descs:
-                    v = rvalue.ll_getvalue(boxes[i], desc.RESTYPE)
-                    setattr(s, desc.fieldname, v)
-                    i = i + 1
-                return rgenop.genconst(s)
+            if TOPPTR == self.PTRTYPE:
+                _super_collect = None
+            else:
+                _super_collect = self.firstsubstructdesc._collect_residual_args
 
-            self.materialize = materialize
+            def _collect_residual_args(v): 
+                if _super_collect is None:
+                    assert not v.vable_access  # xxx need to use access ?
+                    t = ()
+                else:
+                    t = _super_collect(v.super)
+                for name in my_redirected_names:
+                    t = t + (getattr(v, name),)
+                return t
+
+            self._collect_residual_args = _collect_residual_args
+
+            def collect_residual_args(v): 
+                t = (v,) + _collect_residual_args(v)
+                return t
+
+            self.collect_residual_args = collect_residual_args
+        else:
+            self.VStructCls = VirtualStruct
 
         # xxx
         self.gv_make_vinfo_ptr = hrtyper.gv_make_vinfo_ptr
@@ -189,9 +226,20 @@
 
         self.gv_vinfo_read_forced_ptr = hrtyper.gv_vinfo_read_forced_ptr
         self.vinfo_read_forced_token = hrtyper.vinfo_read_forced_token
+
+    def fill_access(self, access):
+        firstsubstructdesc = self.firstsubstructdesc
+        if (firstsubstructdesc is not None and 
+            firstsubstructdesc.virtualizable):
+            firstsubstructdesc.fill_access(access.parent)
+        for name, get_field_ptr in self.my_redirected_getters.iteritems():
+            setattr(access, 'get_'+name, get_field_ptr)
         
     def getfielddesc(self, name):
-        return self.fielddesc_by_name[name]
+        try:
+            return self.fielddesc_by_name[name]
+        except KeyError:
+            return self.firstsubstructdesc.getfielddesc(name)
 
     def factory(self):
         vstruct = self.VStructCls(self)

Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py	Tue Jan 23 19:19:21 2007
@@ -62,7 +62,8 @@
                           ('vable_access', lltype.Ptr(XY_ACCESS)),
                           ('x', lltype.Signed),
                           ('y', lltype.Signed),
-                          hints = {'virtualizable': True}
+                          hints = {'virtualizable': True},
+                          adtmeths = {'ACCESS': XY_ACCESS},
               ))
 
 E = lltype.GcStruct('e', ('xy', lltype.Ptr(XY)),
@@ -77,7 +78,8 @@
                           ('vable_access', lltype.Ptr(XP_ACCESS)),
                           ('x', lltype.Signed),
                           ('p', PS),
-                          hints = {'virtualizable': True}
+                          hints = {'virtualizable': True},
+                          adtmeths = {'ACCESS': XP_ACCESS},
               ))
 xp_get_x, xp_set_x = getset('x')
 xp_get_p, xp_set_p = getset('p')
@@ -101,7 +103,8 @@
                           ('vable_access', lltype.Ptr(PQ_ACCESS)),
                           ('p', PS),
                           ('q', PS),
-                          hints = {'virtualizable': True}
+                          hints = {'virtualizable': True},
+                          adtmeths = {'ACCESS': PQ_ACCESS},
               ))
 pq_get_p, pq_set_p = getset('p')
 pq_get_q, pq_set_q = getset('q')
@@ -681,3 +684,29 @@
         res = self.timeshift_from_portal(main, f, [20, 22], policy=P_OOPSPEC)
         assert res == 42
         self.check_insns(getfield=0)
+
+    def test_simple_inheritance(self):
+
+        class X(object):
+            _virtualizable_ = True
+            
+            def __init__(self, x):
+                self.x = x
+
+        class XY(X):
+
+            def __init__(self, x, y):
+                X.__init__(self, x)
+                self.y = y
+   
+        def f(xy):
+            return xy.x+xy.y
+
+        def main(x, y):
+            X(0)
+            xy = XY(x, y)
+            return f(xy)
+
+        res = self.timeshift_from_portal(main, f, [20, 22], policy=P_OOPSPEC)
+        assert res == 42
+        self.check_insns(getfield=0)

Modified: pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py	Tue Jan 23 19:19:21 2007
@@ -38,15 +38,17 @@
                 raise TyperError("virtulizable class cannot have"
                                  " non-virtualizable base class with instance"
                                  " fields: %r" % self.classdef)
+            redirected_fields = []
+
         else:
             accessors.append(('parent', rbase.ACCESS))
+            redirected_fields = list(rbase.ACCESS.redirected_fields)
         name = self.lowleveltype.TO._name
-        SELF = self.lowleveltype
-        redirected_fields = []
+        TOPPTR = self.get_top_virtualizable_type()
         for name, (mangled_name, r) in self.fields.items():
             T = r.lowleveltype
-            GETTER = lltype.Ptr(lltype.FuncType([SELF], T))
-            SETTER = lltype.Ptr(lltype.FuncType([SELF, T], lltype.Void))
+            GETTER = lltype.Ptr(lltype.FuncType([TOPPTR], T))
+            SETTER = lltype.Ptr(lltype.FuncType([TOPPTR, T], lltype.Void))
             accessors.append(('get_'+mangled_name, GETTER))
             accessors.append(('set_'+mangled_name, SETTER))
             redirected_fields.append(mangled_name)
@@ -93,7 +95,7 @@
             access = top.vable_access
             if access:
                 return getattr(lltype.cast_pointer(ACCESSPTR, access),
-                               'get_'+name)(inst)
+                               'get_'+name)(top)
             else:
                 return getattr(inst, name)
         ll_getter.oopspec = 'vable.get_%s(inst)' % name
@@ -112,7 +114,7 @@
             access = top.vable_access
             if access:
                 return getattr(lltype.cast_pointer(ACCESSPTR, access),
-                               'set_'+name)(inst, value)
+                               'set_'+name)(top, value)
             else:
                 return setattr(inst, name, value)
         ll_setter.oopspec = 'vable.set_%s(inst, value)' % name

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rvirtualizable.py	Tue Jan 23 19:19:21 2007
@@ -118,7 +118,7 @@
         return value
 
     def getv1(vinst):
-        value = vinst.inst_v1
+        value = lltype.normalizeptr(vinst).inst_v1
         witness.append(value)
         return value    
 



More information about the Pypy-commit mailing list