[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