[pypy-commit] lang-smalltalk storage: Refined the compiled_in() method in CompiledMethod.

anton_gulenko noreply at buildbot.pypy.org
Tue Apr 1 10:52:11 CEST 2014


Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage
Changeset: r734:7637f57d242e
Date: 2014-04-01 10:51 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/7637f57d242e/

Log:	Refined the compiled_in() method in CompiledMethod.

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -127,6 +127,12 @@
         """Return True, if the receiver represents the nil object in the given Object Space."""
         return self.is_same_object(space.w_nil)
         
+    def is_class(self, space):
+        """ Return true, if the receiver seems to be a class.
+        We can not be completely sure about this (non-class objects might be
+        used as class)."""
+        return False
+        
     def become(self, other):
         """Become swaps two objects.
            False means swapping failed"""
@@ -509,12 +515,23 @@
         # Don't construct the ClassShadow here, yet!
         self.w_class = g_self.get_class()
         
+    def is_class(self, space):
+        # This is a class if it's a Metaclass or an instance of a Metaclass.
+        if self.has_class():
+            w_Metaclass = space.classtable["w_Metaclass"]
+            w_class = self.getclass(space)
+            if w_Metaclass.is_same_object(w_class):
+                return True
+            if w_class.has_class():
+                return w_Metaclass.is_same_object(w_class.getclass(space))
+        return False
+        
     def getclass(self, space):
         return self.w_class
 
     def guess_classname(self):
         if self.has_class():
-            if self.w_class.has_shadow():
+            if self.w_class.has_space():
                 class_shadow = self.class_shadow(self.w_class.space())
                 return class_shadow.name
             else:
@@ -580,6 +597,12 @@
         from shadow import WeakListStorageShadow
         return isinstance(self.shadow, WeakListStorageShadow)
     
+    def is_class(self, space):
+        from spyvm.shadow import ClassShadow
+        if isinstance(self.shadow, ClassShadow):
+            return True
+        return W_AbstractObjectWithClassReference.is_class(self, space)
+    
     def assert_shadow(self):
         # Failing the following assert most likely indicates a bug. The shadow can only be absent during
         # the bootstrapping sequence. It will be initialized in the fillin() method. Before that, it should
@@ -715,6 +738,10 @@
     def has_shadow(self):
         return self._get_shadow() is not None
 
+    def has_space(self):
+        # The space is accessed through the shadow.
+        return self.has_shadow()
+    
     def _become(self, w_other):
         assert isinstance(w_other, W_PointersObject)
         self.shadow, w_other.shadow = w_other.shadow, self.shadow
@@ -1258,16 +1285,21 @@
     def compiled_in(self):
         w_compiledin = self.w_compiledin
         if not w_compiledin:
-            if self.literals:
-                # (Blue book, p 607) All CompiledMethods that contain
-                # extended-super bytecodes have the clain which they are found as
-                # their last literal variable.
-                # Last of the literals is an association with compiledin as a class
-                w_association = self.literals[-1]
-                if isinstance(w_association, W_PointersObject) and w_association.size() >= 2:
-                    from spyvm import wrapper
-                    association = wrapper.AssociationWrapper(w_association.space(), w_association)
-                    w_compiledin = association.value()
+            literals = self.literals
+            if literals and len(literals) > 0:
+                # (Blue book, p 607) Last of the literals is either the containing class 
+                # or an association with compiledin as a class
+                w_candidate = literals[-1]
+                if isinstance(w_candidate, W_PointersObject) and w_candidate.has_space():
+                    space = w_candidate.space() # Not pretty to steal the space from another object.
+                    if w_candidate.is_class(space):
+                        w_compiledin = w_candidate
+                    elif w_candidate.size() >= 2:
+                        from spyvm import wrapper
+                        association = wrapper.AssociationWrapper(space, w_candidate)
+                        w_candidate = association.value()
+                        if w_candidate.is_class(space):
+                            w_compiledin = w_candidate
             self.w_compiledin = w_compiledin
         return w_compiledin
     
@@ -1378,29 +1410,11 @@
         return retval + "---------------------\n"
 
     def guess_containing_classname(self):
-        from spyvm.shadow import ClassShadow
-        guessed_classname = None
-        if len(self.literals) > 0:
-            w_candidate = self.literals[-1]
-            if isinstance(w_candidate, W_PointersObject):
-                c_shadow = w_candidate._get_shadow()
-                if isinstance(c_shadow, ClassShadow):
-                    guessed_classname = c_shadow.getname()
-                elif w_candidate.size() >= 2:
-                    w_class = w_candidate.fetch(None, 1)
-                    if isinstance(w_class, W_PointersObject):
-                        d_shadow = w_class._get_shadow()
-                        if isinstance(d_shadow, ClassShadow):
-                            guessed_classname = d_shadow.getname()
-        if guessed_classname:
-            class_cutoff = len(guessed_classname) - 6
-            if class_cutoff > 0:
-                classname = guessed_classname[0:class_cutoff]
-            else:
-                classname = guessed_classname
-        else:
-            classname = "<unknown>"
-        return classname
+        w_class = self.compiled_in()
+        if w_class and w_class.has_space():
+            # Not pretty to steal the space from another object.
+            return w_class.as_class_get_shadow(w_class.space()).getname()
+        return "? (no compiledin-info)"
     
     def get_identifier_string(self):
         return "%s >> #%s" % (self.guess_containing_classname(), self._likely_methodname)
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
@@ -123,7 +123,7 @@
     return model.W_PointersObject(space, None, size)
 
 def test_w_compiledin_assoc():
-    val = new_object()
+    val = bootstrap_class(0)
     assoc = new_object(2)
     assoc.store(space, 0, new_object())
     assoc.store(space, 1, val)


More information about the pypy-commit mailing list