Commits

Philip Jenvey committed 3ef7d15

most of smalllong's SMM removal

Comments (0)

Files changed (5)

pypy/objspace/std/floatobject.py

 
 # long-to-float delegation
 def delegate_Long2Float(space, w_longobj):
+    # XXX: tofloat is not abstract (SmallLongs)
     return W_FloatObject(w_longobj.tofloat(space))
 
 

pypy/objspace/std/intobject.py

 for overflows, something CPython does not do anymore.
 """
 
+import operator
+
 from rpython.rlib import jit
 from rpython.rlib.rarithmetic import (
     LONG_BIT, is_valid_int, ovfcheck, string_to_int, r_uint)
 
     def _make_descr_binop(opname):
         # XXX: func_renamer or func_with_new_name?
-        import operator
         from rpython.tool.sourcetools import func_renamer
         op = getattr(operator, opname)
 
     descr_mul, descr_rmul = _make_descr_binop('mul')
 
     def _make_descr_cmp(opname):
-        import operator
         op = getattr(operator, opname)
         def f(self, space, w_other):
+            # XXX: this doesn't belong here, regardless of how we originally set this up. blargh
+            #if isinstance(w_other, W_SmallLongObject):
+            #    return space.newbool(op(space.int_w(self), w_other.longlong))
             if not space.isinstance_w(w_other, space.w_int):
                 return space.w_NotImplemented
 
         b = b.lshift(3).or_(rbigint.fromint(tag))
         return space.newlong_from_rbigint(b)
 
-    def unwrap(self, space):
+    def int_w(self, space):
         return int(self.intval)
-    int_w = unwrap
+    unwrap = int_w
 
     def uint_w(self, space):
         intval = self.intval
     def descr_repr(self, space):
         res = str(self.intval)
         return space.wrap(res)
-
     descr_str = func_with_new_name(descr_repr, 'descr_str')
 
 def _delegate_Int2Long(space, w_intobj):

pypy/objspace/std/longobject.py

 
 from rpython.rlib.rbigint import rbigint
 from rpython.rlib.rstring import ParseStringError
-from rpython.tool.sourcetools import func_with_new_name
+from rpython.tool.sourcetools import func_renamer, func_with_new_name
 
 from pypy.interpreter import typedef
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.objspace.std.stdtypedef import StdTypeDef
 
 
+def delegate_other(func):
+    @func_renamer(func.__name__)
+    def delegated(self, space, w_other):
+        if space.isinstance_w(w_other, space.w_int):
+            w_other = _delegate_Int2Long(space, w_other)
+        elif not space.isinstance_w(w_other, space.w_long):
+            return space.w_NotImplemented
+        # XXX: if a smalllong, delegate to Long?
+        assert isinstance(w_other, W_AbstractLongObject)
+        return func(self, space, w_other)
+    return delegated
+
+def _delegate_Int2Long(space, w_intobj):
+    """int-to-long delegation"""
+    return W_LongObject.fromint(space, w_intobj.int_w(space))
+
+
 class W_AbstractLongObject(W_Object):
     __slots__ = ()
 
     def int(self, space):
         raise NotImplementedError
 
+    def asbigint(self):
+        raise NotImplementedError
+
+    def descr_long(self, space):
+        raise NotImplementedError
+    descr_index = func_with_new_name(descr_long, 'descr_index')
+    descr_trunc = func_with_new_name(descr_long, 'descr_trunc')
+    descr_pos = func_with_new_name(descr_long, 'descr_pos')
+
+    # XXX:
+    def descr_float(self, space):
+        raise NotImplementedError
+    descr_neg = func_with_new_name(descr_long, 'descr_neg')
+    descr_pos = func_with_new_name(descr_long, 'descr_pos')
+    descr_abs = func_with_new_name(descr_long, 'descr_abs')
+    descr_nonzero = func_with_new_name(descr_long, 'descr_nonzero')
+    descr_invert = func_with_new_name(descr_long, 'descr_invert')
+
+    def descr_lt(self, space, w_other):
+        raise NotImplementedError
+    descr_le = func_with_new_name(descr_lt, 'descr_le')
+    descr_eq = func_with_new_name(descr_lt, 'descr_eq')
+    descr_ne = func_with_new_name(descr_lt, 'descr_ne')
+    descr_gt = func_with_new_name(descr_lt, 'descr_gt')
+    descr_ge = func_with_new_name(descr_lt, 'descr_ge')
+
+    descr_add = func_with_new_name(descr_lt, 'descr_add')
+    descr_radd = func_with_new_name(descr_lt, 'descr_radd')
+    descr_sub = func_with_new_name(descr_lt, 'descr_sub')
+    descr_rsub = func_with_new_name(descr_lt, 'descr_rsub')
+    descr_mul = func_with_new_name(descr_lt, 'descr_mul')
+    descr_rmul = func_with_new_name(descr_lt, 'descr_rmul')
+
+    descr_and = func_with_new_name(descr_lt, 'descr_and')
+    descr_rand = func_with_new_name(descr_lt, 'descr_rand')
+    descr_or = func_with_new_name(descr_lt, 'descr_or')
+    descr_ror = func_with_new_name(descr_lt, 'descr_ror')
+    descr_xor = func_with_new_name(descr_lt, 'descr_xor')
+    descr_rxor = func_with_new_name(descr_lt, 'descr_rxor')
+
+    descr_lshift = func_with_new_name(descr_lt, 'descr_lshift')
+    descr_rshift = func_with_new_name(descr_lt, 'descr_rshift')
+
+    descr_floordiv = func_with_new_name(descr_lt, 'descr_floordiv')
+    descr_rfloordiv = func_with_new_name(descr_lt, 'descr_rfloordiv')
+    descr_div = func_with_new_name(descr_lt, 'descr_div')
+    descr_rdiv = func_with_new_name(descr_lt, 'descr_rdiv')
+    descr_mod = func_with_new_name(descr_lt, 'descr_mod')
+    descr_rmod = func_with_new_name(descr_lt, 'descr_rmod')
+    descr_divmod = func_with_new_name(descr_lt, 'descr_divmod')
+    descr_rdivmod = func_with_new_name(descr_lt, 'descr_rdivmod')
+
+    def descr_pow(self, space, w_exponent, w_modulus=None):
+        raise NotImplementedError
+    descr_rpow = func_with_new_name(descr_pow, 'descr_rpow')
+
+    def descr_format(self, space, w_format_spec):
+        return newformat.run_formatter(space, w_format_spec,
+                                       "format_int_or_long", self,
+                                       newformat.LONG_KIND)
+    def descr_repr(self, space):
+        return space.wrap(self.asbigint().repr())
+
+    def descr_str(self, space):
+        return space.wrap(self.asbigint().str())
+
+    def descr_hash(self, space):
+        return space.wrap(self.asbigint().hash())
+
+    def descr_oct(self, space):
+        return space.wrap(self.asbigint().oct())
+
+    def descr_hex(self, space):
+        return space.wrap(self.asbigint().hex())
+
+    def descr_getnewargs(self, space):
+        return space.newtuple([W_LongObject(self.asbigint())])
+
+    def descr_conjugate(self, space):
+        return space.long(self)
+
+    def descr_bit_length(self, space):
+        bigint = space.bigint_w(self)
+        try:
+            return space.wrap(bigint.bit_length())
+        except OverflowError:
+            raise OperationError(space.w_OverflowError,
+                                 space.wrap("too many digits in integer"))
+
+    # XXX: need rtruediv
+    @delegate_other
+    def descr_truediv(self, space, w_other):
+        try:
+            #f = self.num.truediv(w_other.num)
+            f = self.asbigint().truediv(w_other.asbigint())
+        except ZeroDivisionError:
+            raise operationerrfmt(space.w_ZeroDivisionError,
+                                  "long division or modulo by zero")
+        except OverflowError:
+            raise operationerrfmt(space.w_OverflowError,
+                                  "long/long too large for a float")
+        return space.newfloat(f)
+
+    @delegate_other
+    def descr_coerce(self, space, w_other):
+        # XXX: consider stian's branch where he optimizes long + ints
+        return space.newtuple([self, w_other])
+
 
 class W_LongObject(W_AbstractLongObject):
     """This is a wrapper of rbigint."""
         except OverflowError:
             return self.descr_long(space)
 
+    def asbigint(self):
+        return self.num
+
     def __repr__(self):
         return '<W_LongObject(%d)>' % self.num.tolong()
 
-    def descr_conjugate(self, space):
-        return space.long(self)
-
+    # XXX: make these indirect
     def descr_get_numerator(self, space):
         return space.long(self)
 
     def descr_get_imag(self, space):
         return space.newlong(0)
 
-    def descr_get_bit_length(self, space):
-        bigint = space.bigint_w(self)
-        try:
-            return space.wrap(bigint.bit_length())
-        except OverflowError:
-            raise OperationError(space.w_OverflowError,
-                                 space.wrap("too many digits in integer"))
-
     def descr_long(self, space):
         # long__Long is supposed to do nothing, unless it has a derived
         # long object, where it should return an exact one.
     def descr_float(self, space):
         return space.newfloat(self.tofloat(space))
 
-    def descr_repr(self, space):
-        return space.wrap(self.num.repr())
+    def _make_descr_cmp(opname):
+        #from pypy.objspace.std.smalllongobject import W_SmallLongObject
+        op = getattr(rbigint, opname)
+        @delegate_other
+        def descr_impl(self, space, w_other):
+            ## XXX: these only need explicit SmallLong support whereas
+            ## everything else would delegate2Long. blah blah
+            #if isinstance(w_other, W_SmallLongObject):
+            #    result = op(self.num, w_other.asbigint())
+            #else:
+            #    result = op(self.num, w_other.num)
+            #return space.newbool(result)
 
-    def descr_str(self, space):
-        return space.wrap(self.num.str())
-
-    def descr_format(self, space, w_format_spec):
-        return newformat.run_formatter(space, w_format_spec,
-                                       "format_int_or_long", self,
-                                       newformat.LONG_KIND)
-
-    def descr_hash(self, space):
-        return space.wrap(self.num.hash())
-
-    def descr_coerce(self, space, w_other):
-        # XXX: consider stian's branch where he optimizes long + ints
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-        return space.newtuple([self, w_other])
-
-    def _make_descr_cmp(opname):
-        op = getattr(rbigint, opname)
-        def descr_impl(self, space, w_other):
-            if space.isinstance_w(w_other, space.w_int):
-                w_other = _delegate_Int2Long(space, w_other)
-            elif not space.isinstance_w(w_other, space.w_long):
-                return space.w_NotImplemented
-            return space.newbool(op(self.num, w_other.num))
+            # XXX: if we use self.asbigint then can this live on
+            # AbstractLong? eek not really, a '_cmp' (_lt) could live on
+            # it that just did this (without the checks..)
+            return space.newbool(op(self.num, w_other.asbigint()))
         return func_with_new_name(descr_impl, "descr_" + opname)
 
     descr_lt = _make_descr_cmp('lt')
         op = getattr(rbigint, methname)
 
         @func_renamer('descr_' + opname)
+        @delegate_other
         def descr_binop(self, space, w_other):
-            if space.isinstance_w(w_other, space.w_int):
-                w_other = _delegate_Int2Long(space, w_other)
-            elif not space.isinstance_w(w_other, space.w_long):
-                return space.w_NotImplemented
-            return W_LongObject(op(self.num, w_other.num))
+            return W_LongObject(op(self.num, w_other.asbigint()))
 
         @func_renamer('descr_r' + opname)
+        @delegate_other
         def descr_rbinop(self, space, w_other):
-            if space.isinstance_w(w_other, space.w_int):
-                w_other = _delegate_Int2Long(space, w_other)
-            elif not space.isinstance_w(w_other, space.w_long):
-                return space.w_NotImplemented
-            return W_LongObject(op(w_other.num, self.num))
+            return W_LongObject(op(w_other.asbigint(), self.num))
 
         return descr_binop, descr_rbinop
 
     descr_abs = _make_descr_unaryop('abs')
     descr_invert = _make_descr_unaryop('invert')
 
-    def descr_oct(self, space):
-        return space.wrap(self.num.oct())
-
-    def descr_hex(self, space):
-        return space.wrap(self.num.hex())
-
     def descr_nonzero(self, space):
         return space.newbool(self.num.tobool())
 
+    @delegate_other
     def descr_lshift(self, space, w_other):
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-
         # XXX need to replicate some of the logic, to get the errors right
-        if w_other.num.sign < 0:
+        if w_other.asbigint().sign < 0:
             raise operationerrfmt(space.w_ValueError, "negative shift count")
         try:
-            shift = w_other.num.toint()
+            shift = w_other.asbigint().toint()
         except OverflowError:   # b too big
             raise operationerrfmt(space.w_OverflowError,
                                   "shift count too large")
         return W_LongObject(self.num.lshift(shift))
 
+    @delegate_other
     def descr_rshift(self, space, w_other):
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-
         # XXX need to replicate some of the logic, to get the errors right
-        if w_other.num.sign < 0:
+        if w_other.asbigint().sign < 0:
             raise operationerrfmt(space.w_ValueError, "negative shift count")
         try:
-            shift = w_other.num.toint()
+            shift = w_other.asbigint().toint()
         except OverflowError:   # b too big # XXX maybe just return 0L instead?
             raise operationerrfmt(space.w_OverflowError,
                                   "shift count too large")
         return newlong(space, self.num.rshift(shift))
 
-    # XXX: need rtruediv etc
-    def descr_truediv(self, space, w_other):
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-
+    @delegate_other
+    def descr_floordiv(self, space, w_other):
         try:
-            f = self.num.truediv(w_other.num)
+            z = self.num.floordiv(w_other.asbigint())
         except ZeroDivisionError:
             raise operationerrfmt(space.w_ZeroDivisionError,
                                   "long division or modulo by zero")
-        except OverflowError:
-            raise operationerrfmt(space.w_OverflowError,
-                                  "long/long too large for a float")
-        return space.newfloat(f)
+        return newlong(space, z)
+    descr_div = func_with_new_name(descr_floordiv, 'descr_div')
 
-    def descr_floordiv(self, space, w_other):
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-
+    @delegate_other
+    def descr_mod(self, space, w_other):
         try:
-            z = self.num.floordiv(w_other.num)
+            z = self.num.mod(w_other.asbigint())
         except ZeroDivisionError:
             raise operationerrfmt(space.w_ZeroDivisionError,
                                   "long division or modulo by zero")
         return newlong(space, z)
 
-    def descr_div(self, space, w_other):
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-
-        return self.floordiv(space, w_other)
-
-    def descr_mod(self, space, w_other):
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-
+    @delegate_other
+    def descr_divmod(self, space, w_other):
         try:
-            z = self.num.mod(w_other.num)
-        except ZeroDivisionError:
-            raise operationerrfmt(space.w_ZeroDivisionError,
-                                  "long division or modulo by zero")
-        return newlong(space, z)
-
-    def descr_divmod(self, space, w_other):
-        if space.isinstance_w(w_other, space.w_int):
-            w_other = _delegate_Int2Long(space, w_other)
-        elif not space.isinstance_w(w_other, space.w_long):
-            return space.w_NotImplemented
-
-        try:
-            div, mod = self.num.divmod(w_other.num)
+            div, mod = self.num.divmod(w_other.asbigint())
         except ZeroDivisionError:
             raise operationerrfmt(space.w_ZeroDivisionError,
                                   "long division or modulo by zero")
         return space.newtuple([newlong(space, div), newlong(space, mod)])
 
+    #@delegate_other # XXX:
     @unwrap_spec(w_modulus=WrappedDefault(None))
     def descr_pow(self, space, w_exponent, w_modulus=None):
         if space.isinstance_w(w_exponent, space.w_int):
             w_exponent = _delegate_Int2Long(space, w_exponent)
         elif not space.isinstance_w(w_exponent, space.w_long):
             return space.w_NotImplemented
-        if space.isinstance_w(w_modulus, space.w_int):
+        assert isinstance(w_exponent, W_AbstractLongObject)
+
+        #if space.is_none(w_modulus):
+        #    from pypy.objspace.std.floatobject import delegate_Long2Float
+        #    self = delegate_Long2Float(space, self)
+        #    w_exponent = delegate_Long2Float(space, w_exponent)
+        #    return space.pow(self, w_exponent, w_modulus)
+        #elif space.isinstance_w(w_modulus, space.w_int):
+        if space.is_none(w_modulus):
+            # XXX need to replicate some of the logic, to get the errors right
+            if w_exponent.asbigint().sign < 0:
+                from pypy.objspace.std.floatobject import delegate_Long2Float
+                w_exponent = delegate_Long2Float(space, w_exponent)
+                return space.pow(self.descr_float(space), w_exponent, space.w_None if w_modulus is None else w_modulus)
+            return W_LongObject(self.num.pow(w_exponent.asbigint(), None))
+        elif space.isinstance_w(w_modulus, space.w_int):
             w_modulus = _delegate_Int2Long(space, w_modulus)
-        elif space.is_none(w_modulus):
-            # XXX need to replicate some of the logic, to get the errors right
-            if w_exponent.num.sign < 0:
-                return space.pow(self.descr_float(space), w_exponent, w_modulus)
-            return W_LongObject(self.num.pow(w_exponent.num, None))
+        #elif space.is_none(w_modulus):
+        #    # XXX need to replicate some of the logic, to get the errors right
+        #    if w_exponent.num.sign < 0:
+        #        return space.pow(self.descr_float(space), w_exponent, w_modulus)
+        #    return W_LongObject(self.num.pow(w_exponent.num, None))
         elif not space.isinstance_w(w_modulus, space.w_long):
             return space.w_NotImplemented
+        assert isinstance(w_modulus, W_AbstractLongObject)
 
-        # XXX need to replicate some of the logic, to get the errors right
-        if w_exponent.num.sign < 0:
+        if w_exponent.asbigint().sign < 0:
             raise OperationError(
                 space.w_TypeError,
                 space.wrap(
                     "pow() 2nd argument "
                     "cannot be negative when 3rd argument specified"))
         try:
-            return W_LongObject(self.num.pow(w_exponent.num, w_modulus.num))
+            return W_LongObject(self.num.pow(w_exponent.asbigint(),
+                                             w_modulus.asbigint()))
         except ValueError:
             raise OperationError(space.w_ValueError,
                                  space.wrap("pow 3rd argument cannot be 0"))
     return W_LongObject(bigint)
 
 
-def _delegate_Int2Long(space, w_intobj):
-    """int-to-long delegation"""
-    return W_LongObject.fromint(space, w_intobj.int_w(space))
-
-
 # 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 %(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)
+    #return %(opname)s__Long_Long(space, w_long1, w_long2)
+    return w_long1.descr_%(opname)s(space, w_long2)
 """ % {'opname': opname}, '', 'exec')
 
     getattr(model.MM, opname).register(globals()['%s_ovr__Int_Int' % opname],
         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)
+    #return %(opname)s__Long(space, w_long1)
+    return w_long1.descr_%(opname)s(space)
 """ % {'opname': opname}
 
     getattr(model.MM, opname).register(globals()['%s_ovr__Int' % opname],
         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)
+    #return pow__Long_Long_None(space, w_long1, w_long2, w_none3)
+    return w_long1.descr_pow(space, w_long2, w_none3)
 
 def pow_ovr__Int_Int_Long(space, w_int1, w_int2, w_long3):
     w_long1 = _delegate_Int2Long(space, w_int1)
     w_long2 = _delegate_Int2Long(space, w_int2)
-    return pow__Long_Long_Long(space, w_long1, w_long2, w_long3)
+    #return pow__Long_Long_Long(space, w_long1, w_long2, w_long3)
+    return w_long1.descr_pow(space, w_long2, w_long3)
 
 model.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject,
                       W_NoneObject, order=1)
     try:
         bigint = rbigint.fromstr(s, base)
     except ParseStringError as e:
-        raise operationerrfmt(space.w_ValueError, e.msg)
+        raise OperationError(space.w_ValueError, space.wrap(e.msg))
     return newbigint(space, w_longtype, bigint)
 string_to_w_long._dont_inline_ = True
 
     return w_obj
 
 
-W_LongObject.typedef = StdTypeDef("long",
+W_AbstractLongObject.typedef = StdTypeDef("long",
     __doc__ = """long(x[, base]) -> integer
 
 Convert a string or number to a long integer, if possible.  A floating
 string, use the optional base.  It is an error to supply a base when
 converting a non-string.""",
     __new__ = interp2app(descr__new__),
-    conjugate = interp2app(W_LongObject.descr_conjugate),
+    conjugate = interp2app(W_AbstractLongObject.descr_conjugate),
+                                          # XXX: need indirect for these
     numerator = typedef.GetSetProperty(W_LongObject.descr_get_numerator),
     denominator = typedef.GetSetProperty(W_LongObject.descr_get_denominator),
     real = typedef.GetSetProperty(W_LongObject.descr_get_real),
     imag = typedef.GetSetProperty(W_LongObject.descr_get_imag),
-    bit_length = interp2app(W_LongObject.descr_get_bit_length),
+    bit_length = interp2app(W_AbstractLongObject.descr_bit_length),
 
     # XXX: likely need indirect everything for SmallLong
     __int__ = interpindirect2app(W_AbstractLongObject.int),
-    __long__ = interp2app(W_LongObject.descr_long),
-    __trunc__ = interp2app(W_LongObject.descr_trunc),
-    __index__ = interp2app(W_LongObject.descr_index),
-    __float__ = interp2app(W_LongObject.descr_float),
-    __repr__ = interp2app(W_LongObject.descr_repr),
-    __str__ = interp2app(W_LongObject.descr_str),
-    __format__ = interp2app(W_LongObject.descr_format),
+    __long__ = interpindirect2app(W_AbstractLongObject.descr_long),
+    __index__ = interpindirect2app(W_AbstractLongObject.descr_index),
+    __trunc__ = interpindirect2app(W_AbstractLongObject.descr_trunc),
+    __float__ = interpindirect2app(W_AbstractLongObject.descr_float),
 
-    __hash__ = interp2app(W_LongObject.descr_hash),
-    __coerce__ = interp2app(W_LongObject.descr_coerce),
+    __repr__ = interp2app(W_AbstractLongObject.descr_repr),
+    __str__ = interp2app(W_AbstractLongObject.descr_str),
+    __format__ = interp2app(W_AbstractLongObject.descr_format),
 
-    __lt__ = interp2app(W_LongObject.descr_lt),
-    __le__ = interp2app(W_LongObject.descr_le),
-    __eq__ = interp2app(W_LongObject.descr_eq),
-    __ne__ = interp2app(W_LongObject.descr_ne),
-    __gt__ = interp2app(W_LongObject.descr_gt),
-    __ge__ = interp2app(W_LongObject.descr_ge),
+    __hash__ = interp2app(W_AbstractLongObject.descr_hash),
+    __coerce__ = interp2app(W_AbstractLongObject.descr_coerce),
 
-    __add__ = interp2app(W_LongObject.descr_add),
-    __radd__ = interp2app(W_LongObject.descr_radd),
-    __sub__ = interp2app(W_LongObject.descr_sub),
-    __rsub__ = interp2app(W_LongObject.descr_rsub),
-    __mul__ = interp2app(W_LongObject.descr_mul),
-    __rmul__ = interp2app(W_LongObject.descr_rmul),
+    __lt__ = interpindirect2app(W_AbstractLongObject.descr_lt),
+    __le__ = interpindirect2app(W_AbstractLongObject.descr_le),
+    __eq__ = interpindirect2app(W_AbstractLongObject.descr_eq),
+    __ne__ = interpindirect2app(W_AbstractLongObject.descr_ne),
+    __gt__ = interpindirect2app(W_AbstractLongObject.descr_gt),
+    __ge__ = interpindirect2app(W_AbstractLongObject.descr_ge),
 
-    __and__ = interp2app(W_LongObject.descr_and),
-    __rand__ = interp2app(W_LongObject.descr_rand),
-    __or__ = interp2app(W_LongObject.descr_or),
-    __ror__ = interp2app(W_LongObject.descr_ror),
-    __xor__ = interp2app(W_LongObject.descr_xor),
-    __rxor__ = interp2app(W_LongObject.descr_rxor),
+    __add__ = interpindirect2app(W_AbstractLongObject.descr_add),
+    __radd__ = interpindirect2app(W_AbstractLongObject.descr_radd),
+    __sub__ = interpindirect2app(W_AbstractLongObject.descr_sub),
+    __rsub__ = interpindirect2app(W_AbstractLongObject.descr_rsub),
+    __mul__ = interpindirect2app(W_AbstractLongObject.descr_mul),
+    __rmul__ = interpindirect2app(W_AbstractLongObject.descr_rmul),
 
-    __neg__ = interp2app(W_LongObject.descr_neg),
-    __pos__ = interp2app(W_LongObject.descr_pos),
-    __abs__ = interp2app(W_LongObject.descr_abs),
-    __nonzero__ = interp2app(W_LongObject.descr_nonzero),
-    __invert__ = interp2app(W_LongObject.descr_invert),
-    __oct__ = interp2app(W_LongObject.descr_oct),
-    __hex__ = interp2app(W_LongObject.descr_hex),
+    __and__ = interpindirect2app(W_AbstractLongObject.descr_and),
+    __rand__ = interpindirect2app(W_AbstractLongObject.descr_rand),
+    __or__ = interpindirect2app(W_AbstractLongObject.descr_or),
+    __ror__ = interpindirect2app(W_AbstractLongObject.descr_ror),
+    __xor__ = interpindirect2app(W_AbstractLongObject.descr_xor),
+    __rxor__ = interpindirect2app(W_AbstractLongObject.descr_rxor),
 
-    __lshift__ = interp2app(W_LongObject.descr_lshift),
-    __rshift__ = interp2app(W_LongObject.descr_rshift),
+    __neg__ = interpindirect2app(W_AbstractLongObject.descr_neg),
+    __pos__ = interpindirect2app(W_AbstractLongObject.descr_pos),
+    __abs__ = interpindirect2app(W_AbstractLongObject.descr_abs),
+    __nonzero__ = interpindirect2app(W_AbstractLongObject.descr_nonzero),
+    __invert__ = interpindirect2app(W_AbstractLongObject.descr_invert),
 
-    __truediv__ = interp2app(W_LongObject.descr_truediv),
-    __floordiv__ = interp2app(W_LongObject.descr_floordiv),
-    __div__ = interp2app(W_LongObject.descr_div),
-    __mod__ = interp2app(W_LongObject.descr_mod),
-    __divmod__ = interp2app(W_LongObject.descr_divmod),
+    __oct__ = interp2app(W_AbstractLongObject.descr_oct),
+    __hex__ = interp2app(W_AbstractLongObject.descr_hex),
 
-    __pow__ = interp2app(W_LongObject.descr_pow),
-    __rpow__ = interp2app(W_LongObject.descr_rpow),
+    __lshift__ = interpindirect2app(W_AbstractLongObject.descr_lshift),
+    __rshift__ = interpindirect2app(W_AbstractLongObject.descr_rshift),
 
-    __getnewargs__ = interp2app(W_LongObject.descr_getnewargs),
+    # XXX: all these need r sides
+    __truediv__ = interp2app(W_AbstractLongObject.descr_truediv),
+    __floordiv__ = interpindirect2app(W_AbstractLongObject.descr_floordiv),
+    __div__ = interpindirect2app(W_AbstractLongObject.descr_div),
+    __mod__ = interpindirect2app(W_AbstractLongObject.descr_mod),
+    __divmod__ = interpindirect2app(W_AbstractLongObject.descr_divmod),
+
+    __pow__ = interpindirect2app(W_AbstractLongObject.descr_pow),
+    __rpow__ = interpindirect2app(W_AbstractLongObject.descr_rpow),
+
+    __getnewargs__ = interp2app(W_AbstractLongObject.descr_getnewargs),
 )

pypy/objspace/std/model.py

             ]
         self.typeorder[intobject.W_IntObject] += [
             (floatobject.W_FloatObject, floatobject.delegate_Int2Float),
-            (longobject.W_LongObject,   longobject.delegate_Int2Long),
+#            (longobject.W_LongObject,   longobject.delegate_Int2Long),
             (complexobject.W_ComplexObject, complexobject.delegate_Int2Complex),
             ]
         if False and config.objspace.std.withsmalllong:

pypy/objspace/std/smalllongobject.py

 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.objspace.std.register_all import register_all
+import operator
+
+from rpython.rlib.rarithmetic import LONGLONG_BIT, intmask, r_longlong, r_uint
+from rpython.rlib.rbigint import rbigint
+from rpython.tool.sourcetools import func_with_new_name
+
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import WrappedDefault, unwrap_spec
 from pypy.objspace.std.multimethod import FailedToImplementArgs
-from rpython.rlib.rarithmetic import r_longlong, r_int, r_uint
-from rpython.rlib.rarithmetic import intmask, LONGLONG_BIT
-from rpython.rlib.rbigint import rbigint
 from pypy.objspace.std.longobject import W_AbstractLongObject, W_LongObject
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.interpreter.error import OperationError
+from pypy.objspace.std.intobject import _delegate_Int2Long
 
 LONGLONG_MIN = r_longlong((-1) << (LONGLONG_BIT-1))
 
 
 class W_SmallLongObject(W_AbstractLongObject):
-    from pypy.objspace.std.longtype import long_typedef as typedef
+
     _immutable_fields_ = ['longlong']
 
     def __init__(w_self, value):
         else:
             return self
 
+    def descr_long(self, space):
+        # XXX: do subclasses never apply here?
+        return self
+    descr_index = func_with_new_name(descr_long, 'descr_index')
+    descr_trunc = func_with_new_name(descr_long, 'descr_trunc')
+    descr_pos = func_with_new_name(descr_long, 'descr_pos')
+
+    def descr_index(self, space):
+        return self
+
+    def descr_float(self, space):
+        return space.newfloat(float(self.longlong))
+
+    def _make_descr_cmp(opname):
+        op = getattr(operator, opname)
+        def descr_impl(self, space, w_other):
+            if space.isinstance_w(w_other, space.w_int):
+                result = op(self.longlong, w_other.int_w(space))
+            elif not space.isinstance_w(w_other, space.w_long):
+                return space.w_NotImplemented
+            elif isinstance(w_other, W_SmallLongObject):
+                result = op(self.longlong, w_other.longlong)
+            else:
+                result = getattr(self.asbigint(), opname)(w_other.num)
+            return space.newbool(result)
+        return func_with_new_name(descr_impl, "descr_" + opname)
+
+    descr_lt = _make_descr_cmp('lt')
+    descr_le = _make_descr_cmp('le')
+    descr_eq = _make_descr_cmp('eq')
+    descr_ne = _make_descr_cmp('ne')
+    descr_gt = _make_descr_cmp('gt')
+    descr_ge = _make_descr_cmp('ge')
+
+    def _make_descr_binop(func):
+        # XXX: so if w_other is Long, what do we do? sigh
+        # how to handle delegation with descr_add on longobject?
+        opname = func.__name__[1:]
+        methname = opname + '_' if opname in ('and', 'or') else opname
+
+        def descr_impl(self, space, w_other):
+            if space.isinstance_w(w_other, space.w_int):
+                w_other = delegate_Int2SmallLong(space, w_other)
+            elif not space.isinstance_w(w_other, space.w_long):
+                return space.w_NotImplemented
+            elif not isinstance(w_other, W_SmallLongObject):
+                self = delegate_SmallLong2Long(space, self)
+                return getattr(space, methname)(self, w_other)
+
+            try:
+                return func(self, space, w_other)
+            except OverflowError:
+                self = delegate_SmallLong2Long(space, self)
+                w_other = delegate_SmallLong2Long(space, w_other)
+                return getattr(space, methname)(self, w_other)
+
+        def descr_rimpl(self, space, w_other):
+            if space.isinstance_w(w_other, space.w_int):
+                w_other = delegate_Int2SmallLong(space, w_other)
+            elif not space.isinstance_w(w_other, space.w_long):
+                return space.w_NotImplemented
+            elif not isinstance(w_other, W_SmallLongObject):
+                self = delegate_SmallLong2Long(space, self)
+                return getattr(space, methname)(w_other, self)
+
+            try:
+                return func(w_other, space, self)
+            except OverflowError:
+                self = delegate_SmallLong2Long(space, self)
+                w_other = delegate_SmallLong2Long(space, w_other)
+                return getattr(space, methname)(w_other, self)
+
+        return descr_impl, descr_rimpl
+
+    def _add(self, space, w_other):
+        x = self.longlong
+        y = w_other.longlong
+        z = x + y
+        if ((z^x)&(z^y)) < 0:
+            raise OverflowError
+        return W_SmallLongObject(z)
+    descr_add, descr_radd = _make_descr_binop(_add)
+
+    def _sub(self, space, w_other):
+        x = self.longlong
+        y = w_other.longlong
+        z = x - y
+        if ((z^x)&(z^~y)) < 0:
+            raise OverflowError
+        return W_SmallLongObject(z)
+    descr_sub, descr_rsub = _make_descr_binop(_sub)
+
+    def _mul(self, space, w_other):
+        x = self.longlong
+        y = w_other.longlong
+        z = llong_mul_ovf(x, y)
+        return W_SmallLongObject(z)
+    descr_mul, descr_rmul = _make_descr_binop(_mul)
+
+    def _floordiv(self, space, w_other):
+        x = self.longlong
+        y = w_other.longlong
+        try:
+            if y == -1 and x == LONGLONG_MIN:
+                raise OverflowError
+            z = 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)
+    descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv)
+
+    _div = func_with_new_name(_floordiv, '_div')
+    descr_div, descr_rdiv = _make_descr_binop(_div)
+
+    def _mod(self, space, w_other):
+        x = self.longlong
+        y = w_other.longlong
+        try:
+            if y == -1 and x == LONGLONG_MIN:
+                raise OverflowError
+            z = 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)
+    descr_mod, descr_rmod = _make_descr_binop(_mod)
+
+    def _divmod(self, space, w_other):
+        x = self.longlong
+        y = w_other.longlong
+        try:
+            if y == -1 and x == LONGLONG_MIN:
+                raise OverflowError
+            z = 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)])
+    descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
+
+    # XXX:
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    #def descr_pow__SmallLong_Int_SmallLong(self, space, w_exponent,
+    def descr_pow(self, space, w_exponent, w_modulus=None):
+        if space.isinstance_w(w_exponent, space.w_long):
+            self = delegate_SmallLong2Long(space, self)
+            return space.pow(self, w_exponent, w_modulus)
+        elif not space.isinstance_w(w_exponent, space.w_int):
+            return space.w_NotImplemented
         
-registerimplementation(W_SmallLongObject)
+        # XXX: this expects w_exponent as an int o_O
+        """
+        if space.isinstance_w(w_exponent, space.w_int):
+            w_exponent = delegate_Int2SmallLong(space, w_exponent)
+        elif not space.isinstance_w(w_exponent, space.w_long):
+            return space.w_NotImplemented
+        elif not isinstance(w_exponent, W_SmallLongObject):
+            self = delegate_SmallLong2Long(space, self)
+            return space.pow(self, w_exponent, w_modulus)
+            """
+
+        if space.is_none(w_modulus):
+            #return _impl_pow(space, self.longlong, w_exponent)
+            try:
+                return _impl_pow(space, self.longlong, w_exponent)
+            except ValueError:
+                self = delegate_SmallLong2Float(space, self)
+            except OverflowError:
+                self = delegate_SmallLong2Long(space, self)
+            return space.pow(self, w_exponent, w_modulus)
+        elif space.isinstance_w(w_modulus, space.w_int):
+            w_modulus = delegate_Int2SmallLong(space, w_modulus)
+        elif not space.isinstance_w(w_modulus, space.w_long):
+            return space.w_NotImplemented
+        elif not isinstance(w_modulus, W_SmallLongObject):
+            self = delegate_SmallLong2Long(space, self)
+            #return space.pow(self, w_modulus, w_modulus)
+            return space.pow(self, w_exponent, w_modulus)
+
+        z = w_modulus.longlong
+        if z == 0:
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("pow() 3rd argument cannot be 0"))
+        try:
+            return _impl_pow(space, self.longlong, w_exponent, z)
+        except ValueError:
+            self = delegate_SmallLong2Float(space, self)
+        except OverflowError:
+            self = delegate_SmallLong2Long(space, self)
+        return space.pow(self, w_exponent, w_modulus)
+
+    # XXX:
+    @unwrap_spec(w_modulus=WrappedDefault(None))
+    def descr_rpow(self, space, w_exponent, w_modulus=None):
+        # XXX: blargh
+        if space.isinstance_w(w_exponent, space.w_int):
+            w_exponent = _delegate_Int2Long(space, w_exponent)
+        elif not space.isinstance_w(w_exponent, space.w_long):
+            return space.w_NotImplemented
+        return space.pow(w_exponent, self, w_modulus)
+
+    #def descr_lshift__SmallLong_Int(space, w_small1, w_int2):
+    def descr_lshift(self, space, w_other):
+        if space.isinstance_w(w_other, space.w_long):
+            self = delegate_SmallLong2Long(space, self)
+            w_other = delegate_SmallLong2Long(space, w_other)
+            return space.lshift(self, w_other)
+        elif not space.isinstance_w(w_other, space.w_int):
+            return space.w_NotImplemented
+
+        a = self.longlong
+        b = w_other.intval
+        if r_uint(b) < LONGLONG_BIT: # 0 <= b < LONGLONG_BIT
+            try:
+                c = a << b
+                if a != (c >> b):
+                    raise OverflowError
+            except OverflowError:
+                #raise FailedToImplementArgs(space.w_OverflowError,
+                #                        space.wrap("integer left shift"))
+                self = delegate_SmallLong2Long(space, self)
+                w_other = _delegate_Int2Long(space, w_other)
+                return space.lshift(self, w_other)
+            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 self
+            #raise FailedToImplementArgs(space.w_OverflowError,
+            #                        space.wrap("integer left shift"))
+            self = delegate_SmallLong2Long(space, self)
+            w_other = _delegate_Int2Long(space, w_other)
+            return space.lshift(self, w_other)
+
+    def descr_rshift(self, space, w_other):
+        if space.isinstance_w(w_other, space.w_long):
+            self = delegate_SmallLong2Long(space, self)
+            w_other = delegate_SmallLong2Long(space, w_other)
+            return space.rshift(self, w_other)
+        elif not space.isinstance_w(w_other, space.w_int):
+            return space.w_NotImplemented
+
+        a = self.longlong
+        b = w_other.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 self
+                if a < 0:
+                    a = -1
+                else:
+                    a = 0
+        else:
+            a = a >> b
+        return W_SmallLongObject(a)
+
+    def _and(self, space, w_other):
+        a = self.longlong
+        b = w_other.longlong
+        res = a & b
+        return W_SmallLongObject(res)
+    descr_and, descr_rand = _make_descr_binop(_and)
+
+    def _xor(self, space, w_other):
+        a = self.longlong
+        b = w_other.longlong
+        res = a ^ b
+        return W_SmallLongObject(res)
+    descr_xor, descr_rxor = _make_descr_binop(_xor)
+
+    def _or(self, space, w_other):
+        a = self.longlong
+        b = w_other.longlong
+        res = a | b
+        return W_SmallLongObject(res)
+    descr_or, descr_ror = _make_descr_binop(_or)
+
+    def descr_neg(self, space):
+        a = self.longlong
+        try:
+            if a == LONGLONG_MIN:
+                raise OverflowError
+            x = -a
+        except OverflowError:
+            return space.neg(delegate_SmallLong2Long(self))
+            #raise FailedToImplementArgs(space.w_OverflowError,
+            #                        space.wrap("integer negation"))
+        return W_SmallLongObject(x)
+    #get_negint = neg__SmallLong
+
+    #def descr_pos(self, space):
+    #    return self
+
+    def descr_abs(self, space):
+        if self.longlong >= 0:
+            return self
+        else:
+            #return get_negint(space, self)
+            return self.descr_neg(space)
+
+    def descr_nonzero(self, space):
+        return space.newbool(bool(self.longlong))
+
+    def descr_invert(self, space):
+        x = self.longlong
+        a = ~x
+        return W_SmallLongObject(a)
+
 
 # ____________________________________________________________
 
     return W_SmallLongObject(r_longlong(space.is_true(w_bool)))
 
 def delegate_Int2SmallLong(space, w_int):
-    return W_SmallLongObject(r_longlong(w_int.intval))
+    #return W_SmallLongObject(r_longlong(w_int.intval))
+    return W_SmallLongObject(r_longlong(w_int.int_w(space)))
 
 def delegate_SmallLong2Long(space, w_small):
     return W_LongObject(w_small.asbigint())
 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 index__SmallLong(space, w_value):
-    return w_value
-
-def float__SmallLong(space, w_value):
-    return space.newfloat(float(w_value.longlong))
-
-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 = x + y
-        if ((z^x)&(z^y)) < 0:
-            raise OverflowError
-    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 = x - y
-        if ((z^x)&(z^~y)) < 0:
-            raise OverflowError
-    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 = llong_mul_ovf(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:
-        if y == -1 and x == LONGLONG_MIN:
-            raise OverflowError
-        z = 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:
-        if y == -1 and x == LONGLONG_MIN:
-            raise OverflowError
-        z = 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:
-        if y == -1 and x == LONGLONG_MIN:
-            raise OverflowError
-        z = 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)])
             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"))
+        raise ValueError
     temp = iv
     ix = r_longlong(1)
     try:
         if iz:
             ix = ix % iz
     except OverflowError:
-        raise FailedToImplementArgs(space.w_OverflowError,
-                                space.wrap("integer exponentiation"))
+        # XXX:
+        raise OverflowError
     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)
         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:
-        if a == LONGLONG_MIN:
-            raise OverflowError
-        x = -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 = a << b
-            if a != (c >> b):
-                raise OverflowError
-        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:
         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())