Author: Armin Rigo <[email protected]>
Branch: int-float-list-strategy
Changeset: r78386:d38f6591e679
Date: 2015-07-01 19:18 +0200
http://bitbucket.org/pypy/pypy/changeset/d38f6591e679/
Log: in-progress
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -14,6 +14,7 @@
from rpython.rlib.listsort import make_timsort_class
from rpython.rlib.objectmodel import (
import_from_mixin, instantiate, newlist_hint, resizelist_hint, specialize)
+from rpython.rlib import longlong2float
from rpython.tool.sourcetools import func_with_new_name
from pypy.interpreter.baseobjspace import W_Root
@@ -73,33 +74,56 @@
return SizeListStrategy(space, sizehint)
return space.fromcache(EmptyListStrategy)
- # check for ints
- for w_obj in list_w:
- if not type(w_obj) is W_IntObject:
+ w_firstobj = list_w[0]
+ check_int_or_float = False
+
+ if type(w_firstobj) is W_IntObject:
+ # check for all-ints
+ for i in range(1, len(list_w)):
+ w_obj = list_w[i]
+ if type(w_obj) is not W_IntObject:
+ check_int_or_float = (type(w_obj) is W_FloatObject)
+ break
+ else:
+ return space.fromcache(IntegerListStrategy)
+
+ elif type(w_firstobj) is W_BytesObject:
+ # check for all-strings
+ for i in range(1, len(list_w)):
+ if type(list_w[i]) is not W_BytesObject:
+ break
+ else:
+ return space.fromcache(BytesListStrategy)
+
+ elif type(w_firstobj) is W_UnicodeObject:
+ # check for all-unicodes
+ for i in range(1, len(list_w)):
+ if type(list_w[i]) is not W_UnicodeObject:
+ break
+ else:
+ return space.fromcache(UnicodeListStrategy)
+
+ elif type(w_firstobj) is W_FloatObject:
+ # check for all-floats
+ for i in range(1, len(list_w)):
+ w_obj = list_w[i]
+ if type(w_obj) is not W_FloatObject:
+ check_int_or_float = (type(w_obj) is W_IntObject)
+ break
+ else:
+ return space.fromcache(FloatListStrategy)
+
+ if check_int_or_float:
+ for w_obj in list_w:
+ if type(w_obj) is W_IntObject:
+ if longlong2float.can_encode_int32(space.int_w(w_obj)):
+ continue # ok
+ elif type(w_obj) is W_FloatObject:
+ if longlong2float.can_encode_float(space.float_w(w_obj)):
+ continue # ok
break
- else:
- return space.fromcache(IntegerListStrategy)
-
- # check for strings
- for w_obj in list_w:
- if not type(w_obj) is W_BytesObject:
- break
- else:
- return space.fromcache(BytesListStrategy)
-
- # check for unicode
- for w_obj in list_w:
- if not type(w_obj) is W_UnicodeObject:
- break
- else:
- return space.fromcache(UnicodeListStrategy)
-
- # check for floats
- for w_obj in list_w:
- if not type(w_obj) is W_FloatObject:
- break
- else:
- return space.fromcache(FloatListStrategy)
+ else:
+ return space.fromcache(IntOrFloatListStrategy)
return space.fromcache(ObjectListStrategy)
@@ -1382,12 +1406,15 @@
return W_ListObject.from_storage_and_strategy(
self.space, storage, self)
+ def switch_to_next_strategy(self, w_list, w_sample_item):
+ w_list.switch_to_object_strategy()
+
def append(self, w_list, w_item):
if self.is_correct_type(w_item):
self.unerase(w_list.lstorage).append(self.unwrap(w_item))
return
- w_list.switch_to_object_strategy()
+ self.switch_to_next_strategy(w_list, w_item)
w_list.append(w_item)
def insert(self, w_list, index, w_item):
@@ -1397,7 +1424,7 @@
l.insert(index, self.unwrap(w_item))
return
- w_list.switch_to_object_strategy()
+ self.switch_to_next_strategy(w_list, w_item)
w_list.insert(index, w_item)
def _extend_from_list(self, w_list, w_other):
@@ -1673,7 +1700,6 @@
def _safe_find(self, w_list, obj, start, stop):
from rpython.rlib.rfloat import isnan
- from rpython.rlib.longlong2float import float2longlong
#
l = self.unerase(w_list.lstorage)
stop = min(stop, len(l))
@@ -1683,10 +1709,10 @@
if val == obj:
return i
else:
- search = float2longlong(obj)
+ search = longlong2float.float2longlong(obj)
for i in range(start, stop):
val = l[i]
- if float2longlong(val) == search:
+ if longlong2float.float2longlong(val) == search:
return i
raise ValueError
diff --git a/pypy/objspace/std/test/test_liststrategies.py
b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -733,6 +733,11 @@
list_copy[0] = 42
assert list_orig == [1, 2, 3]
+ def test_int_or_float(self):
+ space = self.space
+ w_l = W_ListObject(space, [space.wrap(1), space.wrap(2.3)])
+ xxxxx
+
class TestW_ListStrategiesDisabled:
spaceconfig = {"objspace.std.withliststrategies": False}
diff --git a/rpython/rlib/longlong2float.py b/rpython/rlib/longlong2float.py
--- a/rpython/rlib/longlong2float.py
+++ b/rpython/rlib/longlong2float.py
@@ -7,6 +7,7 @@
"""
from __future__ import with_statement
+import sys
from rpython.annotator import model as annmodel
from rpython.rlib.rarithmetic import r_int64
from rpython.rtyper.lltypesystem import lltype, rffi
@@ -99,3 +100,29 @@
[v_longlong] = hop.inputargs(lltype.SignedLongLong)
hop.exception_cannot_occur()
return hop.genop("convert_longlong_bytes_to_float", [v_longlong],
resulttype=lltype.Float)
+
+# ____________________________________________________________
+
+
+# For encoding integers inside nonstandard NaN bit patterns.
+# ff ff ff fe xx xx xx xx (signed 32-bit int)
+nan_high_word_int32 = -2 # -2 == (int)0xfffffffe
+nan_encoded_zero = rffi.cast(rffi.LONGLONG, nan_high_word_int32 << 32)
+
+def encode_int32_into_longlong_nan(value):
+ return (nan_encoded_zero +
+ rffi.cast(rffi.LONGLONG, rffi.cast(rffi.UINT, value)))
+
+def decode_int32_from_longlong_nan(value):
+ return rffi.cast(lltype.Signed, rffi.cast(rffi.INT, value))
+
+def is_int32_from_longlong_nan(value):
+ return (value >> 32) == nan_high_word_int32
+
+def can_encode_int32(value):
+ if sys.maxint == 2147483647:
+ return True
+ return value == rffi.cast(lltype.Signed, rffi.cast(rffi.INT, value))
+
+def can_encode_float(value):
+ return (float2longlong(value) >> 32) != nan_high_word_int32
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit