[pypy-svn] r13050 - pypy/branch/rpython-refactoring

arigo at codespeak.net arigo at codespeak.net
Sat Jun 4 12:10:50 CEST 2005


Author: arigo
Date: Sat Jun  4 12:10:50 2005
New Revision: 13050

Modified:
   pypy/branch/rpython-refactoring/rclass.py
   pypy/branch/rpython-refactoring/rpbc.py
Log:
A nice and clean -- if still quite strange -- version of rclass.py.


Modified: pypy/branch/rpython-refactoring/rclass.py
==============================================================================
--- pypy/branch/rpython-refactoring/rclass.py	(original)
+++ pypy/branch/rpython-refactoring/rclass.py	Sat Jun  4 12:10:50 2005
@@ -37,99 +37,153 @@
 OBJECT = GcStruct('object', ('typeptr', TYPEPTR))
 
 
-class RClassDef:
-
-    def __init__(self, classdef):
-        self.classdef = classdef
-        if classdef.basedef is None:
-            self.depth = 1
-            parent_vtable_type = OBJECT_VTABLE
-            parent_typeptr = nullptr(OBJECT_VTABLE)
-            parent_object_type = OBJECT
-        else:
-            rbasedef = getrclassdef(classdef.basedef)
-            self.depth = rbasedef.depth + 1
-            parent_vtable_type = rbasedef.vtable_type
-            parent_typeptr = rbasedef.typeptr
-            parent_object_type = rbasedef.object_type
-        self.vtable_type = Struct('%s_vtable' % classdef.cls.__name__,
-                                  ('super', parent_vtable_type),
-                                  # XXX class attributes
-                                  )
-        self.vtable = malloc(self.vtable_type, immortal=True)
-        # cast the vtable pointer from "vtable_type" to "parent_vtable_type"
-        # to "parent_parent_vtable_type" to .... to OBJECT_VTABLE
-        p = self.vtable
-        for i in range(self.depth):
-            p = p.super
-        self.typeptr = cast_flags(TYPEPTR, p)
-        p.parenttypeptr = parent_typeptr
-        #
-        self.parent_object_type = parent_object_type
-        self.object_type = GcStruct(classdef.cls.__name__,
-                                    ('super', parent_object_type),
-                                    # XXX instance attributes
-                                    )
-
-    def parent_cast(self, targetclassdef, v, llops):
-        classdef = self.classdef
-        super_name = inputconst(Void, "super")
-        while classdef is not targetclassdef:
-            rclassdef = getrclassdef(classdef)
-            parent_object_type = rclassdef.parent_object_type
-            v = llops.genop('getsubstruct', [v, super_name],
-                            resulttype = GcPtr(parent_object_type))
-            classdef = classdef.basedef
-        return v
-
-    def rtype_new_instance(self, llops):
-        ctype = inputconst(Void, self.object_type)
-        vptr = llops.genop('malloc', [ctype],
-                           resulttype = GcPtr(self.object_type))
-        vptr_as_object = self.parent_cast(None, vptr, llops)
-        typeptr_name = inputconst(Void, "typeptr")
-        ctypeptr = inputconst(TYPEPTR, self.typeptr)
-        llops.genop('setfield', [vptr_as_object, typeptr_name, ctypeptr])
-        # XXX call __init__ somewhere
-        return vptr
-
+def getclassrepr(classdef):
+    if classdef is None:
+        return root_class_repr
+    try:
+        return classdef._rtype_classrepr_
+    except AttributeError:
+        classdef._rtype_classrepr_ = result = ClassRepr(classdef)
+        return result
 
-def getrclassdef(classdef):
+def getinstancerepr(classdef):
+    if classdef is None:
+        return root_instance_repr
     try:
-        return classdef._rtype_rclassdef_
+        return classdef._rtype_instancerepr_
     except AttributeError:
-        classdef._rtype_rclassdef_ = result = RClassDef(classdef)
+        classdef._rtype_instancerepr_ = result = InstanceRepr(classdef)
         return result
 
 
-def rtype_new_instance(cls, hop):
-    classdef = hop.rtyper.annotator.getuserclasses()[cls]
-    rclassdef = getrclassdef(classdef)
-    return rclassdef.rtype_new_instance(hop.llops)
+class ClassRepr(Repr):
+
+    def __init__(self, classdef):
+        self.classdef = classdef
+        if classdef is None:
+            # 'object' root type
+            self.vtable_type = OBJECT_VTABLE
+            self.typeptr = nullptr(OBJECT_VTABLE)
+        else:
+            self.rbase = getclassrepr(classdef.basedef)
+            self.vtable_type = Struct('%s_vtable' % classdef.cls.__name__,
+                                      ('super', self.rbase.vtable_type),
+                                      # XXX class attributes
+                                      )
+        self.lowleveltype = NonGcPtr(self.vtable_type)
+        self.vtable = None
+
+    def getvtable(self, cast_to_typeptr=True):
+        """Return a ptr to the vtable of this type."""
+        if self.vtable is None:
+            self.vtable = malloc(self.vtable_type, immortal=True)
+            if self.classdef is not None:
+                self.setup_vtable(self.vtable, self.classdef)
+        #
+        vtable = self.vtable
+        if cast_to_typeptr:
+            r = self
+            while r is not root_class_repr:
+                r = r.rbase
+                vtable = cast_flags(r.lowleveltype, vtable.super)
+        return vtable
+
+    def setup_vtable(self, vtable, subclsdef):
+        """Initialize the 'self' portion of the 'vtable' belonging to the
+        'subclsdef'."""
+        if self.classdef is None:
+            # initialize the 'parenttypeptr' field
+            rbase = getclassrepr(subclsdef.basedef)
+            vtable.parenttypeptr = rbase.getvtable()
+        else:
+            # XXX setup class attributes
+            # then initialize the 'super' portion of the vtable
+            self.rbase.setup_vtable(vtable.super, subclsdef)
 
 
+root_class_repr = ClassRepr(None)
+type_repr = root_class_repr
+
 # ____________________________________________________________
 
+
 class __extend__(annmodel.SomeInstance):
     def rtyper_makerepr(self, rtyper):
-        return InstanceRepr(self.classdef)
+        return getinstancerepr(self.classdef)
 
 
 class InstanceRepr(Repr):
 
     def __init__(self, classdef):
-        self.rclassdef = getrclassdef(classdef)
-        self.lowleveltype = GcPtr(self.rclassdef.object_type)
+        self.classdef = classdef
+        self.rclass = getclassrepr(classdef)
+        if self.classdef is None:
+            self.object_type = OBJECT
+        else:
+            self.rbase = getinstancerepr(classdef.basedef)
+            self.object_type = GcStruct(classdef.cls.__name__,
+                                        ('super', self.rbase.object_type),
+                                        # XXX instance attributes
+                                        )
+        self.lowleveltype = GcPtr(self.object_type)
+
+    def parentpart(self, vinst, llops):
+        """Return the pointer 'vinst' cast to the parent type."""
+        try:
+            supercache = llops.__super_cache
+        except AttributeError:
+            supercache = llops.__super_cache = {}
+        #
+        if vinst not in supercache:
+            cname = inputconst(Void, 'super')
+            supercache[vinst] = llops.genop('getsubstruct', [vinst, cname],
+                                            resulttype=self.rbase.lowleveltype)
+        return supercache[vinst]
+
+    def getfield(self, vinst, attr, llops):
+        """Read the given attribute (or __class__ for the type) of 'vinst'."""
+        if self.classdef is None:
+            if attr != '__class__':
+                raise TyperError("attribute error: %s" % attr)
+            cname = inputconst(Void, 'typeptr')
+            return llops.genop('getfield', [vinst, cname], resulttype=TYPEPTR)
+        else:
+            # XXX instance attributes
+            vsuper = self.parentpart(vinst, llops)
+            return self.rbase.getfield(vsuper, attr, llops)
+
+    def setfield(self, vinst, attr, vvalue, llops):
+        """Write the given attribute (or __class__ for the type) of 'vinst'."""
+        if self.classdef is None:
+            if attr != '__class__':
+                raise TyperError("attribute error: %s" % attr)
+            cname = inputconst(Void, 'typeptr')
+            llops.genop('setfield', [vinst, cname, vvalue])
+        else:
+            # XXX instance attributes
+            vsuper = self.parentpart(vinst, llops)
+            self.rbase.getfield(vsuper, attr, llops)
+
+    def new_instance(self, llops):
+        """Build a new instance, without calling __init__."""
+        ctype = inputconst(Void, self.object_type)
+        vptr = llops.genop('malloc', [ctype],
+                           resulttype = GcPtr(self.object_type))
+        ctypeptr = inputconst(TYPEPTR, self.rclass.getvtable())
+        self.setfield(vptr, '__class__', ctypeptr, llops)
+        # XXX instance attributes
+        return vptr
 
     def rtype_type(self, hop):
-        vptr, = hop.inputargs(self)
-        vptr_as_object = self.rclassdef.parent_cast(None, vptr, hop.llops)
-        typeptr_name = hop.inputconst(Void, "typeptr")
-        return hop.genop('getfield', [vptr_as_object, typeptr_name],
-                         resulttype=TYPEPTR)
+        vinst, = hop.inputargs(self)
+        return self.getfield(vinst, '__class__', hop.llops)
 
 
-class TypeRepr(Repr):
-    lowleveltype = TYPEPTR
+root_instance_repr = InstanceRepr(None)
 
-type_repr = TypeRepr()
+# ____________________________________________________________
+
+def rtype_new_instance(cls, hop):
+    classdef = hop.rtyper.annotator.getuserclasses()[cls]
+    rinstance = getinstancerepr(classdef)
+    return rinstance.new_instance(hop.llops)

Modified: pypy/branch/rpython-refactoring/rpbc.py
==============================================================================
--- pypy/branch/rpython-refactoring/rpbc.py	(original)
+++ pypy/branch/rpython-refactoring/rpbc.py	Sat Jun  4 12:10:50 2005
@@ -45,3 +45,4 @@
                              resulttype = rresult)
         elif isinstance(func, (types.ClassType, type)):
             return rclass.rtype_new_instance(s_func.const, hop)
+            # XXX call __init__ somewhere



More information about the Pypy-commit mailing list