[pypy-svn] r69764 - pypy/trunk/pypy/objspace/std

cfbolz at codespeak.net cfbolz at codespeak.net
Mon Nov 30 14:28:56 CET 2009


Author: cfbolz
Date: Mon Nov 30 14:28:55 2009
New Revision: 69764

Modified:
   pypy/trunk/pypy/objspace/std/intobject.py
   pypy/trunk/pypy/objspace/std/smallintobject.py
Log:
Vacation playing around: Clean up small integers a tiny bit:
 - kill outdated comments
 - share comparison code with intobject.py
 - get rid of a number of overflow checks. Many overflows cannot occur, because
   the .intvalue of a W_SmallIntObject fits into 31/63 bits, so the result of
   e.g. an addition will always fit into 32/64 bits.


Modified: pypy/trunk/pypy/objspace/std/intobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/intobject.py	(original)
+++ pypy/trunk/pypy/objspace/std/intobject.py	Mon Nov 30 14:28:55 2009
@@ -53,7 +53,8 @@
 
 str__Int = repr__Int
 
-def declare_new_int_comparison(opname):
+def declare_new_int_comparison(opname, clsname):
+    # also used by smallintobject.py
     import operator
     from pypy.tool.sourcetools import func_with_new_name
     op = getattr(operator, opname)
@@ -61,11 +62,11 @@
         i = w_int1.intval
         j = w_int2.intval
         return space.newbool(op(i, j))
-    name = opname + "__Int_Int"
+    name = "%s__%s_%s" % (opname, clsname, clsname)
     return func_with_new_name(f, name), name
 
 for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']:
-    func, name = declare_new_int_comparison(op)
+    func, name = declare_new_int_comparison(op, "Int")
     globals()[name] = func
 
 def hash__Int(space, w_int1):

Modified: pypy/trunk/pypy/objspace/std/smallintobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/smallintobject.py	(original)
+++ pypy/trunk/pypy/objspace/std/smallintobject.py	Mon Nov 30 14:28:55 2009
@@ -6,7 +6,7 @@
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint
 from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.intobject import W_IntObject, declare_new_int_comparison
 from pypy.rlib.objectmodel import UnboxedValue
 
 # XXX this is a complete copy of intobject.py.  Find a better but still
@@ -37,14 +37,6 @@
     return space.newcomplex(float(w_small.intval), 0.0)
 
 
-"""
-XXX not implemented:
-free list
-FromString
-FromUnicode
-print
-"""
-
 def int_w__SmallInt(space, w_int1):
     return int(w_int1.intval)
 
@@ -63,20 +55,8 @@
 
 str__SmallInt = repr__SmallInt
 
-
-def declare_new_int_comparison(opname):
-    import operator
-    from pypy.tool.sourcetools import func_with_new_name
-    op = getattr(operator, opname)
-    def f(space, w_int1, w_int2):
-        i = w_int1.intval
-        j = w_int2.intval
-        return space.newbool(op(i, j))
-    name = opname + "__SmallInt_SmallInt"
-    return func_with_new_name(f, name), name
-
 for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']:
-    func, name = declare_new_int_comparison(op)
+    func, name = declare_new_int_comparison(op, "SmallInt")
     globals()[name] = func
 
 def hash__SmallInt(space, w_int1):
@@ -93,22 +73,17 @@
 def add__SmallInt_SmallInt(space, w_int1, w_int2):
     x = w_int1.intval
     y = w_int2.intval
-    try:
-        z = ovfcheck(x + y)
-    except OverflowError:
-        raise FailedToImplement(space.w_OverflowError,
-                                space.wrap("integer addition"))
-    return wrapint(space, z)
+    # note that no overflow checking is necessary here: x and y fit into 31
+    # bits (or 63 bits respectively), so their sum fits into 32 (or 64) bits.
+    # wrapint then makes sure that either a tagged int or a normal int is
+    # created
+    return wrapint(space, x + y)
 
 def sub__SmallInt_SmallInt(space, w_int1, w_int2):
     x = w_int1.intval
     y = w_int2.intval
-    try:
-        z = ovfcheck(x - y)
-    except OverflowError:
-        raise FailedToImplement(space.w_OverflowError,
-                                space.wrap("integer substraction"))
-    return wrapint(space, z)
+    # see comment in add__SmallInt_SmallInt
+    return wrapint(space, x - y)
 
 def mul__SmallInt_SmallInt(space, w_int1, w_int2):
     x = w_int1.intval
@@ -123,15 +98,11 @@
 def div__SmallInt_SmallInt(space, w_int1, w_int2):
     x = w_int1.intval
     y = w_int2.intval
-    try:
-        z = ovfcheck(x // y)
-    except ZeroDivisionError:
+    if y == 0:
         raise OperationError(space.w_ZeroDivisionError,
                              space.wrap("integer division by zero"))
-    except OverflowError:
-        raise FailedToImplement(space.w_OverflowError,
-                                space.wrap("integer division"))
-    return wrapint(space, z)
+    # no overflow possible
+    return wrapint(space, x // y)
 
 floordiv__SmallInt_SmallInt = div__SmallInt_SmallInt
 
@@ -145,28 +116,20 @@
 def mod__SmallInt_SmallInt(space, w_int1, w_int2):
     x = w_int1.intval
     y = w_int2.intval
-    try:
-        z = ovfcheck(x % y)
-    except ZeroDivisionError:
+    if y == 0:
         raise OperationError(space.w_ZeroDivisionError,
                              space.wrap("integer modulo by zero"))
-    except OverflowError:
-        raise FailedToImplement(space.w_OverflowError,
-                                space.wrap("integer modulo"))
-    return wrapint(space, z)
+    # no overflow possible
+    return wrapint(space, x % y)
 
 def divmod__SmallInt_SmallInt(space, w_int1, w_int2):
     x = w_int1.intval
     y = w_int2.intval
-    try:
-        z = ovfcheck(x // y)
-    except ZeroDivisionError:
+    if y == 0:
         raise OperationError(space.w_ZeroDivisionError,
                              space.wrap("integer divmod by zero"))
-    except OverflowError:
-        raise FailedToImplement(space.w_OverflowError,
-                                space.wrap("integer modulo"))
     # no overflow possible
+    z = x // y
     m = x % y
     return space.newtuple([space.wrap(z), space.wrap(m)])
 
@@ -188,12 +151,8 @@
 
 def neg__SmallInt(space, w_int1):
     a = w_int1.intval
-    try:
-        x = ovfcheck(-a)
-    except OverflowError:
-        raise FailedToImplement(space.w_OverflowError,
-                                space.wrap("integer negation"))
-    return wrapint(space, x)
+    # no overflow possible since a fits into 31/63 bits
+    return wrapint(space, -a)
 
 
 def abs__SmallInt(space, w_int1):
@@ -221,20 +180,8 @@
     if b >= LONG_BIT:
         raise FailedToImplement(space.w_OverflowError,
                                 space.wrap("integer left shift"))
-    ##
-    ## XXX please! have a look into pyport.h and see how to implement
-    ## the overflow checking, using macro Py_ARITHMETIC_RIGHT_SHIFT
-    ## we *assume* that the overflow checking is done correctly
-    ## in the code generator, which is not trivial!
-    
-    ## XXX also note that Python 2.3 returns a long and never raises
-    ##     OverflowError.
     try:
         c = ovfcheck_lshift(a, b)
-        ## the test in C code is
-        ## if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
-        ##     if (PyErr_Warn(PyExc_FutureWarning,
-        # and so on
     except OverflowError:
         raise FailedToImplement(space.w_OverflowError,
                                 space.wrap("integer left shift"))
@@ -254,8 +201,6 @@
         else:
             a = 0
     else:
-        ## please look into pyport.h, how >> should be implemented!
-        ## a = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
         a = a >> b
     return wrapint(space, a)
 
@@ -277,19 +222,6 @@
     res = a | b
     return wrapint(space, res)
 
-# coerce is not wanted
-##
-##static int
-##coerce__Int(PyObject **pv, PyObject **pw)
-##{
-##    if (PyInt_Check(*pw)) {
-##        Py_INCREF(*pv);
-##        Py_INCREF(*pw);
-##        return 0;
-##    }
-##    return 1; /* Can't do it */
-##}
-
 # int__SmallInt is supposed to do nothing, unless it has
 # a derived integer object, where it should return
 # an exact one.
@@ -297,17 +229,9 @@
     if space.is_w(space.type(w_int1), space.w_int):
         return w_int1
     a = w_int1.intval
-    return wrapint(space, a)
+    return W_SmallIntObject(a)
 pos__SmallInt = int__SmallInt
 
-"""
-# Not registered
-def long__SmallInt(space, w_int1):
-    a = w_int1.intval
-    x = long(a)  ## XXX should this really be done so?
-    return space.newlong(x)
-"""
-
 def float__SmallInt(space, w_int1):
     a = w_int1.intval
     x = float(a)



More information about the Pypy-commit mailing list