Author: Tim Felgentreff <[email protected]>
Branch:
Changeset: r583:6d5ffc8d1ed3
Date: 2014-01-16 14:45 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/6d5ffc8d1ed3/
Log: untagged ints everywhere
diff --git a/spyvm/constants.py b/spyvm/constants.py
--- a/spyvm/constants.py
+++ b/spyvm/constants.py
@@ -1,3 +1,4 @@
+import sys
import time
from rpython.rlib.jit import elidable
@@ -149,6 +150,8 @@
TAGGED_MASK = int(2 ** (LONG_BIT - 1) - 1)
+MAXINT = sys.maxint
+MININT = -sys.maxint-1
# Entries into SO_SPECIAL_SELECTORS_ARRAY:
#(#+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1
#// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd
0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y
0)
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -207,7 +207,7 @@
def time_now(self):
import time
from rpython.rlib.rarithmetic import intmask
- return intmask((int(time.time() * 1000) - self.startup_time) &
constants.TAGGED_MASK)
+ return intmask((int(time.time() * 1000) - self.startup_time))
def padding(self, symbol=' '):
return symbol * (self.max_stack_depth - self.remaining_stack_depth)
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -189,8 +189,7 @@
def unwrap_uint(self, space):
from rpython.rlib.rarithmetic import r_uint
val = self.value
- if val < 0:
- raise error.UnwrappingError("got negative integer")
+ # Assume the caller knows what he does, even if int is negative
return r_uint(val)
@@ -758,7 +757,7 @@
byte0 = ord(self.getchar(byte_index0))
byte1 = ord(self.getchar(byte_index0 + 1)) << 8
if byte1 & 0x8000 != 0:
- byte1 = intmask(-65536 | byte1) # -65536 = 0xffff0000
+ byte1 = intmask(intmask(0xffff0000) | byte1)
return space.wrap_int(byte1 | byte0)
def short_atput0(self, space, index0, w_value):
@@ -896,7 +895,7 @@
else:
short = (word >> 16) & 0xffff
if short & 0x8000 != 0:
- short = -65536 | short # -65536 = 0xffff0000
+ short = intmask(0xffff0000) | short
return space.wrap_int(intmask(short))
def short_atput0(self, space, index0, w_value):
@@ -907,7 +906,7 @@
word_index0 = index0 / 2
word = intmask(self.getword(word_index0))
if index0 % 2 == 0:
- word = (word & -65536) | (i_value & 0xffff) # -65536 = 0xffff0000
+ word = (word & intmask(0xffff0000)) | (i_value & 0xffff)
else:
word = (i_value << 16) | (word & 0xffff)
value = r_uint(word)
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -200,44 +200,21 @@
def wrap_int(self, val):
from spyvm import constants
assert isinstance(val, int)
- if int_between(constants.TAGGED_MININT, val,
- constants.TAGGED_MAXINT + 1):
- return model.W_SmallInteger(val)
- # We can't build large integers here, because we don't know what to do
- # with negativ vals: raise an error or interpret them as 4-byte
positive?
- raise WrappingError("integer too large to fit into a tagged pointer")
+ # we don't do tagging
+ return model.W_SmallInteger(val)
def wrap_uint(self, val):
from rpython.rlib.objectmodel import we_are_translated
- if not we_are_translated():
- assert val <= 0xFFFFFFFF
if val < 0:
raise WrappingError("negative integer")
- if val >= 0:
- try:
- return self.wrap_positive_32bit_int(intmask(val))
- except WrappingError:
- pass
- # XXX this code sucks
- import math
- bytes_len = int(math.log(val) / math.log(0xff)) + 1
- if bytes_len <= 4:
+ else:
return self.wrap_positive_32bit_int(intmask(val))
- else:
- return self._wrap_uint_loop(val, bytes_len)
-
- def _wrap_uint_loop(self, val, bytes_len):
- w_result = model.W_BytesObject(self,
- 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
def wrap_positive_32bit_int(self, val):
# This will always return a positive value.
# XXX: For now, we assume that val is at most 32bit, i.e. overflows are
- # checked for before wrapping.
- if int_between(0, val, constants.TAGGED_MAXINT + 1):
+ # checked for before wrapping. Also, we ignore tagging.
+ if int_between(0, val, constants.MAXINT):
return model.W_SmallInteger(val)
else:
return model.W_LargePositiveInteger1Word(val)
diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py
--- a/spyvm/test/test_miniimage.py
+++ b/spyvm/test/test_miniimage.py
@@ -343,7 +343,7 @@
def test_large_positive_integer_operations():
w_result = perform(interp.space.w_SmallInteger, "maxVal")
- w_result = perform(w_result, "+", space.wrap_int(42))
+ w_result = perform(w_result, "+", interp.space.wrap_int(2 *
interp.space.unwrap_int(w_result)))
assert w_result is not None
assert isinstance(w_result, model.W_LargePositiveInteger1Word)
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
@@ -271,12 +271,15 @@
def test_float_at():
b = model.W_Float(64.0)
r = b.fetch(space, 0)
- assert isinstance(r, model.W_LargePositiveInteger1Word)
- assert r.size() == 4
- assert space.unwrap_int(r.at0(space, 0)) == 0
- assert space.unwrap_int(r.at0(space, 1)) == 0
- assert space.unwrap_int(r.at0(space, 2)) == 80
- assert space.unwrap_int(r.at0(space, 3)) == 64
+ if isinstance(r, model.W_LargePositiveInteger1Word):
+ assert r.size() == 4
+ assert space.unwrap_int(r.at0(space, 0)) == 0
+ assert space.unwrap_int(r.at0(space, 1)) == 0
+ assert space.unwrap_int(r.at0(space, 2)) == 80
+ assert space.unwrap_int(r.at0(space, 3)) == 64
+ else:
+ assert isinstance(r, model.W_SmallInteger)
+ assert space.unwrap_int(r) == (80 << 16) + (64 << 24)
r = b.fetch(space, 1)
assert isinstance(r, model.W_SmallInteger)
assert r.value == 0
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
@@ -47,9 +47,6 @@
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)]:
- with py.test.raises(objspace.UnwrappingError):
- space.unwrap_uint(obj)
# byteobj = space.wrap_uint(0x100000000)
# assert isinstance(byteobj, model.W_BytesObject)
# byteobj.bytes.append('\x01')
@@ -64,8 +61,3 @@
for num in [2L, -5L]:
with py.test.raises(AssertionError):
space.wrap_int(num)
-
- from rpython.rlib.rarithmetic import intmask
- for num in [0x7fffffff, intmask(0x80000000)]:
- with py.test.raises(objspace.WrappingError):
- space.wrap_int(num)
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -69,7 +69,7 @@
assert prim(primitives.ADD, [3,4]).value == 7
def test_small_int_add_fail():
- w_result = prim_fails(primitives.ADD, [constants.TAGGED_MAXINT, 2])
+ w_result = prim_fails(primitives.ADD, [constants.MAXINT, 2])
# assert isinstance(w_result, model.W_LargePositiveInteger1Word)
# assert w_result.value == constants.TAGGED_MAXINT + 2
# prim_fails(primitives.ADD, [constants.TAGGED_MAXINT,
constants.TAGGED_MAXINT * 2])
@@ -78,21 +78,21 @@
assert prim(primitives.SUBTRACT, [5,9]).value == -4
def test_small_int_minus_fail():
- prim_fails(primitives.SUBTRACT, [constants.TAGGED_MININT,1])
+ prim_fails(primitives.SUBTRACT, [constants.MININT,1])
prim_fails(primitives.SUBTRACT,
- [constants.TAGGED_MININT, constants.TAGGED_MAXINT])
+ [constants.MININT, constants.MAXINT])
def test_small_int_multiply():
assert prim(primitives.MULTIPLY, [6,3]).value == 18
def test_small_int_multiply_overflow():
- w_result = prim_fails(primitives.MULTIPLY, [constants.TAGGED_MAXINT, 2])
+ w_result = prim_fails(primitives.MULTIPLY, [constants.MAXINT, 2])
#assert isinstance(w_result, model.W_LargePositiveInteger1Word)
#assert w_result.value == constants.TAGGED_MAXINT * 2
- prim_fails(primitives.MULTIPLY, [constants.TAGGED_MAXINT,
constants.TAGGED_MAXINT])
- prim_fails(primitives.MULTIPLY, [constants.TAGGED_MAXINT, -4])
- prim_fails(primitives.MULTIPLY, [constants.TAGGED_MININT,
constants.TAGGED_MAXINT])
- prim_fails(primitives.MULTIPLY, [constants.TAGGED_MININT, 2])
+ prim_fails(primitives.MULTIPLY, [constants.MAXINT, constants.MAXINT])
+ prim_fails(primitives.MULTIPLY, [constants.MAXINT, -4])
+ prim_fails(primitives.MULTIPLY, [constants.MININT, constants.MAXINT])
+ prim_fails(primitives.MULTIPLY, [constants.MININT, 2])
def test_small_int_divide():
assert prim(primitives.DIVIDE, [6,3]).value == 2
@@ -179,13 +179,9 @@
from rpython.rlib.rarithmetic import intmask
prim_fails(primitives.BIT_SHIFT, [4, 32])
prim_fails(primitives.BIT_SHIFT, [4, 31])
- prim_fails(primitives.BIT_SHIFT, [4, 30])
w_result = prim(primitives.BIT_SHIFT, [4, 29])
assert isinstance(w_result, model.W_LargePositiveInteger1Word)
assert w_result.value == intmask(4 << 29)
- w_result = prim(primitives.BIT_SHIFT, [4, 28])
- assert isinstance(w_result, model.W_LargePositiveInteger1Word)
- assert w_result.value == 4 << 28
def test_smallint_as_float():
assert prim(primitives.SMALLINT_AS_FLOAT, [12]).value == 12.0
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit