[pypy-svn] r78662 - in pypy/branch/smalllong/pypy: config module/marshal/test objspace/std objspace/std/test rlib translator/c/src

arigo at codespeak.net arigo at codespeak.net
Wed Nov 3 12:40:49 CET 2010


Author: arigo
Date: Wed Nov  3 12:40:46 2010
New Revision: 78662

Modified:
   pypy/branch/smalllong/pypy/config/pypyoption.py
   pypy/branch/smalllong/pypy/module/marshal/test/test_marshalimpl.py
   pypy/branch/smalllong/pypy/objspace/std/longobject.py
   pypy/branch/smalllong/pypy/objspace/std/longtype.py
   pypy/branch/smalllong/pypy/objspace/std/marshal_impl.py
   pypy/branch/smalllong/pypy/objspace/std/model.py
   pypy/branch/smalllong/pypy/objspace/std/objspace.py
   pypy/branch/smalllong/pypy/objspace/std/smalllongobject.py
   pypy/branch/smalllong/pypy/objspace/std/strutil.py
   pypy/branch/smalllong/pypy/objspace/std/test/test_smalllongobject.py
   pypy/branch/smalllong/pypy/rlib/rarithmetic.py
   pypy/branch/smalllong/pypy/rlib/rbigint.py
   pypy/branch/smalllong/pypy/translator/c/src/int.h
Log:
Mostly finish smalllongobject.py.  Add support for translating
operations like 'llong_add_ovf'.


Modified: pypy/branch/smalllong/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/smalllong/pypy/config/pypyoption.py	(original)
+++ pypy/branch/smalllong/pypy/config/pypyoption.py	Wed Nov  3 12:40:46 2010
@@ -195,7 +195,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("withstrjoin", "use strings optimized for addition",
                    default=False),

Modified: pypy/branch/smalllong/pypy/module/marshal/test/test_marshalimpl.py
==============================================================================
--- pypy/branch/smalllong/pypy/module/marshal/test/test_marshalimpl.py	(original)
+++ pypy/branch/smalllong/pypy/module/marshal/test/test_marshalimpl.py	Wed Nov  3 12:40:46 2010
@@ -24,6 +24,10 @@
         assert z == 10000000000
         z = marshal.loads('I\x00\x1c\xf4\xab\xfd\xff\xff\xff')
         assert z == -10000000000
+        z = marshal.loads('I\x88\x87\x86\x85\x84\x83\x82\x01')
+        assert z == 108793946209421192
+        z = marshal.loads('I\xd8\xd8\xd9\xda\xdb\xdc\xcd\xfe')
+        assert z == -0x0132232425262728
 
     def test_buffer(self):
         import marshal

Modified: pypy/branch/smalllong/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/longobject.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/longobject.py	Wed Nov  3 12:40:46 2010
@@ -58,6 +58,9 @@
     def get_sign(self):
         return self.num.sign
 
+    def __repr__(self):
+        return '<W_LongObject(%d)>' % self.num.tolong()
+
 registerimplementation(W_LongObject)
 
 def newbigint(space, w_longtype, bigint):
@@ -65,6 +68,21 @@
     W_LongObject.__init__(w_obj, bigint)
     return w_obj
 
+def newlong(space, bigint):
+    """Turn the bigint into a W_LongObject.  If withsmalllong is enabled,
+    check if the bigint would fit in a smalllong, and return a
+    W_SmallLongObject instead if it does.
+    """
+    if space.config.objspace.std.withsmalllong:
+        try:
+            z = bigint.tolonglong()
+        except OverflowError:
+            pass
+        else:
+            from pypy.objspace.std.smalllongobject import W_SmallLongObject
+            return W_SmallLongObject(z)
+    return W_LongObject(bigint)
+
 
 # bool-to-long
 def delegate_Bool2Long(space, w_bool):
@@ -72,7 +90,7 @@
 
 # int-to-long delegation
 def delegate_Int2Long(space, w_intobj):
-    return long__Int(space, w_intobj)
+    return W_LongObject.fromint(space, w_intobj.intval)
 
 
 # long__Long is supposed to do nothing, unless it has
@@ -85,7 +103,7 @@
     return W_LongObject(l)
 
 def long__Int(space, w_intobj):
-    return W_LongObject.fromint(space, w_intobj.intval)
+    return space.newlong(w_intobj.intval)
 
 def int__Long(space, w_value):
     try:
@@ -190,38 +208,41 @@
 
 def truediv__Long_Long(space, w_long1, w_long2):
     try:
-        return space.newfloat(w_long1.num.truediv(w_long2.num))
+        f = w_long1.num.truediv(w_long2.num)
     except ZeroDivisionError:
         raise OperationError(space.w_ZeroDivisionError,
                              space.wrap("long division or modulo by zero"))
     except OverflowError:
         raise OperationError(space.w_OverflowError,
                              space.wrap("long/long too large for a float"))
+    return space.newfloat(f)
 
 def floordiv__Long_Long(space, w_long1, w_long2):
     try:
-        return W_LongObject(w_long1.num.floordiv(w_long2.num))
+        z = w_long1.num.floordiv(w_long2.num)
     except ZeroDivisionError:
         raise OperationError(space.w_ZeroDivisionError,
                              space.wrap("long division or modulo by zero"))
+    return newlong(space, z)
 
 def div__Long_Long(space, w_long1, w_long2):
     return floordiv__Long_Long(space, w_long1, w_long2)
 
 def mod__Long_Long(space, w_long1, w_long2):
     try:
-        return W_LongObject(w_long1.num.mod(w_long2.num))
+        z = w_long1.num.mod(w_long2.num)
     except ZeroDivisionError:
         raise OperationError(space.w_ZeroDivisionError,
                              space.wrap("long division or modulo by zero"))
+    return newlong(space, z)
 
 def divmod__Long_Long(space, w_long1, w_long2):
     try:
         div, mod = w_long1.num.divmod(w_long2.num)
-        return space.newtuple([W_LongObject(div), W_LongObject(mod)])
     except ZeroDivisionError:
         raise OperationError(space.w_ZeroDivisionError,
                              space.wrap("long division or modulo by zero"))
+    return space.newtuple([newlong(space, div), newlong(space, mod)])
 
 def pow__Long_Long_Long(space, w_long1, w_long2, w_long3):
     # XXX need to replicate some of the logic, to get the errors right
@@ -282,10 +303,10 @@
     except OverflowError:   # b too big # XXX maybe just return 0L instead?
         raise OperationError(space.w_OverflowError,
                              space.wrap("shift count too large"))
-    return W_LongObject(w_long1.num.rshift(shift))
+    return newlong(space, w_long1.num.rshift(shift))
 
 def and__Long_Long(space, w_long1, w_long2):
-    return W_LongObject(w_long1.num.and_(w_long2.num))
+    return newlong(space, w_long1.num.and_(w_long2.num))
 
 def xor__Long_Long(space, w_long1, w_long2):
     return W_LongObject(w_long1.num.xor(w_long2.num))
@@ -305,11 +326,18 @@
 register_all(vars())
 
 # register implementations of ops that recover int op overflows
+def recover_with_smalllong(space):
+    # True if there is a chance that a SmallLong would fit when an Int does not
+    return (space.config.objspace.std.withsmalllong and
+            sys.maxint == 2147483647)
 
 # binary ops
 for opname in ['add', 'sub', 'mul', 'div', 'floordiv', 'truediv', 'mod', 'divmod', 'lshift']:
     exec compile("""
 def %(opname)s_ovr__Int_Int(space, w_int1, w_int2):
+    if recover_with_smalllong(space) and %(opname)r != 'truediv':
+        from pypy.objspace.std.smalllongobject import %(opname)s_ovr
+        return %(opname)s_ovr(space, w_int1, w_int2)
     w_long1 = delegate_Int2Long(space, w_int1)
     w_long2 = delegate_Int2Long(space, w_int2)
     return %(opname)s__Long_Long(space, w_long1, w_long2)
@@ -322,6 +350,9 @@
 for opname in ['neg', 'abs']:
     exec """
 def %(opname)s_ovr__Int(space, w_int1):
+    if recover_with_smalllong(space):
+        from pypy.objspace.std.smalllongobject import %(opname)s_ovr
+        return %(opname)s_ovr(space, w_int1)
     w_long1 = delegate_Int2Long(space, w_int1)
     return %(opname)s__Long(space, w_long1)
 """ % {'opname': opname}
@@ -331,6 +362,9 @@
 
 # pow
 def pow_ovr__Int_Int_None(space, w_int1, w_int2, w_none3):
+    if recover_with_smalllong(space):
+        from pypy.objspace.std.smalllongobject import pow_ovr
+        return pow_ovr(space, w_int1, w_int2)
     w_long1 = delegate_Int2Long(space, w_int1)
     w_long2 = delegate_Int2Long(space, w_int2)
     return pow__Long_Long_None(space, w_long1, w_long2, w_none3)

Modified: pypy/branch/smalllong/pypy/objspace/std/longtype.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/longtype.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/longtype.py	Wed Nov  3 12:40:46 2010
@@ -35,7 +35,7 @@
                 return w_obj
             # the following is all for the 'subclass_of_long(x)' case
             if W_SmallLongObject and isinstance(w_obj, W_SmallLongObject):
-                bigint = w_obj.as_bigint()
+                bigint = w_obj.asbigint()
             elif isinstance(w_obj, W_LongObject):
                 bigint = w_obj.num
             elif space.is_true(space.isinstance(w_obj, space.w_int)):
@@ -70,14 +70,14 @@
                              space.wrap(e.msg))
     if (space.config.objspace.std.withsmalllong
         and space.is_w(w_longtype, space.w_long)):
+        from pypy.objspace.std.smalllongobject import W_SmallLongObject
         try:
-            longlong = bigint.tolonglong()
+            return W_SmallLongObject.frombigint(bigint)
         except OverflowError:
             pass
-        else:
-            from pypy.objspace.std.smalllongobject import W_SmallLongObject
-            return W_SmallLongObject(longlong)
+    from pypy.objspace.std.longobject import newbigint
     return newbigint(space, w_longtype, bigint)
+string_to_w_long._dont_inline_ = True
 
 # ____________________________________________________________
 

Modified: pypy/branch/smalllong/pypy/objspace/std/marshal_impl.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/marshal_impl.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/marshal_impl.py	Wed Nov  3 12:40:46 2010
@@ -10,8 +10,8 @@
 
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std.register_all import register_all
-from pypy.rlib.rarithmetic import LONG_BIT
-from pypy.objspace.std import longobject, model
+from pypy.rlib.rarithmetic import LONG_BIT, r_longlong, r_uint
+from pypy.objspace.std import model
 from pypy.objspace.std.longobject import SHIFT as long_bits
 from pypy.interpreter.special import Ellipsis
 from pypy.interpreter.pycode import PyCode
@@ -144,27 +144,13 @@
 register(TYPE_INT, unmarshal_Int)
 
 def unmarshal_Int64(space, u, tc):
+    lo = u.get_int()
+    hi = u.get_int()
     if LONG_BIT >= 64:
-        lo = u.get_int() & (2**32-1)
-        hi = u.get_int()
-        return space.newint((hi << 32) | lo)
-    else:
-        # fall back to a long
-        # XXX at some point, we need to extend longobject
-        # by _PyLong_FromByteArray and _PyLong_AsByteArray.
-        # I will do that when implementing cPickle.
-        # for now, this rare case is solved the simple way.
-        lshift = longobject.lshift__Long_Long
-        longor = longobject.or__Long_Long
-        lo1 = space.newlong(u.get_short() & 0xffff)
-        lo2 = space.newlong(u.get_short() & 0xffff)
-        res = space.newlong(u.get_int())
-        nbits = space.newlong(16)
-        res = lshift(space, res, nbits)
-        res = longor(space, res, lo2)
-        res = lshift(space, res, nbits)
-        res = longor(space, res, lo1)
-        return res
+        x = (hi << 32) | (lo & (2**32-1))    # result fits in an int
+    else:
+        x = (r_longlong(hi) << 32) | r_longlong(r_uint(lo))  # get a r_longlong
+    return space.wrap(x)
 register(TYPE_INT64, unmarshal_Int64)
 
 def pack_float(f):

Modified: pypy/branch/smalllong/pypy/objspace/std/model.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/model.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/model.py	Wed Nov  3 12:40:46 2010
@@ -16,6 +16,7 @@
 
 option_to_typename = {
     "withsmallint"   : ["smallintobject.W_SmallIntObject"],
+    "withsmalllong"  : ["smalllongobject.W_SmallLongObject"],
     "withstrslice"   : ["strsliceobject.W_StringSliceObject"],
     "withstrjoin"    : ["strjoinobject.W_StringJoinObject"],
     "withstrbuf"     : ["strbufobject.W_StringBufferObject"],
@@ -68,6 +69,7 @@
         from pypy.objspace.std import complexobject
         from pypy.objspace.std import setobject
         from pypy.objspace.std import smallintobject
+        from pypy.objspace.std import smalllongobject
         from pypy.objspace.std import tupleobject
         from pypy.objspace.std import listobject
         from pypy.objspace.std import dictmultiobject
@@ -180,6 +182,18 @@
             (longobject.W_LongObject,   longobject.delegate_Int2Long),
             (complexobject.W_ComplexObject, complexobject.delegate_Int2Complex),
             ]
+        if config.objspace.std.withsmalllong:
+            self.typeorder[boolobject.W_BoolObject] += [
+                (smalllongobject.W_SmallLongObject, smalllongobject.delegate_Bool2SmallLong),
+                ]
+            self.typeorder[intobject.W_IntObject] += [
+                (smalllongobject.W_SmallLongObject, smalllongobject.delegate_Int2SmallLong),
+                ]
+            self.typeorder[smalllongobject.W_SmallLongObject] += [
+                (floatobject.W_FloatObject, smalllongobject.delegate_SmallLong2Float),
+                (longobject.W_LongObject, smalllongobject.delegate_SmallLong2Long),
+                (complexobject.W_ComplexObject, smalllongobject.delegate_SmallLong2Complex),
+                ]
         self.typeorder[longobject.W_LongObject] += [
             (floatobject.W_FloatObject, floatobject.delegate_Long2Float),
             (complexobject.W_ComplexObject,

Modified: pypy/branch/smalllong/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/objspace.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/objspace.py	Wed Nov  3 12:40:46 2010
@@ -176,7 +176,13 @@
             #print 'wrapping', x, '->', w_result
             return w_result
         if isinstance(x, base_int):
-            xxxxxxxxx
+            if self.config.objspace.std.withsmalllong:
+                from pypy.objspace.std.smalllongobject import W_SmallLongObject
+                from pypy.rlib.rarithmetic import r_longlong, r_ulonglong
+                from pypy.rlib.rarithmetic import longlongmax
+                if (not isinstance(x, r_ulonglong)
+                    or x <= r_ulonglong(longlongmax)):
+                    return W_SmallLongObject(r_longlong(x))
             return W_LongObject.fromrarith_int(x)
 
         # _____ below here is where the annotator should not get _____
@@ -274,7 +280,7 @@
     def newlong(self, val): # val is an int
         if self.config.objspace.std.withsmalllong:
             from pypy.objspace.std.smalllongobject import W_SmallLongObject
-            return W_SmallLongObject.fromint(self, val)
+            return W_SmallLongObject.fromint(val)
         return W_LongObject.fromint(self, val)
 
     def newtuple(self, list_w):

Modified: pypy/branch/smalllong/pypy/objspace/std/smalllongobject.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/smalllongobject.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/smalllongobject.py	Wed Nov  3 12:40:46 2010
@@ -1,19 +1,428 @@
 """
-Implementation of 'small' longs, stored as a C 'long long' value.
-Useful for 32-bit applications manipulating 64-bit values.
+Implementation of 'small' longs, stored as a r_longlong.
+Useful for 32-bit applications manipulating values a bit larger than
+fits in an 'int'.
 """
 from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.rlib.rarithmetic import r_longlong
+from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.multimethod import FailedToImplementArgs
+from pypy.rlib.rarithmetic import r_longlong, r_int, r_uint
+from pypy.rlib.rarithmetic import intmask, ovfcheck, LONGLONG_BIT
+from pypy.rlib.rbigint import rbigint
+from pypy.objspace.std.longobject import W_LongObject
+from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.noneobject import W_NoneObject
+from pypy.interpreter.error import OperationError
 
 
 class W_SmallLongObject(W_Object):
     from pypy.objspace.std.longtype import long_typedef as typedef
+    _immutable_ = True
 
     def __init__(w_self, value):
         assert isinstance(value, r_longlong)
-        w_self._longlong = value
+        w_self.longlong = value
 
-    def as_bigint(w_self):
-        xxx
+    @staticmethod
+    def fromint(value):
+        return W_SmallLongObject(r_longlong(value))
+
+    @staticmethod
+    def frombigint(bigint):
+        return W_SmallLongObject(bigint.tolonglong())
+
+    def asbigint(w_self):
+        return rbigint.fromrarith_int(w_self.longlong)
+
+    def __repr__(w_self):
+        return '<W_SmallLongObject(%d)>' % w_self.longlong
 
 registerimplementation(W_SmallLongObject)
+
+
+def delegate_Bool2SmallLong(space, w_bool):
+    return W_SmallLongObject(r_longlong(space.is_true(w_bool)))
+
+def delegate_Int2SmallLong(space, w_int):
+    return W_SmallLongObject(r_longlong(w_int.intval))
+
+def delegate_SmallLong2Long(space, w_small):
+    return W_LongObject(w_small.asbigint())
+
+def delegate_SmallLong2Float(space, w_small):
+    return space.newfloat(float(w_small.longlong))
+
+def delegate_SmallLong2Complex(space, w_small):
+    return space.newcomplex(float(w_small.longlong), 0.0)
+
+
+def long__SmallLong(space, w_value):
+    return w_value
+
+def int__SmallLong(space, w_value):
+    a = w_value.longlong
+    b = intmask(a)
+    if b == a:
+        return space.newint(b)
+    else:
+        return w_value
+
+def index__SmallLong(space, w_value):
+    return w_value
+
+def float__SmallLong(space, w_value):
+    return space.newfloat(float(w_value.longlong))
+
+def int_w__SmallLong(space, w_value):
+    a = w_value.longlong
+    b = intmask(a)
+    if b == a:
+        return b
+    else:
+        raise OperationError(space.w_OverflowError, space.wrap(
+            "long int too large to convert to int"))
+
+def uint_w__SmallLong(space, w_value):
+    a = w_value.longlong
+    if a < 0:
+        raise OperationError(space.w_ValueError, space.wrap(
+            "cannot convert negative integer to unsigned int"))
+    b = r_uint(a)
+    if r_longlong(b) == a:
+        return b
+    else:
+        raise OperationError(space.w_OverflowError, space.wrap(
+            "long int too large to convert to unsigned int"))
+
+def bigint_w__SmallLong(space, w_value):
+    return w_value.asbigint()
+
+def lt__SmallLong_SmallLong(space, w_small1, w_small2):
+    return space.newbool(w_small1.longlong <  w_small2.longlong)
+def le__SmallLong_SmallLong(space, w_small1, w_small2):
+    return space.newbool(w_small1.longlong <= w_small2.longlong)
+def eq__SmallLong_SmallLong(space, w_small1, w_small2):
+    return space.newbool(w_small1.longlong == w_small2.longlong)
+def ne__SmallLong_SmallLong(space, w_small1, w_small2):
+    return space.newbool(w_small1.longlong != w_small2.longlong)
+def gt__SmallLong_SmallLong(space, w_small1, w_small2):
+    return space.newbool(w_small1.longlong >  w_small2.longlong)
+def ge__SmallLong_SmallLong(space, w_small1, w_small2):
+    return space.newbool(w_small1.longlong >= w_small2.longlong)
+
+def lt__SmallLong_Long(space, w_small1, w_long2):
+    return space.newbool(w_small1.asbigint().lt(w_long2.num))
+def le__SmallLong_Long(space, w_small1, w_long2):
+    return space.newbool(w_small1.asbigint().le(w_long2.num))
+def eq__SmallLong_Long(space, w_small1, w_long2):
+    return space.newbool(w_small1.asbigint().eq(w_long2.num))
+def ne__SmallLong_Long(space, w_small1, w_long2):
+    return space.newbool(w_small1.asbigint().ne(w_long2.num))
+def gt__SmallLong_Long(space, w_small1, w_long2):
+    return space.newbool(w_small1.asbigint().gt(w_long2.num))
+def ge__SmallLong_Long(space, w_small1, w_long2):
+    return space.newbool(w_small1.asbigint().ge(w_long2.num))
+
+def lt__Long_SmallLong(space, w_long1, w_small2):
+    return space.newbool(w_long1.num.lt(w_small2.asbigint()))
+def le__Long_SmallLong(space, w_long1, w_small2):
+    return space.newbool(w_long1.num.le(w_small2.asbigint()))
+def eq__Long_SmallLong(space, w_long1, w_small2):
+    return space.newbool(w_long1.num.eq(w_small2.asbigint()))
+def ne__Long_SmallLong(space, w_long1, w_small2):
+    return space.newbool(w_long1.num.ne(w_small2.asbigint()))
+def gt__Long_SmallLong(space, w_long1, w_small2):
+    return space.newbool(w_long1.num.gt(w_small2.asbigint()))
+def ge__Long_SmallLong(space, w_long1, w_small2):
+    return space.newbool(w_long1.num.ge(w_small2.asbigint()))
+
+def lt__SmallLong_Int(space, w_small1, w_int2):
+    return space.newbool(w_small1.longlong <  w_int2.intval)
+def le__SmallLong_Int(space, w_small1, w_int2):
+    return space.newbool(w_small1.longlong <= w_int2.intval)
+def eq__SmallLong_Int(space, w_small1, w_int2):
+    return space.newbool(w_small1.longlong == w_int2.intval)
+def ne__SmallLong_Int(space, w_small1, w_int2):
+    return space.newbool(w_small1.longlong != w_int2.intval)
+def gt__SmallLong_Int(space, w_small1, w_int2):
+    return space.newbool(w_small1.longlong >  w_int2.intval)
+def ge__SmallLong_Int(space, w_small1, w_int2):
+    return space.newbool(w_small1.longlong >= w_int2.intval)
+
+def lt__Int_SmallLong(space, w_int1, w_small2):
+    return space.newbool(w_int1.intval <  w_small2.longlong)
+def le__Int_SmallLong(space, w_int1, w_small2):
+    return space.newbool(w_int1.intval <= w_small2.longlong)
+def eq__Int_SmallLong(space, w_int1, w_small2):
+    return space.newbool(w_int1.intval == w_small2.longlong)
+def ne__Int_SmallLong(space, w_int1, w_small2):
+    return space.newbool(w_int1.intval != w_small2.longlong)
+def gt__Int_SmallLong(space, w_int1, w_small2):
+    return space.newbool(w_int1.intval >  w_small2.longlong)
+def ge__Int_SmallLong(space, w_int1, w_small2):
+    return space.newbool(w_int1.intval >= w_small2.longlong)
+
+
+#hash: default implementation via Longs  (a bit messy)
+
+def add__SmallLong_SmallLong(space, w_small1, w_small2):
+    x = w_small1.longlong
+    y = w_small2.longlong
+    try:
+        z = ovfcheck(x + y)
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                    space.wrap("integer addition"))
+    return W_SmallLongObject(z)
+
+def add_ovr(space, w_int1, w_int2):
+    x = r_longlong(w_int1.intval)
+    y = r_longlong(w_int2.intval)
+    return W_SmallLongObject(x + y)
+
+def sub__SmallLong_SmallLong(space, w_small1, w_small2):
+    x = w_small1.longlong
+    y = w_small2.longlong
+    try:
+        z = ovfcheck(x - y)
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                    space.wrap("integer subtraction"))
+    return W_SmallLongObject(z)
+
+def sub_ovr(space, w_int1, w_int2):
+    x = r_longlong(w_int1.intval)
+    y = r_longlong(w_int2.intval)
+    return W_SmallLongObject(x - y)
+
+def mul__SmallLong_SmallLong(space, w_small1, w_small2):
+    x = w_small1.longlong
+    y = w_small2.longlong
+    try:
+        z = ovfcheck(x * y)
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                    space.wrap("integer multiplication"))
+    return W_SmallLongObject(z)
+
+def mul_ovr(space, w_int1, w_int2):
+    x = r_longlong(w_int1.intval)
+    y = r_longlong(w_int2.intval)
+    return W_SmallLongObject(x * y)
+
+#truediv: default implementation via Longs
+
+def floordiv__SmallLong_SmallLong(space, w_small1, w_small2):
+    x = w_small1.longlong
+    y = w_small2.longlong
+    try:
+        z = ovfcheck(x // y)
+    except ZeroDivisionError:
+        raise OperationError(space.w_ZeroDivisionError,
+                             space.wrap("integer division by zero"))
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                space.wrap("integer division"))
+    return W_SmallLongObject(z)
+div__SmallLong_SmallLong = floordiv__SmallLong_SmallLong
+
+def floordiv_ovr(space, w_int1, w_int2):
+    x = r_longlong(w_int1.intval)
+    y = r_longlong(w_int2.intval)
+    return W_SmallLongObject(x // y)
+div_ovr = floordiv_ovr
+
+def mod__SmallLong_SmallLong(space, w_small1, w_small2):
+    x = w_small1.longlong
+    y = w_small2.longlong
+    try:
+        z = ovfcheck(x % y)
+    except ZeroDivisionError:
+        raise OperationError(space.w_ZeroDivisionError,
+                             space.wrap("integer modulo by zero"))
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                space.wrap("integer modulo"))
+    return W_SmallLongObject(z)
+
+def mod_ovr(space, w_int1, w_int2):
+    x = r_longlong(w_int1.intval)
+    y = r_longlong(w_int2.intval)
+    return W_SmallLongObject(x % y)
+
+def divmod__SmallLong_SmallLong(space, w_small1, w_small2):
+    x = w_small1.longlong
+    y = w_small2.longlong
+    try:
+        z = ovfcheck(x // y)
+    except ZeroDivisionError:
+        raise OperationError(space.w_ZeroDivisionError,
+                             space.wrap("integer divmod by zero"))
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                space.wrap("integer modulo"))
+    # no overflow possible
+    m = x % y
+    return space.newtuple([W_SmallLongObject(z), W_SmallLongObject(m)])
+
+def divmod_ovr(space, w_int1, w_int2):
+    return space.newtuple([div_ovr(space, w_int1, w_int2),
+                           mod_ovr(space, w_int1, w_int2)])
+
+def _impl_pow(space, iv, w_int2, iz=r_longlong(0)):
+    iw = w_int2.intval
+    if iw < 0:
+        if iz != 0:
+            raise OperationError(space.w_TypeError,
+                             space.wrap("pow() 2nd argument "
+                 "cannot be negative when 3rd argument specified"))
+        ## bounce it, since it always returns float
+        raise FailedToImplementArgs(space.w_ValueError,
+                                space.wrap("integer exponentiation"))
+    temp = iv
+    ix = r_longlong(1)
+    try:
+        while iw > 0:
+            if iw & 1:
+                ix = ovfcheck(ix*temp)
+            iw >>= 1   #/* Shift exponent down by 1 bit */
+            if iw==0:
+                break
+            temp = ovfcheck(temp*temp) #/* Square the value of temp */
+            if iz:
+                #/* If we did a multiplication, perform a modulo */
+                ix = ix % iz
+                temp = temp % iz
+        if iz:
+            ix = ix % iz
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                space.wrap("integer exponentiation"))
+    return W_SmallLongObject(ix)
+
+def pow__SmallLong_Int_SmallLong(space, w_small1, w_int2, w_small3):
+    z = w_small3.longlong
+    if z == 0:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("pow() 3rd argument cannot be 0"))
+    return _impl_pow(space, w_small1.longlong, w_int2, z)
+
+def pow__SmallLong_Int_None(space, w_small1, w_int2, _):
+    return _impl_pow(space, w_small1.longlong, w_int2)
+
+def pow_ovr(space, w_int1, w_int2):
+    try:
+        return _impl_pow(space, r_longlong(w_int1.intval), w_int2)
+    except FailedToImplementArgs:
+        from pypy.objspace.std import longobject
+        w_a = W_LongObject.fromint(space, w_int1.intval)
+        w_b = W_LongObject.fromint(space, w_int2.intval)
+        return longobject.pow__Long_Long_None(space, w_a, w_b, space.w_None)
+
+def neg__SmallLong(space, w_small):
+    a = w_small.longlong
+    try:
+        x = ovfcheck(-a)
+    except OverflowError:
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                space.wrap("integer negation"))
+    return W_SmallLongObject(x)
+get_negint = neg__SmallLong
+
+def neg_ovr(space, w_int):
+    a = r_longlong(w_int.intval)
+    return W_SmallLongObject(-a)
+
+
+def pos__SmallLong(space, w_small):
+    return w_small
+
+def abs__SmallLong(space, w_small):
+    if w_small.longlong >= 0:
+        return w_small
+    else:
+        return get_negint(space, w_small)
+
+def abs_ovr(space, w_int):
+    a = r_longlong(w_int.intval)
+    if a < 0: a = -a
+    return W_SmallLongObject(a)
+
+def nonzero__SmallLong(space, w_small):
+    return space.newbool(bool(w_small.longlong))
+
+def invert__SmallLong(space, w_small):
+    x = w_small.longlong
+    a = ~x
+    return W_SmallLongObject(a)
+
+def lshift__SmallLong_Int(space, w_small1, w_int2):
+    a = w_small1.longlong
+    b = w_int2.intval
+    if r_uint(b) < LONGLONG_BIT: # 0 <= b < LONGLONG_BIT
+        try:
+            c = ovfcheck(a << b)
+        except OverflowError:
+            raise FailedToImplementArgs(space.w_OverflowError,
+                                    space.wrap("integer left shift"))
+        return W_SmallLongObject(c)
+    if b < 0:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("negative shift count"))
+    else: #b >= LONGLONG_BIT
+        if a == 0:
+            return w_small1
+        raise FailedToImplementArgs(space.w_OverflowError,
+                                space.wrap("integer left shift"))
+
+def lshift_ovr(space, w_int1, w_int2):
+    a = r_longlong(w_int1.intval)
+    try:
+        return lshift__SmallLong_Int(space, W_SmallLongObject(a), w_int2)
+    except FailedToImplementArgs:
+        from pypy.objspace.std import longobject
+        w_a = W_LongObject.fromint(space, w_int1.intval)
+        w_b = W_LongObject.fromint(space, w_int2.intval)
+        return longobject.lshift__Long_Long(space, w_a, w_b)
+
+def rshift__SmallLong_Int(space, w_small1, w_int2):
+    a = w_small1.longlong
+    b = w_int2.intval
+    if r_uint(b) >= LONGLONG_BIT: # not (0 <= b < LONGLONG_BIT)
+        if b < 0:
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("negative shift count"))
+        else: # b >= LONGLONG_BIT
+            if a == 0:
+                return w_small1
+            if a < 0:
+                a = -1
+            else:
+                a = 0
+    else:
+        a = a >> b
+    return W_SmallLongObject(a)
+
+def and__SmallLong_SmallLong(space, w_small1, w_small2):
+    a = w_small1.longlong
+    b = w_small2.longlong
+    res = a & b
+    return W_SmallLongObject(res)
+
+def xor__SmallLong_SmallLong(space, w_small1, w_small2):
+    a = w_small1.longlong
+    b = w_small2.longlong
+    res = a ^ b
+    return W_SmallLongObject(res)
+
+def or__SmallLong_SmallLong(space, w_small1, w_small2):
+    a = w_small1.longlong
+    b = w_small2.longlong
+    res = a | b
+    return W_SmallLongObject(res)
+
+#oct: default implementation via Longs
+#hex: default implementation via Longs
+#getnewargs: default implementation via Longs
+
+register_all(vars())

Modified: pypy/branch/smalllong/pypy/objspace/std/strutil.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/strutil.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/strutil.py	Wed Nov  3 12:40:46 2010
@@ -205,67 +205,66 @@
         digits = '0'
 
     # a few abbreviations
-    from pypy.objspace.std import longobject
-    mklong = longobject.W_LongObject.fromint
-    d2long = longobject.W_LongObject.fromdecimalstr
-    adlong = longobject.add__Long_Long
-    longup = longobject.pow__Long_Long_None
-    multip = longobject.mul__Long_Long
-    divide = longobject.div__Long_Long
-    lshift = longobject.lshift__Long_Long
-    rshift = longobject.rshift__Long_Long
+    from pypy.rlib.rbigint import rbigint
+    mklong = rbigint.fromint
+    d2long = rbigint.fromdecimalstr
+    adlong = rbigint.static_add
+    longup = rbigint.static_pow
+    multip = rbigint.static_mul
+    divide = rbigint.static_floordiv
+    lshift = rbigint.static_lshift
+    rshift = rbigint.static_rshift
 
     # 4) compute the exponent and truncate to +-400
     if not exponent:
         exponent = '0'
-    w_le = d2long(exponent)
-    w_le = adlong(space, w_le, mklong(space, dexp))
+    b_le = d2long(exponent)
+    b_le = adlong(b_le, mklong(dexp))
     try:
-        e = w_le.toint()
+        e = b_le.toint()
     except OverflowError:
-        # XXX poking at internals
-        e = w_le.num.sign * 400
+        e = b_le.getsign() * 400
     if e >= 400:
         e = 400
     elif e <= -400:
         e = -400
 
     # 5) compute the value using long math and proper rounding.
-    w_lr = d2long(digits)
-    w_10 = mklong(space, 10)
-    w_1 = mklong(space, 1)
+    b_lr = d2long(digits)
+    b_10 = mklong(10)
+    b_1 = mklong(1)
     if e >= 0:
         bits = 0
-        w_pten = longup(space, w_10, mklong(space, e), space.w_None)
-        w_m = multip(space, w_lr, w_pten)
+        b_pten = longup(b_10, mklong(e))
+        b_m = multip(b_lr, b_pten)
     else:
         # compute a sufficiently large scale
         prec = MANTISSA_DIGITS * 2 + 22 # 128, maybe
         bits = - (int(math.ceil(-e / math.log10(2.0) - 1e-10)) + prec)
-        w_scale = lshift(space, w_1, mklong(space, -bits))
-        w_pten = longup(space, w_10, mklong(space, -e), None)
-        w_tmp = multip(space, w_lr, w_scale)
-        w_m = divide(space, w_tmp, w_pten)
+        b_scale = lshift(b_1, -bits)
+        b_pten = longup(b_10, mklong(-e))
+        b_tmp = multip(b_lr, b_scale)
+        b_m = divide(b_tmp, b_pten)
 
     # we now have a fairly large mantissa.
     # Shift it and round the last bit.
 
     # first estimate the bits and do a big shift
-    mbits = w_m._count_bits()
+    mbits = b_m._count_bits()
     needed = MANTISSA_BITS
     if mbits > needed:
         if mbits > needed+1:
             shifted = mbits - (needed+1)
-            w_m = rshift(space, w_m, mklong(space, shifted))
+            b_m = rshift(b_m, shifted)
             bits += shifted
         # do the rounding
         bits += 1
-        round = w_m.is_odd()
-        w_m = rshift(space, w_m, w_1)
-        w_m = adlong(space, w_m, mklong(space, round))
+        round = b_m.is_odd()
+        b_m = rshift(b_m, 1)
+        b_m = adlong(b_m, mklong(round))
 
     try:
-        r = math.ldexp(w_m.tofloat(), bits)
+        r = math.ldexp(b_m.tofloat(), bits)
         # XXX I guess we do not check for overflow in ldexp as we agreed to!
         if r == 2*r and r != 0.0:
             raise OverflowError

Modified: pypy/branch/smalllong/pypy/objspace/std/test/test_smalllongobject.py
==============================================================================
--- pypy/branch/smalllong/pypy/objspace/std/test/test_smalllongobject.py	(original)
+++ pypy/branch/smalllong/pypy/objspace/std/test/test_smalllongobject.py	Wed Nov  3 12:40:46 2010
@@ -1,5 +1,39 @@
+import py
+import sys
+from pypy.objspace.std.smalllongobject import W_SmallLongObject
 from pypy.objspace.std.test import test_longobject
 from pypy.conftest import gettestobjspace
+from pypy.rlib.rarithmetic import r_longlong
+from pypy.interpreter.error import OperationError
+
+
+def test_direct():
+    space = gettestobjspace(**{"objspace.std.withsmalllong": True})
+    w5 = space.wrap(r_longlong(5))
+    assert isinstance(w5, W_SmallLongObject)
+    wlarge = space.wrap(r_longlong(0x123456789ABCDEFL))
+    #
+    assert space.int_w(w5) == 5
+    if sys.maxint < 0x123456789ABCDEFL:
+        py.test.raises(OperationError, space.int_w, wlarge)
+    else:
+        assert space.int_w(wlarge) == 0x123456789ABCDEF
+    #
+    assert space.pos(w5) is w5
+    assert space.abs(w5) is w5
+    wm5 = space.wrap(r_longlong(-5))
+    assert space.int_w(space.abs(wm5)) == 5
+    assert space.int_w(space.neg(w5)) == -5
+    assert space.is_true(w5) is True
+    assert space.is_true(wm5) is True
+    w0 = space.wrap(r_longlong(0))
+    assert space.is_true(w0) is False
+    #
+    w14000000000000 = space.wrap(r_longlong(0x14000000000000L))
+    assert space.is_true(space.eq(
+        space.lshift(w5, space.wrap(49)), w14000000000000)) is False
+    assert space.is_true(space.eq(
+        space.lshift(w5, space.wrap(50)), w14000000000000)) is True
 
 
 class AppTestSmallLong(test_longobject.AppTestLong):
@@ -10,3 +44,75 @@
         import __pypy__
         s = __pypy__.internal_repr(5L)
         assert 'SmallLong' in s
+
+    def test_sl_hash(self):
+        import __pypy__
+        x = 5L
+        assert 'SmallLong' in __pypy__.internal_repr(x)
+        assert hash(5) == hash(x)
+        biglong = 5L
+        biglong ^= 2**100      # hack based on the fact that xor__Long_Long
+        biglong ^= 2**100      # does not call newlong()
+        assert biglong == 5L
+        assert 'SmallLong' not in __pypy__.internal_repr(biglong)
+        assert hash(5) == hash(biglong)
+        #
+        x = 0x123456789ABCDEFL
+        assert 'SmallLong' in __pypy__.internal_repr(x)
+        biglong = x
+        biglong ^= 2**100
+        biglong ^= 2**100
+        assert biglong == x
+        assert 'SmallLong' not in __pypy__.internal_repr(biglong)
+        assert hash(biglong) == hash(x)
+
+    def test_sl_int(self):
+        x = 0x123456789ABCDEFL
+        two = 2
+        assert int(x) == x
+        assert type(int(x)) == type(0x1234567 ** two)
+        y = x >> 32
+        assert int(y) == y
+        assert type(int(y)) is int
+
+    def test_sl_long(self):
+        import __pypy__
+        x = long(0)
+        assert 'SmallLong' in __pypy__.internal_repr(x)
+
+    def test_sl_add(self):
+        import __pypy__
+        x = 0x123456789ABCDEFL
+        assert x + x == 0x2468ACF13579BDEL
+        assert 'SmallLong' in __pypy__.internal_repr(x + x)
+        x = -0x123456789ABCDEFL
+        assert x + x == -0x2468ACF13579BDEL
+        assert 'SmallLong' in __pypy__.internal_repr(x + x)
+        x = 0x723456789ABCDEF0L
+        assert x + x == 0xE468ACF13579BDE0L
+        assert 'SmallLong' not in __pypy__.internal_repr(x + x)
+        x = -0x723456789ABCDEF0L
+        assert x + x == -0xE468ACF13579BDE0L
+        assert 'SmallLong' not in __pypy__.internal_repr(x + x)
+
+    def test_sl_add_32(self):
+        import sys, __pypy__
+        if sys.maxint == 2147483647:
+            x = 2147483647
+            assert x + x == 4294967294L
+            assert 'SmallLong' in __pypy__.internal_repr(x + x)
+            y = -1
+            assert x - y == 2147483648L
+            assert 'SmallLong' in __pypy__.internal_repr(x - y)
+
+    def test_sl_lshift(self):
+        for x in [1, 1L]:
+            assert x << 1 == 2L
+            assert x << 30 == 1073741824L
+            assert x << 31 == 2147483648L
+            assert x << 32 == 4294967296L
+            assert x << 62 == 4611686018427387904L
+            assert x << 63 == 9223372036854775808L
+            assert x << 64 == 18446744073709551616L
+            assert (x << 31) << 31 == 4611686018427387904L
+            assert (x << 32) << 32 == 18446744073709551616L

Modified: pypy/branch/smalllong/pypy/rlib/rarithmetic.py
==============================================================================
--- pypy/branch/smalllong/pypy/rlib/rarithmetic.py	(original)
+++ pypy/branch/smalllong/pypy/rlib/rarithmetic.py	Wed Nov  3 12:40:46 2010
@@ -49,6 +49,9 @@
 LONG_BIT = _bits+1
 LONG_MASK = _Ltest*2-1
 LONG_TEST = _Ltest
+LONGLONG_BIT  = 64
+LONGLONG_MASK = (2**LONGLONG_BIT)-1
+LONGLONG_TEST = 2**(LONGLONG_BIT-1)
 
 LONG_BIT_SHIFT = 0
 while (1 << LONG_BIT_SHIFT) != LONG_BIT:
@@ -76,6 +79,15 @@
         n -= 2*LONG_TEST
     return int(n)
 
+def longlongmask(n):
+    if isinstance(n, int):
+        n = long(n)
+    assert isinstance(n, long)
+    n &= LONGLONG_MASK
+    if n >= LONGLONG_TEST:
+        n -= 2*LONGLONG_TEST
+    return r_longlong(n)
+
 def widen(n):
     from pypy.rpython.lltypesystem import lltype
     if _should_widen_type(lltype.typeOf(n)):
@@ -389,6 +401,8 @@
 r_longlong = build_int('r_longlong', True, 64)
 r_ulonglong = build_int('r_ulonglong', False, 64)
 
+longlongmax = r_longlong(LONGLONG_TEST - 1)
+
 
 # float as string  -> sign, beforept, afterpt, exponent
 

Modified: pypy/branch/smalllong/pypy/rlib/rbigint.py
==============================================================================
--- pypy/branch/smalllong/pypy/rlib/rbigint.py	(original)
+++ pypy/branch/smalllong/pypy/rlib/rbigint.py	Wed Nov  3 12:40:46 2010
@@ -558,6 +558,34 @@
         if self._numdigits() == 1 and self.digits[0] == 0:
             self.sign = 0
 
+    def getsign(self):
+        return self.sign
+
+
+    @staticmethod
+    def static_add(a, b):
+        return a.add(b)
+
+    @staticmethod
+    def static_mul(a, b):
+        return a.mul(b)
+
+    @staticmethod
+    def static_floordiv(a, b):
+        return a.floordiv(b)
+
+    @staticmethod
+    def static_lshift(a, b):
+        return a.lshift(b)
+
+    @staticmethod
+    def static_rshift(a, b):
+        return a.rshift(b)
+
+    @staticmethod
+    def static_pow(a, b):
+        return a.pow(b)
+
 
     def __repr__(self):
         return "<rbigint digits=%s, sign=%s, %s>" % (self.digits, self.sign, self.str())

Modified: pypy/branch/smalllong/pypy/translator/c/src/int.h
==============================================================================
--- pypy/branch/smalllong/pypy/translator/c/src/int.h	(original)
+++ pypy/branch/smalllong/pypy/translator/c/src/int.h	Wed Nov  3 12:40:46 2010
@@ -64,6 +64,11 @@
 	if ((r^(x)) >= 0 || (r^(y)) >= 0); \
 	else FAIL_OVF("integer addition")
 
+#define OP_LLONG_ADD_OVF(x,y,r) \
+	OP_LLONG_ADD(x,y,r); \
+	if ((r^(x)) >= 0 || (r^(y)) >= 0); \
+	else FAIL_OVF("integer addition")
+
 #define OP_INT_ADD_NONNEG_OVF(x,y,r)  /* y can be assumed >= 0 */ \
     r = (long)((unsigned long)x + (unsigned long)y); \
     if (r >= (x)); \
@@ -78,22 +83,17 @@
 	if ((r^(x)) >= 0 || (r^~(y)) >= 0); \
 	else FAIL_OVF("integer subtraction")
 
-#define OP_INT_MUL(x,y,r)     r = (x) * (y)
-
-#if defined(HAVE_LONG_LONG) && SIZE_OF_LONG_LONG < SIZE_OF_LONG
-#  define OP_INT_MUL_OVF_LL      1
-#lse
-#  define OP_INT_MUL_OVF_LL      0
-#endif
+#define OP_LLONG_SUB_OVF(x,y,r) \
+	OP_LLONG_SUB(x,y,r); \
+	if ((r^(x)) >= 0 || (r^~(y)) >= 0); \
+	else FAIL_OVF("integer subtraction")
 
-#if !OP_INT_MUL_OVF_LL
+#define OP_INT_MUL(x,y,r)     r = (x) * (y)
 
+#if SIZE_OF_LONG == SIZE_OF_LONG_LONG
 #define OP_INT_MUL_OVF(x,y,r) \
-	if (op_int_mul_ovf(x,y,&r)); \
-	else FAIL_OVF("integer multiplication")
-
+	r = op_llong_mul_ovf(x, y)
 #else
-
 #define OP_INT_MUL_OVF(x,y,r) \
 	{ \
 		PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y); \
@@ -103,6 +103,9 @@
 	}
 #endif
 
+#define OP_LLONG_MUL_OVF(x,y,r) \
+	r = op_llong_mul_ovf(x, y)
+
 /* shifting */
 
 /* NB. shifting has same limitations as C: the shift count must be
@@ -121,6 +124,10 @@
 	OP_INT_LSHIFT(x,y,r); \
 	if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \
 		FAIL_OVF("x<<y losing bits or changing sign")
+#define OP_LLONG_LSHIFT_OVF(x,y,r) \
+	OP_LLONG_LSHIFT(x,y,r); \
+	if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(PY_LONG_LONG, r, (y))) \
+		FAIL_OVF("x<<y losing bits or changing sign")
 
 /* floor division */
 
@@ -133,6 +140,10 @@
 	if ((y) == -1 && (x) == LONG_MIN) \
             { FAIL_OVF("integer division"); } \
         else OP_INT_FLOORDIV(x,y,r)
+#define OP_LLONG_FLOORDIV_OVF(x,y,r) \
+	if ((y) == -1 && (x) == LLONG_MIN) \
+            { FAIL_OVF("integer division"); } \
+        else OP_LLONG_FLOORDIV(x,y,r)
 
 #define OP_INT_FLOORDIV_ZER(x,y,r) \
 	if ((y)) { OP_INT_FLOORDIV(x,y,r); } \
@@ -150,6 +161,9 @@
 #define OP_INT_FLOORDIV_OVF_ZER(x,y,r) \
 	if ((y)) { OP_INT_FLOORDIV_OVF(x,y,r); } \
 	else FAIL_ZER("integer division")
+#define OP_LLONG_FLOORDIV_OVF_ZER(x,y,r) \
+	if ((y)) { OP_LLONG_FLOORDIV_OVF(x,y,r); } \
+	else FAIL_ZER("integer division")
 
 /* modulus */
 
@@ -162,6 +176,10 @@
 	if ((y) == -1 && (x) == LONG_MIN) \
             { FAIL_OVF("integer modulo"); }\
         else OP_INT_MOD(x,y,r)
+#define OP_LLONG_MOD_OVF(x,y,r) \
+	if ((y) == -1 && (x) == LLONG_MIN) \
+            { FAIL_OVF("integer modulo"); }\
+        else OP_LLONG_MOD(x,y,r)
 
 #define OP_INT_MOD_ZER(x,y,r) \
 	if ((y)) { OP_INT_MOD(x,y,r); } \
@@ -179,6 +197,9 @@
 #define OP_INT_MOD_OVF_ZER(x,y,r) \
 	if ((y)) { OP_INT_MOD_OVF(x,y,r); } \
 	else FAIL_ZER("integer modulo")
+#define OP_LLONG_MOD_OVF_ZER(x,y,r) \
+	if ((y)) { OP_LLONG_MOD_OVF(x,y,r); } \
+	else FAIL_ZER("integer modulo")
 
 /* bit operations */
 
@@ -208,31 +229,31 @@
 
 /* _________________ certain implementations __________________ */
 
-#if !OP_INT_MUL_OVF_LL
 /* adjusted from intobject.c, Python 2.3.3 */
 
 /* prototypes */
 
-int op_int_mul_ovf(long a, long b, long *longprod);
+PY_LONG_LONG op_llong_mul_ovf(PY_LONG_LONG a, PY_LONG_LONG b);
 
 /* implementations */
 
 #ifndef PYPY_NOT_MAIN_FILE
 
-int
-op_int_mul_ovf(long a, long b, long *longprod)
+PY_LONG_LONG
+op_llong_mul_ovf(PY_LONG_LONG a, PY_LONG_LONG b)
 {
 	double doubled_longprod;	/* (double)longprod */
 	double doubleprod;		/* (double)a * (double)b */
+        PY_LONG_LONG longprod;
 
-	*longprod = a * b;
+	longprod = a * b;
 	doubleprod = (double)a * (double)b;
-	doubled_longprod = (double)*longprod;
+	doubled_longprod = (double)longprod;
 
 	/* Fast path for normal case:  small multiplicands, and no info
 	   is lost in either method. */
 	if (doubled_longprod == doubleprod)
-		return 1;
+		return longprod;
 
 	/* Somebody somewhere lost info.  Close enough, or way off?  Note
 	   that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
@@ -247,15 +268,15 @@
 		/* absdiff/absprod <= 1/32 iff
 		   32 * absdiff <= absprod -- 5 good bits is "close enough" */
 		if (32.0 * absdiff <= absprod)
-			return 1;
-		return 0;
+			return longprod;
+
+                FAIL_OVF("integer multiplication");
+		return -1;
 	}
 }
 
 #endif /* PYPY_NOT_MAIN_FILE */
 
-#endif /* !OP_INT_MUL_OVF_LL */
-
 /* implementations */
 
 #define OP_UINT_IS_TRUE OP_INT_IS_TRUE



More information about the Pypy-commit mailing list