[pypy-svn] r13481 - in pypy/dist/pypy: annotation rpython rpython/test

arigo at codespeak.net arigo at codespeak.net
Thu Jun 16 18:05:16 CEST 2005


Author: arigo
Date: Thu Jun 16 18:05:13 2005
New Revision: 13481

Modified:
   pypy/dist/pypy/annotation/classdef.py
   pypy/dist/pypy/rpython/exceptiondata.py
   pypy/dist/pypy/rpython/rclass.py
   pypy/dist/pypy/rpython/test/test_rclass.py
Log:
Recursive prebuilt instances in the rtyper.
Commented out a debugging print statement.
The annotator now says 'readonly=False' for attributes that exist on prebuilt
instances, which allows 'readonly' to be used as a flag to know if the
attribute must be attached to the instance or to the class.


Modified: pypy/dist/pypy/annotation/classdef.py
==============================================================================
--- pypy/dist/pypy/annotation/classdef.py	(original)
+++ pypy/dist/pypy/annotation/classdef.py	Thu Jun 16 18:05:13 2005
@@ -16,6 +16,9 @@
     #       immutablevalue() wouldn't be happy with them
     #     * there is an infinite recursion between immutablevalue() and
     #       add_source_for_attribute() for cyclic constant structures.
+    # NB2. an attribute is readonly if it is a constant class attribute.
+    #      Both writing to the instance attribute and discovering prebuilt
+    #      instances that have the attribute set will turn off readonly-ness.
 
     def __init__(self, name, bookkeeper):
         self.name = name
@@ -120,6 +123,8 @@
         homedef = self.locate_attribute(attr)
         attrdef = homedef.attrs[attr]
         attrdef.sources[source] = clsdef
+        if clsdef is None:
+            attrdef.readonly = False    # see note about 'readonly' in ClassDef
         if attrdef.read_locations:
             # we should reflow from all the reader's position,
             # but as an optimization we try to see if the attribute

Modified: pypy/dist/pypy/rpython/exceptiondata.py
==============================================================================
--- pypy/dist/pypy/rpython/exceptiondata.py	(original)
+++ pypy/dist/pypy/rpython/exceptiondata.py	Thu Jun 16 18:05:13 2005
@@ -88,7 +88,7 @@
         for cls in table.keys():
             add_class(cls)
         assert table == {}
-        print sortedtable
+        #print sortedtable
 
         A = Array(('pycls', Ptr(PyObject)),
                   ('excinst', self.lltype_of_exception_value))

Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py	(original)
+++ pypy/dist/pypy/rpython/rclass.py	Thu Jun 16 18:05:13 2005
@@ -298,6 +298,7 @@
             self.object_type = OBJECT
         else:
             self.object_type = GcForwardReference()
+        self.prebuiltinstances = {}   # { id(x): (x, _ptr) }
         self.lowleveltype = Ptr(self.object_type)
 
     def __repr__(self):
@@ -348,32 +349,46 @@
                                               OBJECT)
         self.initialized = True
 
-    def convert_const(self, value, targetptr=None, vtable=None):
+    def convert_const(self, value):
         if value is None:
             return nullptr(self.object_type)
-        # we will need the vtable pointer, so ask it first, to let
-        # ClassRepr.convert_const() perform all the necessary checks on 'value'
-        if vtable is None:
-            vtable = self.rclass.convert_const(value.__class__)
-        if targetptr is None:
-            targetptr = malloc(self.object_type)
-        #
-        if self.classdef is None:
-            # instantiate 'object': should be disallowed, but it's convenient
-            # to write convert_const() this way and use itself recursively
-            targetptr.typeptr = cast_vtable_to_typeptr(vtable)
-        else:
-            # build the parent part of the instance
-            self.rbase.convert_const(value,
-                                     targetptr = targetptr.super,
-                                     vtable = vtable)
-            # add instance attributes from this level
+        try:
+            classdef = self.rtyper.annotator.getuserclasses()[value.__class__]
+        except KeyError:
+            raise TyperError("no classdef: %r" % (value.__class__,))
+        if classdef != self.classdef:
+            # if the class does not match exactly, check that 'value' is an
+            # instance of a subclass and delegate to that InstanceRepr
+            if classdef is None:
+                raise TyperError("not implemented: object() instance")
+            if classdef.commonbase(self.classdef) != self.classdef:
+                raise TyperError("not an instance of %r: %r" % (
+                    self.classdef.cls, value))
+            rinstance = getinstancerepr(self.rtyper, classdef)
+            return rinstance.convert_const(value)
+        # common case
+        try:
+            return self.prebuiltinstances[id(value)][1]
+        except KeyError:
+            result = malloc(self.object_type)
+            self.prebuiltinstances[id(value)] = value, result
+            self.initialize_prebuilt_instance(value, classdef, result)
+            return result
+
+    def initialize_prebuilt_instance(self, value, classdef, result):
+        if self.classdef is not None:
+            # recursively build the parent part of the instance
+            self.rbase.initialize_prebuilt_instance(value, classdef,
+                                                    result.super)
+            # then add instance attributes from this level
             for name, (mangled_name, r) in self.fields.items():
                 attrvalue = getattr(value, name)
-                # XXX RECURSIVE PREBUILT DATA STRUCTURES XXX
                 llattrvalue = r.convert_const(attrvalue)
-                setattr(targetptr, mangled_name, llattrvalue)
-        return targetptr
+                setattr(result, mangled_name, llattrvalue)
+        else:
+            # OBJECT part
+            rclass = getclassrepr(self.rtyper, classdef)
+            result.typeptr = rclass.getvtable()
 
     #def parentpart(self, vinst, llops):
     #    """Return the pointer 'vinst' cast to the parent type."""

Modified: pypy/dist/pypy/rpython/test/test_rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rclass.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rclass.py	Thu Jun 16 18:05:13 2005
@@ -57,7 +57,7 @@
         return a.x
     rtype(dummyfn)
 
-def WORKING_ON_test_recursive_prebuilt_instance():
+def test_recursive_prebuilt_instance():
     a = EmptyBase()
     b = EmptyBase()
     a.x = 5



More information about the Pypy-commit mailing list