Author: Maciej Fijalkowski <[email protected]>
Branch:
Changeset: r62707:97b734570970
Date: 2013-03-23 13:54 -0700
http://bitbucket.org/pypy/pypy/changeset/97b734570970/
Log: revert the smallint changes
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -189,6 +189,11 @@
BoolOption("withtproxy", "support transparent proxies",
default=True),
+ BoolOption("withsmallint", "use tagged integers",
+ default=False,
+ requires=[("objspace.std.withprebuiltint", False),
+ ("translation.taggedpointers", True)]),
+
BoolOption("withprebuiltint", "prebuild commonly used int objects",
default=False),
@@ -199,7 +204,9 @@
default=100, cmdline="--prebuiltintto"),
BoolOption("withsmalllong", "use a version of 'long' in a C long long",
- default=False),
+ default=False,
+ requires=[("objspace.std.withsmallint", False)]),
+ # ^^^ because of missing delegate_xx2yy
BoolOption("withstrbuf", "use strings optimized for addition (ver 2)",
default=False),
diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py
--- a/pypy/objspace/std/frame.py
+++ b/pypy/objspace/std/frame.py
@@ -6,7 +6,7 @@
from pypy.interpreter import pyopcode
from pypy.interpreter.pyframe import PyFrame
from pypy.interpreter.error import OperationError
-from pypy.objspace.std import intobject
+from pypy.objspace.std import intobject, smallintobject
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.objspace.std.listobject import W_ListObject
@@ -23,6 +23,20 @@
raise AssertionError
+def small_int_BINARY_ADD(f, oparg, next_instr):
+ w_2 = f.popvalue()
+ w_1 = f.popvalue()
+ if (type(w_1) is smallintobject.W_SmallIntObject and
+ type(w_2) is smallintobject.W_SmallIntObject):
+ try:
+ w_result = smallintobject.add__SmallInt_SmallInt(f.space, w_1, w_2)
+ except FailedToImplement:
+ w_result = f.space.add(w_1, w_2)
+ else:
+ w_result = f.space.add(w_1, w_2)
+ f.pushvalue(w_result)
+
+
def int_BINARY_ADD(f, oparg, next_instr):
w_2 = f.popvalue()
w_1 = f.popvalue()
@@ -88,7 +102,10 @@
class StdObjSpaceFrame(BaseFrame):
pass
if space.config.objspace.std.optimized_int_add:
- StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD
+ if space.config.objspace.std.withsmallint:
+ StdObjSpaceFrame.BINARY_ADD = small_int_BINARY_ADD
+ else:
+ StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD
if space.config.objspace.std.optimized_list_getitem:
StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR
if space.config.objspace.opcodes.CALL_METHOD:
diff --git a/pypy/objspace/std/inttype.py b/pypy/objspace/std/inttype.py
--- a/pypy/objspace/std/inttype.py
+++ b/pypy/objspace/std/inttype.py
@@ -39,7 +39,14 @@
def wrapint(space, x):
- if space.config.objspace.std.withprebuiltint:
+ if space.config.objspace.std.withsmallint:
+ from pypy.objspace.std.smallintobject import W_SmallIntObject
+ try:
+ return W_SmallIntObject(x)
+ except OverflowError:
+ from pypy.objspace.std.intobject import W_IntObject
+ return W_IntObject(x)
+ elif space.config.objspace.std.withprebuiltint:
from pypy.objspace.std.intobject import W_IntObject
lower = space.config.objspace.std.prebuiltintfrom
upper = space.config.objspace.std.prebuiltintto
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -17,6 +17,7 @@
option_to_typename = {
"withspecialisedtuple" :
["specialisedtupleobject.W_SpecialisedTupleObject"],
"withsmalltuple" : ["smalltupleobject.W_SmallTupleObject"],
+ "withsmallint" : ["smallintobject.W_SmallIntObject"],
"withsmalllong" : ["smalllongobject.W_SmallLongObject"],
"withstrbuf" : ["strbufobject.W_StringBufferObject"],
}
@@ -157,6 +158,18 @@
# when trying to dispatch multimethods.
# XXX build these lists a bit more automatically later
+ if config.objspace.std.withsmallint:
+ from pypy.objspace.std import smallintobject
+ self.typeorder[boolobject.W_BoolObject] += [
+ (smallintobject.W_SmallIntObject,
boolobject.delegate_Bool2SmallInt),
+ ]
+ self.typeorder[smallintobject.W_SmallIntObject] += [
+ (intobject.W_IntObject, smallintobject.delegate_SmallInt2Int),
+ (floatobject.W_FloatObject,
smallintobject.delegate_SmallInt2Float),
+ (longobject.W_LongObject,
smallintobject.delegate_SmallInt2Long),
+ (complexobject.W_ComplexObject,
smallintobject.delegate_SmallInt2Complex),
+ ]
+
if config.objspace.usemodules.micronumpy:
from pypy.module.micronumpy.stdobjspace import register_delegates
register_delegates(self.typeorder)
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -26,6 +26,7 @@
from pypy.objspace.std.iterobject import W_SeqIterObject
from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject
from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.smallintobject import W_SmallIntObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import W_UnicodeObject
from pypy.objspace.std.tupleobject import W_AbstractTupleObject
@@ -579,8 +580,16 @@
self.setitem(w_obj, self.wrap(key), w_value)
def getindex_w(self, w_obj, w_exception, objdescr=None):
- if type(w_obj) is W_IntObject:
- return w_obj.intval
+ # Performance shortcut for the common case of w_obj being an int.
+ # If withsmallint is disabled, we check for W_IntObject.
+ # If withsmallint is enabled, we only check for W_SmallIntObject - it's
+ # probably not useful to have a shortcut for W_IntObject at all then.
+ if self.config.objspace.std.withsmallint:
+ if type(w_obj) is W_SmallIntObject:
+ return w_obj.intval
+ else:
+ if type(w_obj) is W_IntObject:
+ return w_obj.intval
return ObjSpace.getindex_w(self, w_obj, w_exception, objdescr)
def call_method(self, w_obj, methname, *arg_w):
diff --git a/pypy/objspace/std/smallintobject.py
b/pypy/objspace/std/smallintobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/smallintobject.py
@@ -0,0 +1,87 @@
+"""
+Implementation of small ints, stored as odd-valued pointers in the
+translated PyPy. To enable them, see inttype.py.
+"""
+from pypy.objspace.std import intobject
+from pypy.objspace.std.model import registerimplementation, W_Object
+from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.noneobject import W_NoneObject
+from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject
+from pypy.interpreter.error import OperationError
+from rpython.rlib.objectmodel import UnboxedValue
+from rpython.rlib.rbigint import rbigint
+from rpython.rlib.rarithmetic import r_uint
+from rpython.tool.sourcetools import func_with_new_name
+from pypy.objspace.std.inttype import wrapint
+
+class W_SmallIntObject(W_AbstractIntObject, UnboxedValue):
+ __slots__ = 'intval'
+ from pypy.objspace.std.inttype import int_typedef as typedef
+
+ def unwrap(w_self, space):
+ return int(w_self.intval)
+ int_w = unwrap
+
+ def uint_w(w_self, space):
+ intval = w_self.intval
+ if intval < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("cannot convert negative integer
to unsigned"))
+ else:
+ return r_uint(intval)
+
+ def bigint_w(w_self, space):
+ return rbigint.fromint(w_self.intval)
+
+
+registerimplementation(W_SmallIntObject)
+
+
+def delegate_SmallInt2Int(space, w_small):
+ return W_IntObject(w_small.intval)
+
+def delegate_SmallInt2Long(space, w_small):
+ return space.newlong(w_small.intval)
+
+def delegate_SmallInt2Float(space, w_small):
+ return space.newfloat(float(w_small.intval))
+
+def delegate_SmallInt2Complex(space, w_small):
+ return space.newcomplex(float(w_small.intval), 0.0)
+
+def add__SmallInt_SmallInt(space, w_a, w_b):
+ return wrapint(space, w_a.intval + w_b.intval) # cannot overflow
+
+def sub__SmallInt_SmallInt(space, w_a, w_b):
+ return wrapint(space, w_a.intval - w_b.intval) # cannot overflow
+
+def floordiv__SmallInt_SmallInt(space, w_a, w_b):
+ return wrapint(space, w_a.intval // w_b.intval) # cannot overflow
+
+div__SmallInt_SmallInt = floordiv__SmallInt_SmallInt
+
+def mod__SmallInt_SmallInt(space, w_a, w_b):
+ return wrapint(space, w_a.intval % w_b.intval) # cannot overflow
+
+def divmod__SmallInt_SmallInt(space, w_a, w_b):
+ w = wrapint(space, w_a.intval // w_b.intval) # cannot overflow
+ z = wrapint(space, w_a.intval % w_b.intval)
+ return space.newtuple([w, z])
+
+def copy_multimethods(ns):
+ """Copy integer multimethods for small int."""
+ for name, func in intobject.__dict__.iteritems():
+ if "__Int" in name:
+ new_name = name.replace("Int", "SmallInt")
+ if new_name not in ns:
+ # Copy the function, so the annotator specializes it for
+ # W_SmallIntObject.
+ ns[new_name] = func = func_with_new_name(func, new_name,
globals=ns)
+ else:
+ ns[name] = func
+ ns["get_integer"] = ns["pos__SmallInt"] = ns["int__SmallInt"]
+ ns["get_negint"] = ns["neg__SmallInt"]
+
+copy_multimethods(globals())
+
+register_all(vars())
diff --git a/pypy/objspace/std/test/test_smallintobject.py
b/pypy/objspace/std/test/test_smallintobject.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/test/test_smallintobject.py
@@ -0,0 +1,229 @@
+import sys, py
+
+#from pypy.objspace.std.model import WITHSMALLINT
+#if not WITHSMALLINT:
+# py.test.skip("WITHSMALLINT is not enabled")
+
+from pypy.objspace.std.inttype import wrapint
+from pypy.objspace.std.multimethod import FailedToImplement
+from rpython.rlib.rarithmetic import r_uint
+
+from pypy.objspace.std.test.test_intobject import AppTestInt
+
+class TestW_IntObject:
+ spaceconfig = {"objspace.std.withsmallint": True}
+
+ def test_int_w(self):
+ assert self.space.int_w(self.space.wrap(42)) == 42
+
+ def test_uint_w(self):
+ space = self.space
+ assert space.uint_w(space.wrap(42)) == 42
+ assert isinstance(space.uint_w(space.wrap(42)), r_uint)
+ space.raises_w(space.w_ValueError, space.uint_w, space.wrap(-1))
+
+ def test_repr(self):
+ x = 1
+ f1 = wrapint(self.space, x)
+ result = self.space.repr(f1)
+ assert self.space.unwrap(result) == repr(x)
+
+ def test_str(self):
+ x = 12345
+ f1 = wrapint(self.space, x)
+ result = self.space.str(f1)
+ assert self.space.unwrap(result) == str(x)
+
+ def test_hash(self):
+ x = 42
+ f1 = wrapint(self.space, x)
+ result = self.space.hash(f1)
+ assert result.intval == hash(x)
+
+ def test_compare(self):
+ import operator
+ optab = ['lt', 'le', 'eq', 'ne', 'gt', 'ge']
+ for x in (-10, -1, 0, 1, 2, 1000, sys.maxint):
+ for y in (-sys.maxint-1, -11, -9, -2, 0, 1, 3, 1111, sys.maxint):
+ for op in optab:
+ wx = wrapint(self.space, x)
+ wy = wrapint(self.space, y)
+ res = getattr(operator, op)(x, y)
+ method = getattr(self.space, op)
+ myres = method(wx, wy)
+ assert self.space.unwrap(myres) == res
+
+ def test_add(self):
+ for x in [1, 100, sys.maxint // 2 - 50,
+ sys.maxint // 2, sys.maxint - 1000, sys.maxint]:
+ for y in [1, 100, sys.maxint // 2 - 50,
+ sys.maxint // 2, sys.maxint - 1000, sys.maxint]:
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ result = self.space.unwrap(self.space.add(f1, f2))
+ assert result == x+y
+
+ def test_sub(self):
+ for x in [1, 100, sys.maxint // 2 - 50,
+ sys.maxint // 2, sys.maxint - 1000, sys.maxint]:
+ for y in [1, 100, sys.maxint // 2 - 50,
+ sys.maxint // 2, sys.maxint - 1000, sys.maxint]:
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ result = self.space.unwrap(self.space.sub(f1, f2))
+ assert result == x-y
+
+ def test_mul(self):
+ for x in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]:
+ for y in [0, 1, 100, sys.maxint // 2 - 50, sys.maxint - 1000]:
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ result = self.space.unwrap(self.space.mul(f1, f2))
+ assert result == x*y
+
+
+ def test_div(self):
+ for i in range(10):
+ res = i//3
+ f1 = wrapint(self.space, i)
+ f2 = wrapint(self.space, 3)
+ result = self.space.div(f1, f2)
+ assert result.intval == res
+
+ def test_mod(self):
+ x = 1
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ v = self.space.mod(f1, f2)
+ assert v.intval == x % y
+ # not that mod cannot overflow
+
+ def test_divmod(self):
+ x = 1
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ ret = self.space.divmod(f1, f2)
+ v, w = self.space.unwrap(ret)
+ assert (v, w) == divmod(x, y)
+
+ def test_pow_iii(self):
+ x = 10
+ y = 2
+ z = 13
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ f3 = wrapint(self.space, z)
+ v = self.space.pow(f1, f2, f3)
+ assert v.intval == pow(x, y, z)
+ f1, f2, f3 = [wrapint(self.space, i) for i in (10, -1, 42)]
+ self.space.raises_w(self.space.w_TypeError,
+ self.space.pow,
+ f1, f2, f3)
+ f1, f2, f3 = [wrapint(self.space, i) for i in (10, 5, 0)]
+ self.space.raises_w(self.space.w_ValueError,
+ self.space.pow,
+ f1, f2, f3)
+
+ def test_pow_iin(self):
+ x = 10
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ v = self.space.pow(f1, f2, self.space.w_None)
+ assert v.intval == x ** y
+
+ def test_neg(self):
+ x = 42
+ f1 = wrapint(self.space, x)
+ v = self.space.neg(f1)
+ assert v.intval == -x
+
+ def test_pos(self):
+ x = 42
+ f1 = wrapint(self.space, x)
+ v = self.space.pos(f1)
+ assert v.intval == +x
+ x = -42
+ f1 = wrapint(self.space, x)
+ v = self.space.pos(f1)
+ assert v.intval == +x
+
+ def test_abs(self):
+ x = 42
+ f1 = wrapint(self.space, x)
+ v = self.space.abs(f1)
+ assert v.intval == abs(x)
+ x = -42
+ f1 = wrapint(self.space, x)
+ v = self.space.abs(f1)
+ assert v.intval == abs(x)
+
+ def test_invert(self):
+ x = 42
+ f1 = wrapint(self.space, x)
+ v = self.space.invert(f1)
+ assert v.intval == ~x
+
+ def test_lshift(self):
+ x = 12345678
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ v = self.space.lshift(f1, f2)
+ assert v.intval == x << y
+
+ def test_rshift(self):
+ x = 12345678
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ v = self.space.rshift(f1, f2)
+ assert v.intval == x >> y
+
+ def test_and(self):
+ x = 12345678
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ v = self.space.and_(f1, f2)
+ assert v.intval == x & y
+
+ def test_xor(self):
+ x = 12345678
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ v = self.space.xor(f1, f2)
+ assert v.intval == x ^ y
+
+ def test_or(self):
+ x = 12345678
+ y = 2
+ f1 = wrapint(self.space, x)
+ f2 = wrapint(self.space, y)
+ v = self.space.or_(f1, f2)
+ assert v.intval == x | y
+
+ def test_int(self):
+ f1 = wrapint(self.space, 1)
+ result = self.space.int(f1)
+ assert result == f1
+
+ def test_oct(self):
+ x = 012345
+ f1 = wrapint(self.space, x)
+ result = self.space.oct(f1)
+ assert self.space.unwrap(result) == oct(x)
+
+ def test_hex(self):
+ x = 0x12345
+ f1 = wrapint(self.space, x)
+ result = self.space.hex(f1)
+ assert self.space.unwrap(result) == hex(x)
+
+
+class AppTestSmallInt(AppTestInt):
+ spaceconfig = {"objspace.std.optimized_int_add" : True,
+ "objspace.std.withsmallint" : True}
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit