[pypy-commit] lang-smalltalk default: Removed the second link of W_PointersObject s to their class. Only s_class is maintained.

lwassermann noreply at buildbot.pypy.org
Wed Mar 20 14:53:29 CET 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r225:87d8824f17f5
Date: 2013-03-19 18:20 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/87d8824f17f5/

Log:	Removed the second link of W_PointersObject s to their class. Only
	s_class is maintained.

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -154,7 +154,7 @@
 
 class W_Float(W_Object):
     """Boxed float value."""
-    _attrs_ = ['value']
+    _attrs_ = ['value', 'space']
     _immutable_fields_ = ['space']
 
     def fillin_fromwords(self, space, high, low):
@@ -258,21 +258,18 @@
 class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash):
     """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or
     Float)."""
-    _attrs_ = ['w_class', 's_class']
+    _attrs_ = ['s_class', 'space']
     _immutable_fields_ = ['space']
     s_class = None
 
     def __init__(self, space, w_class):
-        if w_class is not None:     # it's None only for testing and space generation
+        self.space = space
+        if w_class is not None:# it's None only for testing and space generation
             assert isinstance(w_class, W_PointersObject)
-            if w_class.has_shadow():
-                self.s_class = w_class.as_class_get_shadow(w_class._shadow.space)
-        self.w_class = w_class
-        self.space = space
+            self.s_class = w_class.as_class_get_shadow(space)
 
     def getclass(self, space):
-        assert self.w_class is not None
-        return self.w_class
+        return self.s_class.w_self()
 
     def __repr__(self):
         return "<%s %s>" % (self.__class__.__name__, self)
@@ -282,25 +279,25 @@
             return self._shadow.getname()
         else:
             name = None
-            if self.w_class.has_shadow():
-                name = self.w_class._shadow.name
+            if self.s_class is not None:
+                name = self.s_class.name
             return "a %s" % (name or '?',)
 
     def invariant(self):
+        from spyvm.shadow import ClassShadow
         return (W_AbstractObjectWithIdentityHash.invariant(self) and
-                isinstance(self.w_class, W_PointersObject))
+                isinstance(self.s_class.w_self(), W_PointersObject) and
+                isinstance(self.s_class, ClassShadow))
 
     def _become(self, w_other):
-        self.w_class, w_other.w_class = w_other.w_class, self.w_class
         self.s_class, w_other.s_class = w_other.s_class, self.s_class
         W_AbstractObjectWithIdentityHash._become(self, w_other)
 
     def has_class(self):
-        return self.w_class is not None
+        return self.s_class is not None
 
     def shadow_of_my_class(self, space):
-        if self.s_class is None:
-            self.s_class = self.w_class.as_class_get_shadow(space)
+        assert self.s_class is not None
         return self.s_class
 
 class W_PointersObject(W_AbstractObjectWithClassReference):
@@ -393,6 +390,12 @@
         from spyvm.shadow import ClassShadow
         return jit.promote(self.as_special_get_shadow(space, ClassShadow))
 
+    def as_class_get_uninitialized_shadow(self, space):
+        from spyvm.shadow import ClassShadow
+        if self._shadow is None:
+            self.attach_shadow_of_class(space, ClassShadow)
+        return jit.promote(self._shadow)
+
     def as_blockcontext_get_shadow(self, space):
         from spyvm.shadow import BlockContextShadow
         return self.as_special_get_shadow(space, BlockContextShadow)
@@ -438,7 +441,8 @@
         return True
         
     def clone(self, space):
-        w_result = W_PointersObject(self.space, self.w_class, len(self._vars))
+        w_result = W_PointersObject(self.space, self.s_class.w_self(),
+                                    len(self._vars))
         w_result._vars = [self.fetch(space, i) for i in range(len(self._vars))]
         return w_result
 
@@ -490,7 +494,8 @@
         return self.bytes == other.bytes
 
     def clone(self, space):
-        w_result = W_BytesObject(self.space, self.w_class, len(self.bytes))
+        w_result = W_BytesObject(self.space, self.s_class.w_self(),
+                                len(self.bytes))
         w_result.bytes = list(self.bytes)
         return w_result
 
@@ -523,7 +528,8 @@
                 isinstance(self.words, list))
 
     def clone(self, space):
-        w_result = W_WordsObject(self.space, self.space, self.w_class, len(self.words))
+        w_result = W_WordsObject(self.space, self.s_class.w_self(),
+                                len(self.words))
         w_result.words = list(self.words)
         return w_result
 
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -58,8 +58,8 @@
         # at this point, all classes that still lack a w_class are themselves
         # metaclasses
         for nm, w_cls_obj in self.classtable.items():
-            if w_cls_obj.w_class is None:
-                w_cls_obj.w_class = w_Metaclass
+            if w_cls_obj.s_class is None:
+                w_cls_obj.s_class = w_Metaclass.as_class_get_shadow(self)
         
         def define_cls(cls_nm, supercls_nm, instvarsize=0, format=shadow.POINTERS,
                        varsized=False):
@@ -134,7 +134,7 @@
         # initialize their fields to nil, we have to create it in the model
         # package, and then patch up its fields here:
         w_nil = self.w_nil = model.w_nil
-        w_nil.w_class = self.classtable['w_UndefinedObject']
+        w_nil.s_class = self.classtable['w_UndefinedObject'].as_class_get_shadow(self)
 
         w_true = self.classtable['w_True'].as_class_get_shadow(self).new()
         self.w_true = w_true
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -647,7 +647,6 @@
     if w_arg_class.instsize() != w_rcvr_class.instsize():
         raise PrimitiveFailedError()
 
-    w_rcvr.w_class = w_arg.w_class
     w_rcvr.s_class = w_arg.s_class
 
 # ___________________________________________________________________________
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -45,12 +45,15 @@
 
     def attach_shadow(self):
         self.w_self().store_shadow(self)
-        self.update()
 
     def update(self):
         """This should get called whenever the base Smalltalk
         object changes."""
-        self.sync_cache()
+        w_self = self.w_self()
+        if isinstance(w_self, model.W_PointersObject):
+            if w_self.size() == 0:
+                return
+        return self.sync_cache()
 
     def sync_cache(self):
         raise NotImplementedError()
@@ -102,8 +105,6 @@
         "Update the ClassShadow with data from the w_self class."
 
         w_self = self.w_self()
-        if w_self.size() == 0:
-            return
 
         # read and painfully decode the format
         try:
@@ -350,8 +351,6 @@
         self.invalid = True
 
     def sync_cache(self):
-        if self.w_self().size() == 0:
-            return
         w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX)
         assert isinstance(w_values, model.W_PointersObject)
         s_values = w_values.as_observed_get_shadow(self.space)
diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py
--- a/spyvm/squeakimage.py
+++ b/spyvm/squeakimage.py
@@ -305,6 +305,8 @@
         for chunk in self.chunks.itervalues():
             casted = chunk.g_object.w_object
             if isinstance(casted, model.W_PointersObject) and casted.has_shadow():
+                assert hasattr(casted, '_vars')
+                assert casted.size() != 0
                 casted._shadow.update()
 
     def init_compactclassesarray(self):
@@ -533,8 +535,7 @@
         w_pointersobject._vars = [g_object.w_object for g_object in self.pointers]
         w_class = self.g_class.w_object
         assert isinstance(w_class, model.W_PointersObject)
-        w_pointersobject.w_class = w_class
-        w_pointersobject.s_class = None
+        w_pointersobject.s_class = w_class.as_class_get_uninitialized_shadow(self.space)
         w_pointersobject.hash = self.chunk.hash12
 
     def fillin_floatobject(self, w_floatobject):
@@ -551,13 +552,13 @@
         w_wordsobject.words = [r_uint(x) for x in self.chunk.data]
         w_class = self.g_class.w_object
         assert isinstance(w_class, model.W_PointersObject)
-        w_wordsobject.w_class = w_class
+        w_wordsobject.s_class = w_class.as_class_get_uninitialized_shadow(self.space)
         w_wordsobject.hash = self.chunk.hash12 # XXX check this
 
     def fillin_bytesobject(self, w_bytesobject):
         w_class = self.g_class.w_object
         assert isinstance(w_class, model.W_PointersObject)
-        w_bytesobject.w_class = w_class
+        w_bytesobject.s_class = w_class.as_class_get_uninitialized_shadow(self.space)
         w_bytesobject.bytes = self.get_bytes()
         w_bytesobject.hash = self.chunk.hash12 # XXX check this
 
diff --git a/spyvm/test/test_objectspace.py b/spyvm/test/test_objectspace.py
--- a/spyvm/test/test_objectspace.py
+++ b/spyvm/test/test_objectspace.py
@@ -8,11 +8,11 @@
     # Heuristic to detect if this is a metaclass. Don't use apart
     # from in this test file, because classtable['w_Metaclass'] is
     # bogus after loading an image.
-    return w_cls.w_class is space.classtable['w_Metaclass']
+    return w_cls.s_class.w_self() is space.classtable['w_Metaclass']
 
 def test_every_class_is_an_instance_of_a_metaclass():
     for (nm, w_cls) in space.classtable.items():
-        assert ismetaclass(w_cls) or ismetaclass(w_cls.w_class)
+        assert ismetaclass(w_cls) or ismetaclass(w_cls.s_class.w_self())
 
 def test_every_metaclass_inherits_from_class_and_behavior():
     s_Class = space.classtable['w_Class'].as_class_get_shadow(space)
@@ -25,7 +25,7 @@
 
 def test_metaclass_of_metaclass_is_an_instance_of_metaclass():
     w_Metaclass = space.classtable['w_Metaclass']
-    assert w_Metaclass.w_class.w_class is w_Metaclass
+    assert w_Metaclass.s_class.w_self().s_class.w_self() is w_Metaclass
 
 def test_ruint():
     """
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -19,7 +19,7 @@
         s_self.reset_stack()
         s_self.push_all(stack)
         s_self.store_expected_argument_count(0)
-        self.w_class = space.w_MethodContext
+        self.s_class = space.w_MethodContext.as_class_get_shadow(space)
     
     def as_blockcontext_get_shadow(self):
         self._shadow = shadow.BlockContextShadow(space, self)
diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py
--- a/spyvm/test/test_shadow.py
+++ b/spyvm/test/test_shadow.py
@@ -32,7 +32,7 @@
                           w_classofclass=None, methods={}):
     if w_classofclass is None:
         w_classofclass = build_smalltalk_class(None, 0x94,
-                                               w_superclass.w_class,
+                                               w_superclass.s_class.w_self(),
                                                w_Metaclass)
     w_methoddict = build_methoddict(methods)
     size = constants.CLASS_NAME_INDEX + 1


More information about the pypy-commit mailing list