[pypy-commit] lang-smalltalk default: (cfbolz, timfel) Floats are word objects, implement at: and at:put:

timfel noreply at buildbot.pypy.org
Wed Mar 13 17:47:38 CET 2013


Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch: 
Changeset: r173:fe9b2f9cab9e
Date: 2013-03-13 17:09 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/fe9b2f9cab9e/

Log:	(cfbolz, timfel) Floats are word objects, implement at: and at:put:

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -192,6 +192,35 @@
     def clone(self, space):
         return self
 
+    def at0(self, space, index0):
+        return self.fetch(space, index0)
+
+    def atput0(self, space, index0, w_value):
+        self.store(space, index0, w_value)
+
+    def fetch(self, space, n0):
+        from rpython.rlib.rstruct.ieee import float_pack
+        r = float_pack(self.value, 8) # C double
+        if n0 == 0:
+            return space.wrap_uint(r_uint(intmask(r >> 32)))
+        else:
+            assert n0 == 1
+            return space.wrap_uint(r_uint(intmask(r)))
+
+    def store(self, space, n0, w_obj):
+        from rpython.rlib.rstruct.ieee import float_unpack, float_pack
+        from rpython.rlib.rarithmetic import r_ulonglong
+
+        uint = r_ulonglong(space.unwrap_uint(w_obj))
+        r = float_pack(self.value, 8)
+        if n0 == 0:
+            r = ((r << 32) >> 32) | (uint << 32)
+        else:
+            assert n0 == 1
+            r = ((r >> 32) << 32) | uint
+        self.value = float_unpack(r, 8)
+
+
 class W_AbstractObjectWithIdentityHash(W_Object):
     """Object with explicit hash (ie all except small
     ints and floats)."""
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -178,7 +178,7 @@
                 return self.wrap_int(intmask(val))
             except WrappingError:
                 pass
-        # XXX is math allowed here?
+        # XXX this code sucks
         import math
         bytes_len = int(math.log(val) / math.log(0xff)) + 1
         bytes_len = 4 if 4 > bytes_len else bytes_len
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
@@ -238,3 +238,21 @@
     r = b.at0(space, 0)
     assert isinstance(r, model.W_BytesObject)
     assert r.size() == 4
+
+def test_float_at():
+    b = model.W_Float(64.0)
+    r = b.fetch(space, 0)
+    assert isinstance(r, model.W_BytesObject)
+    assert r.size() == 4
+    assert r.bytes == [chr(0), chr(0), chr(80), chr(64)]
+    r = b.fetch(space, 1)
+    assert isinstance(r, model.W_SmallInteger)
+    assert r.value == 0
+
+def test_float_at_put():
+    target = model.W_Float(1.0)
+    for f in [1.0, -1.0, 1.1, 64.4, -0.0]:
+        source = model.W_Float(f)
+        target.store(space, 0, source.fetch(space, 0))
+        target.store(space, 1, source.fetch(space, 1))
+        assert target.value == f


More information about the pypy-commit mailing list