[pypy-svn] r36773 - in pypy/dist/pypy: rpython/ootypesystem rpython/ootypesystem/test rpython/test translator/cli translator/js translator/jvm/test
antocuni at codespeak.net
antocuni at codespeak.net
Mon Jan 15 13:00:45 CET 2007
Author: antocuni
Date: Mon Jan 15 13:00:35 2007
New Revision: 36773
Modified:
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/rclass.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
pypy/dist/pypy/rpython/test/test_rclass.py
pypy/dist/pypy/translator/cli/class_.py
pypy/dist/pypy/translator/js/_class.py
pypy/dist/pypy/translator/jvm/test/test_class.py
Log:
Fix an ootypesystem bug that prevented the thunk object space to run
with gencli:
- add support for overridden default values for fields to
ootype.Instance
- add logic that detect overridden default values on
ootypesystem/rclass
- fix gencli and genjs to cope with the new concept of overridden
default values
- skip the new test in genjvm because it's not trivial to fix it
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Mon Jan 15 13:00:35 2007
@@ -57,6 +57,7 @@
self._methods = frozendict()
self._fields = frozendict()
+ self._overridden_defaults = frozendict()
self._add_fields(fields)
self._add_methods(methods)
@@ -115,6 +116,13 @@
self._fields.update(fields)
+ def _override_default_for_fields(self, fields):
+ # sanity check
+ for field in fields:
+ INST, TYPE = self._superclass._lookup_field(field)
+ assert TYPE is not None, "Can't find field %s in superclasses" % field
+ self._overridden_defaults.update(fields)
+
def _add_methods(self, methods):
# Note to the unwary: _add_methods adds *methods* whereas
# _add_fields adds *descriptions* of fields. This is obvious
@@ -134,6 +142,9 @@
for name, (ootype, default) in self._fields.iteritems():
instance.__dict__[name] = enforce(ootype, default)
+ for name, (ootype, default) in self._overridden_defaults.iteritems():
+ instance.__dict__[name] = enforce(ootype, default)
+
def _has_field(self, name):
try:
self._fields[name]
@@ -1380,6 +1391,9 @@
def addMethods(INSTANCE, methods):
INSTANCE._add_methods(methods)
+def overrideDefaultForFields(INSTANCE, fields):
+ INSTANCE._override_default_for_fields(fields)
+
def runtimeClass(INSTANCE):
assert isinstance(INSTANCE, Instance)
return INSTANCE._class
Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Mon Jan 15 13:00:35 2007
@@ -322,6 +322,34 @@
r = self.rtyper.getrepr(s_value)
m = self.attach_class_attr_accessor(mangled, value, r)
+ # step 4: do the same with instance fields whose default
+ # values are overridden in subclasses. Not sure it's the best
+ # way to do it.
+ overridden_defaults = {}
+
+ if self.classdef is not None:
+ for name, constant in self.classdef.classdesc.classdict.iteritems():
+ # look for the attrdef in the superclasses
+ classdef = self.classdef.basedef
+ attrdef = None
+ while classdef is not None:
+ if name in classdef.attrs:
+ attrdef = classdef.attrs[name]
+ break
+ classdef = classdef.basedef
+ if attrdef is not None and not attrdef.readonly:
+ # it means that the default value for this field
+ # is overridden in this subclass. Record we know
+ # about it
+ repr = self.rtyper.getrepr(attrdef.s_value)
+ oot = repr.lowleveltype
+ mangled = mangle(name)
+ value = self.classdef.classdesc.read_attribute(name)
+ default = repr.convert_desc_or_const(value)
+ overridden_defaults[mangled] = oot, default
+
+ ootype.overrideDefaultForFields(self.lowleveltype, overridden_defaults)
+
def attach_class_attr_accessor(self, mangled, value, r_value):
def ll_getclassattr(self):
return oovalue
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Mon Jan 15 13:00:35 2007
@@ -74,6 +74,14 @@
py.test.raises(TypeError, "Instance('test', ROOT, {'a': (Signed, 3.0)})")
+def test_overridden_default():
+ A = Instance("A", ROOT, {"a": (Signed, 3)})
+ B = Instance("B", A)
+ overrideDefaultForFields(B, {"a": (Signed, 5)})
+
+ b = new(B)e
+ assert b.a == 5
+
def test_simple_null():
C = Instance("test", ROOT, {"a": Signed})
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 Mon Jan 15 13:00:35 2007
@@ -115,6 +115,28 @@
res = self.interpret(dummyfn, [])
assert res == 13
+ def test_overridden_classattr_as_defaults(self):
+ class W_Root(object):
+ pass
+ class W_Thunk(W_Root):
+ pass
+
+ THUNK_PLACEHOLDER = W_Thunk()
+ W_Root.w_thunkalias = None
+ W_Thunk.w_thunkalias = THUNK_PLACEHOLDER
+
+ def dummyfn(x):
+ if x == 1:
+ t = W_Thunk()
+ elif x == 2:
+ t = W_Thunk()
+ t.w_thunkalias = W_Thunk()
+ else:
+ t = W_Root()
+ return t.w_thunkalias is THUNK_PLACEHOLDER
+ res = self.interpret(dummyfn, [1])
+ assert res == True
+
def test_prebuilt_instance(self):
a = EmptyBase()
a.x = 5
Modified: pypy/dist/pypy/translator/cli/class_.py
==============================================================================
--- pypy/dist/pypy/translator/cli/class_.py (original)
+++ pypy/dist/pypy/translator/cli/class_.py Mon Jan 15 13:00:35 2007
@@ -110,6 +110,7 @@
if ARG is not ootype.Void]
returntype = self.cts.lltype_to_cts(METH.RESULT)
ilasm.begin_function(m_name, arglist, returntype, False, 'virtual') #, 'abstract')
+ ilasm.add_comment('abstract method')
if isinstance(METH.RESULT, ootype.OOType):
ilasm.opcode('ldnull')
else:
@@ -127,7 +128,9 @@
self.ilasm.opcode('ldarg.0')
self.ilasm.call('instance void %s::.ctor()' % self.get_base_class())
# set default values for fields
- for f_name, (F_TYPE, f_default) in self.INSTANCE._fields.iteritems():
+ default_values = self.INSTANCE._fields.copy()
+ default_values.update(self.INSTANCE._overridden_defaults)
+ for f_name, (F_TYPE, f_default) in default_values.iteritems():
cts_type = self.cts.lltype_to_cts(F_TYPE)
f_name = self.cts.escape_name(f_name)
if cts_type != 'void':
Modified: pypy/dist/pypy/translator/js/_class.py
==============================================================================
--- pypy/dist/pypy/translator/js/_class.py (original)
+++ pypy/dist/pypy/translator/js/_class.py Mon Jan 15 13:00:35 2007
@@ -77,7 +77,9 @@
self.db.record_class(self.classdef, self.name)
def copy_class_attributes(self, ilasm):
- for field_name, (field_type, field_value) in self.classdef._fields.items():
+ default_values = self.classdef._fields.copy()
+ default_values.update(self.classdef._overridden_defaults)
+ for field_name, (field_type, field_value) in default_values.iteritems():
ilasm.load_str("this")
self.db.load_const(field_type, field_value, ilasm)
ilasm.set_field(None, field_name)
Modified: pypy/dist/pypy/translator/jvm/test/test_class.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/test_class.py (original)
+++ pypy/dist/pypy/translator/jvm/test/test_class.py Mon Jan 15 13:00:35 2007
@@ -4,7 +4,8 @@
from pypy.rpython.test.test_rspecialcase import BaseTestRspecialcase
class TestJvmClass(JvmTest, BaseTestRclass):
- pass
+ def test_overridden_classattr_as_defaults(self):
+ py.test.skip("JVM doesn't support overridden default value yet")
#class TestCliSpecialCase(CliTest, BaseTestRspecialcase):
# pass
More information about the pypy-svn
mailing list