[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