[pypy-svn] r78585 - in pypy/branch/smalllong/pypy: config objspace/std objspace/std/test

arigo at codespeak.net arigo at codespeak.net
Sun Oct 31 11:30:02 CET 2010


Author: arigo
Date: Sun Oct 31 11:30:00 2010
New Revision: 78585

Added:
   pypy/branch/smalllong/pypy/objspace/std/smalllongobject.py
   pypy/branch/smalllong/pypy/objspace/std/test/test_smalllongobject.py
Modified:
   pypy/branch/smalllong/pypy/config/pypyoption.py
   pypy/branch/smalllong/pypy/objspace/std/longobject.py
   pypy/branch/smalllong/pypy/objspace/std/longtype.py
   pypy/branch/smalllong/pypy/objspace/std/objspace.py
   pypy/branch/smalllong/pypy/objspace/std/strutil.py
Log:
In-progress.


Modified: pypy/branch/smalllong/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/smalllong/pypy/config/pypyoption.py	(original)
+++ pypy/branch/smalllong/pypy/config/pypyoption.py	Sun Oct 31 11:30:00 2010
@@ -194,6 +194,9 @@
         IntOption("prebuiltintto", "highest integer which is prebuilt",
                   default=100, cmdline="--prebuiltintto"),
 
+        BoolOption("withsmalllong", "use a version of 'long' in a C long long",
+                   default=False),
+
         BoolOption("withstrjoin", "use strings optimized for addition",
                    default=False),
 

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	Sun Oct 31 11:30:00 2010
@@ -60,6 +60,12 @@
 
 registerimplementation(W_LongObject)
 
+def newbigint(space, w_longtype, bigint):
+    w_obj = space.allocate_instance(W_LongObject, w_longtype)
+    W_LongObject.__init__(w_obj, bigint)
+    return w_obj
+
+
 # bool-to-long
 def delegate_Bool2Long(space, w_bool):
     return W_LongObject(rbigint.frombool(space.is_true(w_bool)))

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	Sun Oct 31 11:30:00 2010
@@ -4,45 +4,48 @@
 from pypy.objspace.std.strutil import string_to_bigint, ParseStringError
 
 def descr__new__(space, w_longtype, w_x=0, w_base=gateway.NoneNotWrapped):
-    from pypy.objspace.std.longobject import W_LongObject
+    from pypy.objspace.std.longobject import W_LongObject, newbigint
+    from pypy.rlib.rbigint import rbigint
+    if space.config.objspace.std.withsmalllong:
+        from pypy.objspace.std.smalllongobject import W_SmallLongObject
+    else:
+        W_SmallLongObject = None
     w_value = w_x     # 'x' is the keyword argument name in CPython
     if w_base is None:
         # check for easy cases
-        if type(w_value) is W_LongObject:
-            bigint = w_value.num
+        if (W_SmallLongObject and type(w_value) is W_SmallLongObject
+            and space.is_w(w_longtype, space.w_long)):
+            return w_value
+        elif type(w_value) is W_LongObject:
+            return newbigint(space, w_longtype, w_value.num)
         elif space.is_true(space.isinstance(w_value, space.w_str)):
-            try:
-                bigint = string_to_bigint(space.str_w(w_value))
-            except ParseStringError, e:
-                raise OperationError(space.w_ValueError,
-                                     space.wrap(e.msg))
+            return string_to_w_long(space, w_longtype, space.str_w(w_value))
         elif space.is_true(space.isinstance(w_value, space.w_unicode)):
-            try:
-                if space.config.objspace.std.withropeunicode:
-                    from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
-                else:
-                    from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
-                bigint = string_to_bigint(unicode_to_decimal_w(space, w_value))
-            except ParseStringError, e:
-                raise OperationError(space.w_ValueError,
-                                     space.wrap(e.msg))
+            if space.config.objspace.std.withropeunicode:
+                from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w
+            else:
+                from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
+            return string_to_w_long(space, w_longtype,
+                                    unicode_to_decimal_w(space, w_value))
         else:
             # otherwise, use the __long__() method
             w_obj = space.long(w_value)
             # 'long(x)' should return whatever x.__long__() returned
             if space.is_w(w_longtype, space.w_long):
                 return w_obj
-            if space.is_true(space.isinstance(w_obj, space.w_long)):
-                assert isinstance(w_obj, W_LongObject)  # XXX this could fail!
-                # XXX find a way to do that even if w_obj is not a W_LongObject
+            # 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()
+            elif isinstance(w_obj, W_LongObject):
                 bigint = w_obj.num
             elif space.is_true(space.isinstance(w_obj, space.w_int)):
                 from pypy.rlib.rbigint import rbigint
-                intval = space.int_w(w_obj)
-                bigint = rbigint.fromint(intval)
+                bigint = rbigint.fromint(space.int_w(w_obj))
             else:
                 raise OperationError(space.w_ValueError,
-                                    space.wrap("value can't be converted to long"))
+                                space.wrap("value can't be converted to long"))
+            return newbigint(space, w_longtype, bigint)
+    #
     else:
         base = space.int_w(w_base)
 
@@ -56,15 +59,25 @@
                 raise OperationError(space.w_TypeError,
                                      space.wrap("long() can't convert non-string "
                                                 "with explicit base"))
+        return string_to_w_long(space, w_longtype, s, base)
+
+
+def string_to_w_long(space, w_longtype, s, base=10):
+    try:
+        bigint = string_to_bigint(s, base)
+    except ParseStringError, e:
+        raise OperationError(space.w_ValueError,
+                             space.wrap(e.msg))
+    if (space.config.objspace.std.withsmalllong
+        and space.is_w(w_longtype, space.w_long)):
         try:
-            bigint = string_to_bigint(s, base)
-        except ParseStringError, e:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap(e.msg))
-
-    w_obj = space.allocate_instance(W_LongObject, w_longtype)
-    W_LongObject.__init__(w_obj, bigint)
-    return w_obj
+            longlong = bigint.tolonglong()
+        except OverflowError:
+            pass
+        else:
+            from pypy.objspace.std.smalllongobject import W_SmallLongObject
+            return W_SmallLongObject(longlong)
+    return newbigint(space, w_longtype, bigint)
 
 # ____________________________________________________________
 

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	Sun Oct 31 11:30:00 2010
@@ -176,6 +176,7 @@
             #print 'wrapping', x, '->', w_result
             return w_result
         if isinstance(x, base_int):
+            xxxxxxxxx
             return W_LongObject.fromrarith_int(x)
 
         # _____ below here is where the annotator should not get _____
@@ -198,6 +199,16 @@
         # The following cases are even stranger.
         # Really really only for tests.
         if type(x) is long:
+            if self.config.objspace.std.withsmalllong:
+                from pypy.rlib.rarithmetic import r_longlong
+                try:
+                    rx = r_longlong(x)
+                except OverflowError:
+                    pass
+                else:
+                    from pypy.objspace.std.smalllongobject import \
+                                                   W_SmallLongObject
+                    return W_SmallLongObject(rx)
             return W_LongObject.fromlong(x)
         if isinstance(x, slice):
             return W_SliceObject(self.wrap(x.start),
@@ -261,6 +272,9 @@
         return W_ComplexObject(realval, imagval)
 
     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_LongObject.fromint(self, val)
 
     def newtuple(self, list_w):

Added: pypy/branch/smalllong/pypy/objspace/std/smalllongobject.py
==============================================================================
--- (empty file)
+++ pypy/branch/smalllong/pypy/objspace/std/smalllongobject.py	Sun Oct 31 11:30:00 2010
@@ -0,0 +1,19 @@
+"""
+Implementation of 'small' longs, stored as a C 'long long' value.
+Useful for 32-bit applications manipulating 64-bit values.
+"""
+from pypy.objspace.std.model import registerimplementation, W_Object
+from pypy.rlib.rarithmetic import r_longlong
+
+
+class W_SmallLongObject(W_Object):
+    from pypy.objspace.std.longtype import long_typedef as typedef
+
+    def __init__(w_self, value):
+        assert isinstance(value, r_longlong)
+        w_self._longlong = value
+
+    def as_bigint(w_self):
+        xxx
+
+registerimplementation(W_SmallLongObject)

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	Sun Oct 31 11:30:00 2010
@@ -3,7 +3,7 @@
 """
 
 from pypy.rlib.rarithmetic import ovfcheck, break_up_float, parts_to_float,\
-     INFINITY, NAN
+     INFINITY, NAN, r_longlong
 from pypy.rlib.rbigint import rbigint, parse_digit_string
 from pypy.interpreter.error import OperationError
 import math

Added: pypy/branch/smalllong/pypy/objspace/std/test/test_smalllongobject.py
==============================================================================
--- (empty file)
+++ pypy/branch/smalllong/pypy/objspace/std/test/test_smalllongobject.py	Sun Oct 31 11:30:00 2010
@@ -0,0 +1,12 @@
+from pypy.objspace.std.test import test_longobject
+from pypy.conftest import gettestobjspace
+
+
+class AppTestSmallLong(test_longobject.AppTestLong):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withsmalllong": True})
+
+    def test_sl_simple(self):
+        import __pypy__
+        s = __pypy__.internal_repr(5L)
+        assert 'SmallLong' in s



More information about the Pypy-commit mailing list