[pypy-svn] r51836 - in pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk: . test

tverwaes at codespeak.net tverwaes at codespeak.net
Sun Feb 24 18:19:34 CET 2008


Author: tverwaes
Date: Sun Feb 24 18:19:33 2008
New Revision: 51836

Modified:
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/objtable.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py
   pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/utility.py
Log:
adding untested become primitive implementation. All objects saved globally;
should become weakref array


Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/interpreter.py	Sun Feb 24 18:19:33 2008
@@ -145,7 +145,7 @@
         self.push(interp.TWO)
 
     def pushActiveContextBytecode(self, interp):
-        self.push(self)
+        self.push(self.w_self())
 
     def duplicateTopBytecode(self, interp):
         self.push(self.top())

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/model.py	Sun Feb 24 18:19:33 2008
@@ -48,6 +48,9 @@
     def equals(self, other):
         return self.pointer_equals(other)
 
+    def become(self, w_old, w_new):
+        pass
+
 class W_SmallInteger(W_Object):
     __slots__ = ('value',)     # the only allowed slot here
 
@@ -122,7 +125,7 @@
         return self.w_class
 
     def __repr__(self):
-        return "<%s %s>" % (self.__class__.__name__, self)
+        return "<%s %s at %r>" % (self.__class__.__name__, self, self.gethash())
 
     def __str__(self):
         if isinstance(self, W_PointersObject) and self._shadow is not None:
@@ -137,6 +140,7 @@
     def equals(self, w_other):
         # Special case:
         # Chars are not compared by pointer but by char-value.
+        # XXX Check comment at utility.unwrap_char ... is related.
         from pypy.lang.smalltalk.classtable import w_Character
         from pypy.lang.smalltalk import utility
         if self.getclass() == w_Character:
@@ -147,6 +151,10 @@
         else:
             return self.pointer_equals(w_other)
 
+    def become(self, w_old, w_new):
+        if self.w_class == w_old:
+            self.w_class = w_new
+
 class W_PointersObject(W_AbstractObjectWithClassReference):
     """ The normal object """
     
@@ -248,6 +256,12 @@
         from pypy.lang.smalltalk.shadow import ContextPartShadow
         return self.as_special_get_shadow(ContextPartShadow)
 
+    def become(self, w_old, w_new):
+        W_AbstractObjectWithClassReference.become(self, w_old, w_new)
+        for i in range(len(self._vars)):
+            if self.fetch(i) == w_old:
+                self.store(i, w_new)
+
 class W_BytesObject(W_AbstractObjectWithClassReference):
     def __init__(self, w_class, size):
         W_AbstractObjectWithClassReference.__init__(self, w_class)
@@ -319,6 +333,8 @@
         return (W_AbstractObjectWithClassReference.invariant(self) and
                 isinstance(self.words, list))
 
+# XXX Shouldn't compiledmethod have class reference for subclassed compiled
+# methods?
 class W_CompiledMethod(W_AbstractObjectWithIdentityHash):
     """My instances are methods suitable for interpretation by the virtual machine.  This is the only class in the system whose instances intermix both indexable pointer fields and indexable integer fields.
 
@@ -370,8 +386,11 @@
         return w_literal.as_string()    # XXX performance issue here
 
     def create_frame(self, receiver, arguments, sender = None):
+        from pypy.lang.smalltalk import objtable
         assert len(arguments) == self.argsize
-        return W_MethodContext(self, receiver, arguments, sender)
+        w_new = W_MethodContext(self, receiver, arguments, sender)
+        objtable.objects += [w_new]
+        return w_new
 
     def __str__(self):
         from pypy.lang.smalltalk.interpreter import BYTECODE_TABLE
@@ -463,8 +482,6 @@
         
     def atput0(self, index0, w_value):
         from pypy.lang.smalltalk import utility
-        print index0
-        print self.getliteralsize()
         if index0 <= self.getliteralsize():
             self.literalatput0(index0/constants.BYTES_PER_WORD, w_value)
         else:
@@ -558,6 +575,15 @@
             # Invalid!
             raise IndexError
 
+    def become(self, w_old, w_new):
+        if self._s_sender is not None and self._s_sender.w_self() == w_old:
+            self._s_sender = w_new.as_context_get_shadow()
+        for i in range(len(self._stack)):
+            if self._stack[i] == w_old:
+                self._stack[i] = w_new
+        if self._s_home is not None and self._s_home.w_self() == w_old:
+            self._s_home = w_new.as_context_get_shadow()
+
     def stackstart(self):
         return constants.MTHDCTX_TEMP_FRAME_START
 
@@ -623,7 +649,7 @@
         res = self.stack()[start:]
         del self.stack()[start:]
         return res
-    
+
 class W_BlockContext(W_ContextPart):
 
     def __init__(self, s_home, s_sender, argcnt, initialip):
@@ -652,7 +678,7 @@
         elif index == constants.BLKCTX_INITIAL_IP_INDEX:
             return utility.wrap_int(self.initialip)
         elif index == constants.BLKCTX_HOME_INDEX:
-            return self.s_home()
+            return self.s_home().w_self()
         elif index >= constants.BLKCTX_TEMP_FRAME_START:
             stack_index = len(self.stack()) - index - 1
             return self.stack()[stack_index]
@@ -700,6 +726,26 @@
     def store_w_receiver(self, w_receiver):
         self._w_receiver = w_receiver
 
+    def become(self, w_old, w_new):
+        W_ContextPart.become(self, w_old, w_new)
+        for i in range(len(self.temps)):
+            if self.temps[i] == w_old:
+                self.temps[i] = w_new
+        if w_old == self._w_receiver:
+            self._w_receiver = w_new
+        if w_old == self._w_method:
+            self._w_method = w_new
+
+    def at0(self, index0):
+        # XXX to test
+        # Fetches in temppart (variable size)
+        return self.fetch(index0+constants.MTHDCTX_TEMP_FRAME_START)
+
+    def atput0(self, index0, w_v):
+        # XXX to test
+        # Stores in temppart (variable size)
+        return self.store(index0+constants.MTHDCTX_TEMP_FRAME_START, w_v)
+
     def fetch(self, index):
         if index == constants.MTHDCTX_METHOD:
             return self.w_method()
@@ -749,6 +795,8 @@
     def w_method(self):
         return self._w_method
 
+    def size(self):
+        return len(self.temps) + len(self.stack())
 
 # Use black magic to create w_nil without running the constructor,
 # thus allowing it to be used even in the constructor of its own

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/objtable.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/objtable.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/objtable.py	Sun Feb 24 18:19:33 2008
@@ -8,15 +8,15 @@
 def wrap_char_table():
     global CharacterTable
     def bld_char(i):
-        w_cinst = classtable.w_Character.as_class_get_shadow().new()
+        w_cinst = classtable.w_Character.as_class_get_shadow().new(store=False)
         w_cinst.store(constants.CHARACTER_VALUE_INDEX,
                       model.W_SmallInteger(i))
         return w_cinst
     CharacterTable = [bld_char(i) for i in range(256)]
 wrap_char_table()
 
-w_true  = classtable.classtable['w_True'].as_class_get_shadow().new()
-w_false = classtable.classtable['w_False'].as_class_get_shadow().new()
+w_true  = classtable.classtable['w_True'].as_class_get_shadow().new(store=False)
+w_false = classtable.classtable['w_False'].as_class_get_shadow().new(store=False)
 w_minus_one = model.W_SmallInteger(-1)
 w_zero = model.W_SmallInteger(0)
 w_one = model.W_SmallInteger(1)
@@ -29,6 +29,8 @@
 w_nil.w_class = classtable.classtable['w_UndefinedObject']
 
 objtable = {}
+# XXX Should be table of weakref, contains all objects in the system
+objects = []
 
 for name in constants.objects_in_special_object_table:
     try:

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/primitives.py	Sun Feb 24 18:19:33 2008
@@ -490,9 +490,16 @@
 
 # ___________________________________________________________________________
 # Squeak Miscellaneous Primitives (128-149)
+BECOME = 128
 FULL_GC = 130
 INC_GC = 131
 
+ at expose_primitive(BECOME, unwrap_spec=[object, object])
+def func(interp, w_rcvr, w_new):
+    for w_object in objtable.objects:
+        w_object.become(w_rcvr, w_new)
+    return w_rcvr
+
 def fake_bytes_left():
     return utility.wrap_int(2**20) # XXX we don't know how to do this :-(
 

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/shadow.py	Sun Feb 24 18:19:33 2008
@@ -144,12 +144,15 @@
         else:
             self.s_superclass = w_superclass.as_class_get_shadow()
 
-    def new(self, extrasize=0):
+    # XXX check better way to store objects
+    # XXX storing is necessary for "become" which loops over all pointers
+    # XXX and replaces old pointers with new pointers
+    def new(self, extrasize=0, store=True):
         from pypy.lang.smalltalk import classtable
         w_cls = self.w_self()
         
         if w_cls == classtable.w_BlockContext:
-            return model.W_BlockContext(None, None, 0, 0)
+            w_new = model.W_BlockContext(None, None, 0, 0)
         elif w_cls == classtable.w_MethodContext:
             # From slang: Contexts must only be created with newForMethod:
             # raise error.PrimitiveFailedError
@@ -160,18 +163,22 @@
             # The mini.image -however- doesn't overwrite this method, and as
             # far as I was able to trace it back, it -does- call this method.
             from pypy.rlib.objectmodel import instantiate
-            return instantiate(model.W_MethodContext)
+            w_new = instantiate(model.W_MethodContext)
             
         if self.instance_kind == POINTERS:
-            return model.W_PointersObject(w_cls, self.instance_size+extrasize)
+            w_new = model.W_PointersObject(w_cls, self.instance_size+extrasize)
         elif self.instance_kind == WORDS:
-            return model.W_WordsObject(w_cls, extrasize)
+            w_new = model.W_WordsObject(w_cls, extrasize)
         elif self.instance_kind == BYTES:
-            return model.W_BytesObject(w_cls, extrasize)
+            w_new = model.W_BytesObject(w_cls, extrasize)
         elif self.instance_kind == COMPILED_METHOD:
-            return model.W_CompiledMethod(extrasize)
+            w_new = model.W_CompiledMethod(extrasize)
         else:
             raise NotImplementedError(self.instance_kind)
+        if store:
+            from pypy.lang.smalltalk import objtable
+            objtable.objects += [w_new]
+        return w_new
 
     # _______________________________________________________________
     # Methods for querying the format word, taken from the blue book:

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/squeakimage.py	Sun Feb 24 18:19:33 2008
@@ -202,8 +202,8 @@
                                 reader.chunks[reader.specialobjectspointer]
                                 .g_object.pointers]
 
-        self.objects = [chunk.g_object.w_object for chunk in reader.chunklist]
-        from pypy.lang.smalltalk import constants, objtable
+        from pypy.lang.smalltalk import objtable
+        objtable.objects = [chunk.g_object.w_object for chunk in reader.chunklist]
         for name, idx in constants.objects_in_special_object_table.items():
             objtable.objtable["w_" + name] = self.special_objects[idx]
 

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/test/test_miniimage.py	Sun Feb 24 18:19:33 2008
@@ -57,7 +57,7 @@
       
 def test_number_of_objects():
     image = get_image()
-    objects = image.objects
+    objects = objtable.objects
     assert len(objects) > 0
     assert 15000 < len(objects) < 16000 
     
@@ -76,7 +76,7 @@
     
 def test_invariant():
     image = get_image()
-    for each in image.objects:
+    for each in objtable.objects:
         each.invariant()
     
 def test_float_class_size():

Modified: pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/utility.py
==============================================================================
--- pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/utility.py	(original)
+++ pypy/branch/smalltalk-shadow-changes/pypy/lang/smalltalk/utility.py	Sun Feb 24 18:19:33 2008
@@ -10,6 +10,8 @@
         return w_value.value
     raise UnwrappingError("expected a W_SmallInteger, got %s" % (w_value,))
 
+# XXX maybe chars are stored in char-table for uniqueness? This would solve
+# the equal problem...
 def unwrap_char(w_char):
     from pypy.lang.smalltalk import classtable, objtable, constants
     w_class = w_char.getclass()



More information about the Pypy-commit mailing list