Author: Armin Rigo <[email protected]>
Branch: no-silent-merging-of-int-types
Changeset: r74913:bdfb89396304
Date: 2014-12-14 17:41 +0100
http://bitbucket.org/pypy/pypy/changeset/bdfb89396304/
Log: No longer silently merge different int types in RPython.
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -176,31 +176,35 @@
return newfunc
class __extend__(pairtype(SomeInteger, SomeInteger)):
- # unsignedness is considered a rare and contagious disease
def union((int1, int2)):
- if int1.unsigned == int2.unsigned:
- knowntype = rarithmetic.compute_restype(int1.knowntype,
int2.knowntype)
+ # Rules: int1 and int2 must be in one of the following two cases:
+ # * int1 and int2 are the same type; or
+ # * one of them is a constant 'int'.
+ # This rule is stricter than it used to be (Dec'14).
+ #
+ t1 = int1.knowntype
+ if t1 is bool:
+ t1 = int
+ t2 = int2.knowntype
+ if t2 is bool:
+ t2 = int
+ #
+ if t1 == t2:
+ knowntype = t1
+ elif (t1 in (int, rarithmetic.r_int) and
+ t2 in (int, rarithmetic.r_int)):
+ knowntype = rarithmetic.r_int
+ elif (t1 in (int, rarithmetic.r_int) and int1.is_constant()
+ and long(t2(int1.const)) == int1.const):
+ knowntype = t2
+ elif (t2 in (int, rarithmetic.r_int) and int2.is_constant()
+ and long(t1(int2.const)) == int2.const):
+ knowntype = t1
else:
- t1 = int1.knowntype
- if t1 is bool:
- t1 = int
- t2 = int2.knowntype
- if t2 is bool:
- t2 = int
-
- if t2 is int:
- if int2.nonneg == False:
- raise UnionError(int1, int2, "RPython cannot prove that
these " + \
- "integers are of the same signedness")
- knowntype = t1
- elif t1 is int:
- if int1.nonneg == False:
- raise UnionError(int1, int2, "RPython cannot prove that
these " + \
- "integers are of the same signedness")
- knowntype = t2
- else:
- raise UnionError(int1, int2)
+ raise UnionError(int1, int2, "cannot merge two integers"
+ " of different types; explicit casts are needed."
+ " (exception: integer constants)")
return SomeInteger(nonneg=int1.nonneg and int2.nonneg,
knowntype=knowntype)
@@ -218,13 +222,13 @@
inplace_truediv = truediv
def sub((int1, int2)):
- knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+ knowntype = pair(int1, int2).union().knowntype
return SomeInteger(knowntype=knowntype)
sub.can_only_throw = []
sub_ovf = _clone(sub, [OverflowError])
def and_((int1, int2)):
- knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+ knowntype = pair(int1, int2).union().knowntype
return SomeInteger(nonneg=int1.nonneg or int2.nonneg,
knowntype=knowntype)
and_.can_only_throw = []
diff --git a/rpython/annotator/test/test_annrpython.py
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -921,9 +921,7 @@
c = b
return c
a = self.RPythonAnnotator()
- s = a.build_types(f, [r_uint, int])
- assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
-
+ py.test.raises(annmodel.UnionError, a.build_types, f, [r_uint, int])
def test_prebuilt_long_that_is_not_too_long(self):
small_constant = 12L
@@ -4178,9 +4176,6 @@
with py.test.raises(annmodel.UnionError) as exc:
a.build_types(f, [int])
- assert ("RPython cannot prove that these integers are of the "
- "same signedness" in exc.value.msg)
-
def test_unionerror_instance(self):
class A(object): pass
class B(object): pass
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -440,6 +440,7 @@
self.max_delta = 0.125 * env.get_total_memory()
gc_increment_step =
env.read_uint_from_env('PYPY_GC_INCREMENT_STEP')
+ gc_increment_step = intmask(gc_increment_step)
if gc_increment_step > 0:
self.gc_increment_step = gc_increment_step
else:
diff --git a/rpython/rtyper/lltypesystem/rdict.py
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -476,7 +476,7 @@
i = i & MASK
ENTRY = lltype.typeOf(d.entries).TO.OF
entry = d.entries[i]
- if not d.entries.everused(i):
+ if not d.entries.everused(intmask(i)):
# a new entry that was never used before
ll_assert(not valid, "valid but not everused")
rc = d.resize_counter - 3
@@ -586,10 +586,10 @@
entries = d.entries
ENTRIES = lltype.typeOf(entries).TO
direct_compare = not hasattr(ENTRIES, 'no_direct_compare')
- mask = len(entries) - 1
- i = r_uint(hash & mask)
+ mask = r_uint(len(entries) - 1)
+ i = r_uint(hash) & mask
# do the first try before any looping
- if entries.valid(i):
+ if entries.valid(intmask(i)):
checkingkey = entries[i].key
if direct_compare and checkingkey == key:
return i # found the entry
@@ -599,13 +599,14 @@
found = d.keyeq(checkingkey, key)
if d.paranoia:
if (entries != d.entries or
- not entries.valid(i) or entries[i].key != checkingkey):
+ not entries.valid(intmask(i)) or
+ entries[i].key != checkingkey):
# the compare did major nasty stuff to the dict: start over
return ll_dict_lookup(d, key, hash)
if found:
return i # found the entry
freeslot = -1
- elif entries.everused(i):
+ elif entries.everused(intmask(i)):
freeslot = intmask(i)
else:
return i | HIGHEST_BIT # pristine entry -- lookup failed
@@ -619,11 +620,11 @@
i = i & mask
# keep 'i' as a signed number here, to consistently pass signed
# arguments to the small helper methods.
- if not entries.everused(i):
+ if not entries.everused(intmask(i)):
if freeslot == -1:
freeslot = intmask(i)
return r_uint(freeslot) | HIGHEST_BIT
- elif entries.valid(i):
+ elif entries.valid(intmask(i)):
checkingkey = entries[i].key
if direct_compare and checkingkey == key:
return i
@@ -633,7 +634,8 @@
found = d.keyeq(checkingkey, key)
if d.paranoia:
if (entries != d.entries or
- not entries.valid(i) or entries[i].key != checkingkey):
+ not entries.valid(intmask(i)) or
+ entries[i].key != checkingkey):
# the compare did major nasty stuff to the dict:
# start over
return ll_dict_lookup(d, key, hash)
@@ -648,10 +650,10 @@
# key is new, and the dictionary doesn't contain deleted entries.
# It only finds the next free slot for the given hash.
entries = d.entries
- mask = len(entries) - 1
- i = r_uint(hash & mask)
+ mask = r_uint(len(entries) - 1)
+ i = r_uint(hash) & mask
perturb = r_uint(hash)
- while entries.everused(i):
+ while entries.everused(intmask(i)):
i = (i << 2) + i + perturb + 1
i = i & mask
perturb >>= PERTURB_SHIFT
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py
b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -717,8 +717,8 @@
INDEXES = _ll_ptr_to_array_of(T)
entries = d.entries
indexes = lltype.cast_opaque_ptr(INDEXES, d.indexes)
- mask = len(indexes) - 1
- i = r_uint(hash & mask)
+ mask = r_uint(len(indexes) - 1)
+ i = r_uint(hash) & mask
# do the first try before any looping
ENTRIES = lltype.typeOf(entries).TO
direct_compare = not hasattr(ENTRIES, 'no_direct_compare')
@@ -802,8 +802,8 @@
# It only finds the next free slot for the given hash.
INDEXES = _ll_ptr_to_array_of(T)
indexes = lltype.cast_opaque_ptr(INDEXES, d.indexes)
- mask = len(indexes) - 1
- i = r_uint(hash & mask)
+ mask = r_uint(len(indexes) - 1)
+ i = r_uint(hash) & mask
perturb = r_uint(hash)
while rffi.cast(lltype.Signed, indexes[i]) != 0:
i = (i << 2) + i + perturb + 1
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit