[pypy-svn] r62185 - in pypy/branch/spy-graphic/pypy/lang/smalltalk: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Feb 26 14:06:47 CET 2009


Author: cfbolz
Date: Thu Feb 26 14:06:46 2009
New Revision: 62185

Modified:
   pypy/branch/spy-graphic/pypy/lang/smalltalk/model.py
   pypy/branch/spy-graphic/pypy/lang/smalltalk/objspace.py
   pypy/branch/spy-graphic/pypy/lang/smalltalk/primitives.py
   pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_miniimage.py
   pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_primitives.py
Log:
A bug in become that was hiding a bug in the test of become. Took me ages to
find. Squeak is extreeeeeeeeeeeeemely strange, try the following and print it:

#(1 2 3) at: 1 put: 5. #(1 2 3)

Not what I would expect at all.

Also implemented the clock primitive.


Modified: pypy/branch/spy-graphic/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/branch/spy-graphic/pypy/lang/smalltalk/model.py	(original)
+++ pypy/branch/spy-graphic/pypy/lang/smalltalk/model.py	Thu Feb 26 14:06:46 2009
@@ -88,7 +88,10 @@
         return self.getclass(space).as_class_get_shadow(space)
 
     def is_same_object(self, other):
-        """Compare object identity"""
+        """Compare object identity. This should be used instead of directly
+        using is everywhere in the interpreter, in case we ever want to
+        implement it differently (which is useful e.g. for proxies). Also,
+        SmallIntegers and Floats need a different implementation."""
         return self is other
 
     def become(self, other):
@@ -105,7 +108,6 @@
         self.value = value
 
     def getclass(self, space):
-        """Return SmallInteger from special objects array."""
         return space.w_SmallInteger
 
     def gethash(self):
@@ -191,11 +193,8 @@
     def invariant(self):
         return isinstance(self.hash, int)
 
-    def become(self, w_other):
-        if not isinstance(w_other, W_AbstractObjectWithIdentityHash):
-            return False
+    def _become(self, w_other):
         self.hash, w_other.hash = w_other.hash, self.hash
-        return True
 
 class W_AbstractObjectWithClassReference(W_AbstractObjectWithIdentityHash):
     """Objects with arbitrary class (ie not CompiledMethod, SmallInteger or
@@ -226,11 +225,9 @@
         return (W_AbstractObjectWithIdentityHash.invariant(self) and
                 isinstance(self.w_class, W_PointersObject))
 
-    def become(self, w_other):
-        if not isinstance(w_other, W_AbstractObjectWithClassReference):
-            return False
+    def _become(self, w_other):
         self.w_class, w_other.w_class = w_other.w_class, self.w_class
-        return W_AbstractObjectWithIdentityHash.become(self, w_other)
+        W_AbstractObjectWithIdentityHash._become(self, w_other)
         
 
 class W_PointersObject(W_AbstractObjectWithClassReference):
@@ -344,7 +341,8 @@
             return False
         self._vars, w_other._vars = w_other._vars, self._vars
         self._shadow, w_other._shadow = w_other._shadow, self._shadow
-        return W_AbstractObjectWithClassReference.become(self, w_other)
+        W_AbstractObjectWithClassReference._become(self, w_other)
+        return True
         
 
 class W_BytesObject(W_AbstractObjectWithClassReference):
@@ -386,6 +384,7 @@
         return True
 
     def is_same_object(self, other):
+        # XXX this sounds very wrong to me
         if not isinstance(other, W_BytesObject):
             return False
         return self.bytes == other.bytes
@@ -397,13 +396,7 @@
         
     def at0(self, space, index0):
         val = self.getword(index0)
-        if val & (3 << 30) == 0:
-            return space.wrap_int(val)
-        else:
-            w_result = W_BytesObject(space.classtable['w_LargePositiveInteger'], 4)
-            for i in range(4):
-                w_result.setchar(i, chr((val >> i*8) & 255))
-            return w_result
+        return space.wrap_pos_full_int(val)
  
     def atput0(self, space, index0, w_value):
         if isinstance(w_value, W_BytesObject):
@@ -459,6 +452,21 @@
         self.setheader(header)
         self.bytes = "\x00"*bytecount
 
+    def become(self, w_other):
+        if not isinstance(w_other, W_CompiledMethod):
+            return False
+        self.argsize, w_other.argsize = w_other.argsize, self.argsize
+        self.primitive, w_other.primitive = w_other.primitive, self.primitive
+        self.literals, w_other.literals = w_other.literals, self.literals
+        self.tempsize, w_other.tempsize = w_other.tempsize, self.tempsize
+        self.bytes, w_other.bytes = w_other.bytes, self.bytes
+        self.header, w_other.header = w_other.header, self.header
+        self.literalsize, w_other.literalsize = w_other.literalsize, self.literalsize
+        self.w_compiledin, w_other.w_compiledin = w_other.w_compiledin, self.w_compiledin
+        self.islarge, w_other.islarge = w_other.islarge, self.islarge
+        W_AbstractObjectWithIdentityHash._become(self, w_other)
+        return True
+
     def compiledin(self):  
         if self.w_compiledin is None:
             from pypy.lang.smalltalk import wrapper

Modified: pypy/branch/spy-graphic/pypy/lang/smalltalk/objspace.py
==============================================================================
--- pypy/branch/spy-graphic/pypy/lang/smalltalk/objspace.py	(original)
+++ pypy/branch/spy-graphic/pypy/lang/smalltalk/objspace.py	Thu Feb 26 14:06:46 2009
@@ -163,6 +163,19 @@
             return model.W_SmallInteger(val)
         raise WrappingError("integer too large to fit into a tagged pointer")
 
+    def wrap_pos_full_int(self, val):
+        if val < 0:
+            raise WrappingError("negative integer")
+        try:
+            return self.wrap_int(val)
+        except WrappingError:
+            pass
+        # XXX this is not really working well on 64 bit machines
+        w_result = model.W_BytesObject(self.classtable['w_LargePositiveInteger'], 4)
+        for i in range(4):
+            w_result.setchar(i, chr((val >> i*8) & 255))
+        return w_result
+
     def wrap_float(self, i):
         return model.W_Float(i)
 
@@ -216,6 +229,8 @@
         elif isinstance(w_v, model.W_SmallInteger): return float(w_v.value)
         raise UnwrappingError()
 
+    def _freeze_(self):
+        return True
 
 
 def bootstrap_class(space, instsize, w_superclass=None, w_metaclass=None,

Modified: pypy/branch/spy-graphic/pypy/lang/smalltalk/primitives.py
==============================================================================
--- pypy/branch/spy-graphic/pypy/lang/smalltalk/primitives.py	(original)
+++ pypy/branch/spy-graphic/pypy/lang/smalltalk/primitives.py	Thu Feb 26 14:06:46 2009
@@ -595,8 +595,9 @@
 @expose_primitive(SECONDS_CLOCK, unwrap_spec=[object])
 def func(interp, w_arg):
     import time
-    return interp.space.wrap_int(0x23910d6c)      # HACK: too big for a small int!
-    #return interp.space.wrap_int(int(time.time()))
+    sec_since_epoch = int(time.time())
+    sec_since_1901 = sec_since_epoch + ((69 * 365 + 17) * 24 * 3600)
+    return interp.space.wrap_pos_full_int(sec_since_1901)
 
 # ___________________________________________________________________________
 # Boolean Primitives
@@ -796,7 +797,7 @@
 def func(interp, w_rcvr):
     # XXX we might want to disable this check
     if not w_rcvr.getclass(interp.space).is_same_object(
-        interp.space.classtable['w_Semaphore']):
+        interp.space.w_Semaphore):
         raise PrimitiveFailedError()
     wrapper.SemaphoreWrapper(interp.space, w_rcvr).signal(interp)
     return w_rcvr
@@ -805,7 +806,7 @@
 def func(interp, w_rcvr):
     # XXX we might want to disable this check
     if not w_rcvr.getclass(interp.space).is_same_object(
-        interp.space.classtable['w_Semaphore']):
+        interp.space.w_Semaphore):
         raise PrimitiveFailedError()
     wrapper.SemaphoreWrapper(interp.space, w_rcvr).wait(interp)
     return w_rcvr
@@ -814,7 +815,7 @@
 def func(interp, w_rcvr,):
     # XXX we might want to disable this check
     if not w_rcvr.getclass(interp.space).is_same_object(
-        interp.space.classtable['w_Process']):
+        interp.space.w_Process):
         raise PrimitiveFailedError()
     wrapper.ProcessWrapper(interp.space, w_rcvr).resume(interp)
     return w_rcvr
@@ -823,7 +824,7 @@
 def func(interp, w_rcvr):
     # XXX we might want to disable this check
     if not w_rcvr.getclass(interp.space).is_same_object(
-        interp.space.classtable['w_Process']):
+        interp.space.w_Process):
         raise PrimitiveFailedError()
     wrapper.ProcessWrapper(interp.space, w_rcvr).suspend(interp)
     return w_rcvr

Modified: pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_miniimage.py
==============================================================================
--- pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_miniimage.py	(original)
+++ pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_miniimage.py	Thu Feb 26 14:06:46 2009
@@ -261,23 +261,24 @@
       p1 := 1 at 2.
       p2 := #(3 4 5).
       a := p1 -> p2.
-      (1 at 2 = a key)        ifFalse: [^false].
-      (#(3 4 5) = a value) ifFalse: [^false].
-      (p1 -> p2 = a)       ifFalse: [^false].
-      (p1 == a key)        ifFalse: [^false].
-      (p2 == a value)      ifFalse: [^false].
+      (1 at 2 = a key)        ifFalse: [^1].
+      (#(3 4 5) = a value) ifFalse: [^2].
+      (p1 -> p2 = a)       ifFalse: [^3].
+      (p1 == a key)        ifFalse: [^4].
+      (p2 == a value)      ifFalse: [^5].
       p1 become: p2.
-      (1 at 2 = a value)      ifFalse: [^false].
-      (#(3 4 5) = a key)   ifFalse: [^false].
-      (p1 -> p2 = a)       ifFalse: [^false].
-      (p1 == a key)        ifFalse: [^false].
-      (p2 == a value)      ifFalse: [^false].
+      (1 at 2 = a value)      ifFalse: [^6].
+      (3 = (a key at: 1))  ifFalse: [^7].
+      (4 = (a key at: 2))  ifFalse: [^8].
+      (5 = (a key at: 3))  ifFalse: [^9].
+      (p1 -> p2 = a)       ifFalse: [^10].
+      (p1 == a key)        ifFalse: [^11].
+      (p2 == a value)      ifFalse: [^12].
   
-      ^true"""
+      ^42"""
     perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None))
-    w_true = w(True)
     w_result = perform(w(10), "testBecome")
-    w_result.is_same_object(w_true)
+    assert space.unwrap_int(w_result) == 42
        
 def perform(w_receiver, selector, *arguments_w):
     interp = interpreter.Interpreter(space)

Modified: pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_primitives.py
==============================================================================
--- pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_primitives.py	(original)
+++ pypy/branch/spy-graphic/pypy/lang/smalltalk/test/test_primitives.py	Thu Feb 26 14:06:46 2009
@@ -46,11 +46,9 @@
 def prim_fails(code, stack):
     interp, argument_count = mock(stack)
     orig_stack = list(interp.s_active_context().stack())
-    try:
-        prim_table[code](interp, argument_count-1)
-        py.test.fail("Expected PrimitiveFailedError")
-    except PrimitiveFailedError:
-        assert interp.s_active_context().stack() == orig_stack
+    py.test.raises(PrimitiveFailedError,
+                   "prim_table[code](interp, argument_count - 1)")
+    assert interp.s_active_context().stack() == orig_stack
         
 # smallinteger tests
 def test_small_int_add():
@@ -291,9 +289,9 @@
     assert prim(primitives.CLASS, [1]).is_same_object(space.w_SmallInteger)
 
 def test_as_oop():
-    py.test.skip("not yet clear what AS_OOP returns: hash or header?")
+    # I checked potato, and that returns the hash for as_oop
     w_obj = mockclass(space, 0).as_class_get_shadow(space).new()
-    w_obj.w_hash = wrap(22)
+    w_obj.hash = 22
     assert prim(primitives.AS_OOP, [w_obj]).value == 22
 
 def test_as_oop_not_applicable_to_int():
@@ -396,7 +394,13 @@
 def test_seconds_clock():
     import time
     now = int(time.time())
-    assert (prim(primitives.SECONDS_CLOCK, [42]).value - now) <= 2
+    w_smalltalk_now1 = prim(primitives.SECONDS_CLOCK, [42])
+    assert (now % 256 - ord(w_smalltalk_now1.bytes[0])) % 256 <= 2
+    w_smalltalk_now2 = prim(primitives.SECONDS_CLOCK, [42])
+    # the high-order byte should only change by one (and even that is
+    # extreeemely unlikely)
+    assert (ord(w_smalltalk_now2.bytes[-1]) - ord(w_smalltalk_now1.bytes[-1])) <= 1
+
 
 def test_load_inst_var():
     " try to test the LoadInstVar primitives a little "



More information about the Pypy-commit mailing list