[pypy-commit] lang-smalltalk default: Switched from saving w_superclass to s_superclass

lwassermann noreply at buildbot.pypy.org
Sun Mar 10 20:25:29 CET 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r159:3c05ce8c677c
Date: 2013-03-10 20:25 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/3c05ce8c677c/

Log:	Switched from saving w_superclass to s_superclass Patched
	W_PointerObject#become and test to ensure that the backlink w_self
	also points to the correct object refactored patching of
	ProtoObjectClass shadow of objspace

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -259,9 +259,9 @@
 class W_PointersObject(W_AbstractObjectWithClassReference):
     """Common object."""
     _attrs_ = ['_shadow', '_vars']
+
+    _shadow = None # Default value
     
-    _shadow = None # Default value
-
     @jit.unroll_safe
     def __init__(self, w_class, size):
         """Create new object with size = fixed + variable size."""
@@ -269,7 +269,7 @@
         vars = self._vars = [None] * size
         for i in range(size): # do it by hand for the JIT's sake
             vars[i] = w_nil
-        self._shadow = None
+        self._shadow = None # Default value
 
     def at0(self, space, index0):
         # To test, at0 = in varsize part
@@ -382,7 +382,11 @@
         if not isinstance(w_other, W_PointersObject):
             return False
         self._vars, w_other._vars = w_other._vars, self._vars
+        # switching means also switching shadows
         self._shadow, w_other._shadow = w_other._shadow, self._shadow
+        # shadow links are in both directions -> also update shadows
+        if    self.has_shadow():    self._shadow._w_self = self
+        if w_other.has_shadow(): w_other._shadow._w_self = w_other
         W_AbstractObjectWithClassReference._become(self, w_other)
         return True
         
@@ -499,10 +503,11 @@
 ###    variables.  The number of bytes used for this purpose is the value of
 ###    the last byte in the method.
 
-    _shadow = None
+    _shadow = None # Default value
     _likely_methodname = "<unknown>"
 
     def __init__(self, bytecount=0, header=0):
+        self._shadow = None
         self.setheader(header)
         self.bytes = ["\x00"] * bytecount
 
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -53,13 +53,8 @@
         w_Class = self.classtable["w_Class"]
         w_Metaclass = self.classtable["w_Metaclass"]
         # XXX
-        proto_shadow = instantiate(shadow.ClassShadow)
-        proto_shadow.space = self
-        proto_shadow.name = ''
-        proto_shadow.w_superclass = w_Class
-        proto_shadow.version = shadow.Version()
-        w_ProtoObjectClass._shadow = None
-        w_ProtoObjectClass.store_shadow(proto_shadow)
+        proto_shadow = w_ProtoObjectClass._shadow
+        proto_shadow.store_w_superclass(w_Class)
         # at this point, all classes that still lack a w_class are themselves
         # metaclasses
         for nm, w_cls_obj in self.classtable.items():
@@ -299,7 +294,7 @@
     s = instantiate(shadow.ClassShadow)
     s.space = space
     s._w_self = w_class
-    s.w_superclass = w_superclass
+    s.store_w_superclass(w_superclass)
     s.name = name
     s.version = shadow.Version()
     s.instance_size = instsize
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -74,7 +74,7 @@
     (i.e. used as the class of another Smalltalk object).
     """
 
-    _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "w_superclass"]
+    _attr_ = ["name", "instance_size", "instance_varsized", "instance_kind", "w_methoddict", "s_methoddict", "_s_superclass"]
 
     def __init__(self, space, w_self):
         # fields added here should also be in objspace.py:60ff, 300ff
@@ -141,10 +141,10 @@
 
         w_superclass = w_self._fetch(constants.CLASS_SUPERCLASS_INDEX)
         if w_superclass.is_same_object(self.space.w_nil):
-            self.w_superclass = None
+            self._s_superclass = None
         else:
             assert isinstance(w_superclass, model.W_PointersObject)
-            self.w_superclass = w_superclass
+            self._s_superclass = w_superclass.as_class_get_shadow(self.space)
         self.version = Version()
 
     def guess_class_name(self):
@@ -194,9 +194,9 @@
         return jit.promote(self.w_methoddict.as_methoddict_get_shadow(self.space))
 
     def s_superclass(self):
-        if self.w_superclass is None:
+        if self._s_superclass is None:
             return None
-        return self.w_superclass.as_class_get_shadow(self.space)
+        return self._s_superclass
 
     # _______________________________________________________________
     # Methods for querying the format word, taken from the blue book:
@@ -226,23 +226,37 @@
         " Number of named instance variables for each instance of this class "
         return self.instance_size
 
+    def store_w_superclass(self, w_class):
+        if w_class is None:
+            self._s_superclass = None
+        else:
+            self._s_superclass = w_class.as_class_get_shadow(self.space)
+
     # _______________________________________________________________
     # Methods for querying the format word, taken from the blue book:
 
     def __repr__(self):
         return "<ClassShadow %s>" % (self.name or '?',)
 
+    def lookup(self, w_selector):
+        jit.promote(self)
+        version = self.version
+        jit.promote(version)
+        return self.safe_lookup(w_selector, version)
+
     @jit.unroll_safe
-    def lookup(self, w_selector):
+    def safe_lookup(self, w_selector, version):
+        assert version is self.version
         look_in_shadow = self
         jit.promote(w_selector)
         while look_in_shadow is not None:
             w_method = look_in_shadow.s_methoddict().find_selector(w_selector)
             if w_method is not None:
                 return w_method.as_compiledmethod_get_shadow(self.space)
-            look_in_shadow = look_in_shadow.s_superclass()
+            look_in_shadow = look_in_shadow._s_superclass
         raise MethodNotFound(self, w_selector)
 
+
     # _______________________________________________________________
     # Methods used only in testing
 
diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py
--- a/spyvm/test/test_model.py
+++ b/spyvm/test/test_model.py
@@ -213,7 +213,9 @@
     res = w_clsa.become(w_clsb)
     assert res
     assert w_clsa.as_class_get_shadow(space) is s_clsb
+    assert s_clsa._w_self is w_clsb
     assert w_clsb.as_class_get_shadow(space) is s_clsa
+    assert s_clsb._w_self is w_clsa
 
 def test_word_atput():
     i = model.W_SmallInteger(100)


More information about the pypy-commit mailing list