Author: Tobias Pape <[email protected]>
Branch:
Changeset: r22:d0ece51ae683
Date: 2013-01-25 08:07 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/d0ece51ae683/
Log: fix Large Integers. They can be more than four bytes wide. The ruint
test passes on 64bit now, too
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -173,8 +173,10 @@
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):
+ import math
+ bytes_len = max(4, int(math.log(val, 0xff)) + 1)
+ w_result =
model.W_BytesObject(self.classtable['w_LargePositiveInteger'], bytes_len)
+ for i in range(bytes_len):
w_result.setchar(i, chr(intmask((val >> i*8) & 255)))
return w_result
@@ -221,12 +223,10 @@
if isinstance(w_value, model.W_BytesObject):
# TODO: Completely untested! This failed translation bigtime...
# XXX Probably we want to allow all subclasses
- if not (w_value.getclass(self).is_same_object(
- self.w_LargePositiveInteger) and
- w_value.size() == 4):
+ if not
w_value.getclass(self).is_same_object(self.w_LargePositiveInteger):
raise UnwrappingError("Failed to convert bytes to word")
word = 0
- for i in range(4):
+ for i in range(w_value.size()):
word += r_uint(ord(w_value.getchar(i))) << 8*i
return word
else:
diff --git a/spyvm/test/test_objectspace.py b/spyvm/test/test_objectspace.py
--- a/spyvm/test/test_objectspace.py
+++ b/spyvm/test/test_objectspace.py
@@ -28,25 +28,30 @@
assert w_Metaclass.w_class.w_class is w_Metaclass
def test_ruint():
+ """
+ | a b |
+ a := (9223372036854775808).
+ b := LargePositiveInteger new: a size + 1.
+ 1 to: a size do: [:index |
+ b digitAt: index put: (a digitAt: index)].
+ b digitAt: (a size + 1) put: 1.
+ b.
+ => 27670116110564327424
+ """
+
from rpython.rlib.rarithmetic import r_uint
- for num in [0, 1, 41, 100, 2**31]:
+ for num in [0, 1, 41, 100, 2**31, sys.maxint + 1]:
num = r_uint(num)
assert space.unwrap_uint(space.wrap_uint(num)) == num
- for num in [-1, -100]:
- py.test.raises(objspace.WrappingError, space.wrap_uint, num)
+ for num in [-1, -100, -sys.maxint]:
+ with py.test.raises(objspace.WrappingError):
+ space.wrap_uint(num)
for obj in [space.wrap_char('a'), space.wrap_int(-1)]:
- py.test.raises(objspace.UnwrappingError, space.unwrap_uint, obj)
+ with py.test.raises(objspace.UnwrappingError):
+ space.unwrap_uint(obj)
byteobj = space.wrap_uint(sys.maxint + 1)
byteobj.bytes.append('\x01')
- py.test.raises(objspace.UnwrappingError, space.unwrap_uint, byteobj)
+ num = space.unwrap_uint(byteobj)
+ # should not raise. see docstring.
+
[email protected]("sys.maxint > 2147483647")
-def test_ruint_max():
- from rpython.rlib.rarithmetic import r_uint
- num = r_uint(sys.maxint + 1)
- assert space.unwrap_uint(space.wrap_uint(num)) == num
- num = -sys.maxint
- py.test.raises(objspace.WrappingError, space.wrap_uint, num)
-
-
-
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit