Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r57804:628675137bde
Date: 2012-10-06 12:44 +0200
http://bitbucket.org/pypy/pypy/changeset/628675137bde/

Log:    More removal of long longs.

diff --git a/pypy/module/_cffi_backend/ccallback.py 
b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -133,8 +133,7 @@
             # manual inlining and tweaking of
             # W_CTypePrimitiveSigned.convert_from_object() in order
             # to write a whole 'ffi_arg'.
-            value = misc.as_long_long(space, w_res)
-            value = r_ulonglong(value)
+            value = misc.as_long(space, w_res)
             misc.write_raw_integer_data(ll_res, value, SIZE_OF_FFI_ARG)
             return
         else:
diff --git a/pypy/module/_cffi_backend/cdataobj.py 
b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -4,7 +4,7 @@
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
 from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.objectmodel import keepalive_until_here
+from pypy.rlib.objectmodel import keepalive_until_here, specialize
 from pypy.rlib import objectmodel, rgc
 from pypy.tool.sourcetools import func_with_new_name
 
@@ -190,6 +190,7 @@
     def iter(self):
         return self.ctype.iter(self)
 
+    @specialize.argtype(1)
     def write_raw_integer_data(self, source):
         misc.write_raw_integer_data(self._cdata, source, self.ctype.size)
         keepalive_until_here(self)
diff --git a/pypy/module/_cffi_backend/ctypeprim.py 
b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -4,7 +4,7 @@
 
 from pypy.interpreter.error import operationerrfmt
 from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.rarithmetic import r_ulonglong
+from pypy.rlib.rarithmetic import r_uint, r_ulonglong, intmask
 from pypy.rlib.objectmodel import keepalive_until_here
 from pypy.rlib import jit
 
@@ -164,9 +164,10 @@
         W_CTypePrimitive.__init__(self, *args)
         self.value_fits_long = self.size <= rffi.sizeof(lltype.Signed)
         if self.size < rffi.sizeof(lltype.SignedLongLong):
+            assert self.value_fits_long
             sh = self.size * 8
-            self.vmin = r_ulonglong(-1) << (sh - 1)
-            self.vrangemax = (r_ulonglong(1) << sh) - 1
+            self.vmin = r_uint(-1) << (sh - 1)
+            self.vrangemax = (r_uint(1) << sh) - 1
 
     def int(self, cdata):
         # enums: really call convert_to_object() just below,
@@ -182,12 +183,15 @@
             return self.space.wrap(value)    # r_longlong => on 32-bit, 'long'
 
     def convert_from_object(self, cdata, w_ob):
-        value = misc.as_long_long(self.space, w_ob)
-        if self.size < rffi.sizeof(lltype.SignedLongLong):
-            if r_ulonglong(value) - self.vmin > self.vrangemax:
-                self._overflow(w_ob)
-        value = r_ulonglong(value)
-        misc.write_raw_integer_data(cdata, value, self.size)
+        if self.value_fits_long:
+            value = misc.as_long(self.space, w_ob)
+            if self.size < rffi.sizeof(lltype.Signed):
+                if r_uint(value) - self.vmin > self.vrangemax:
+                    self._overflow(w_ob)
+            misc.write_raw_integer_data(cdata, value, self.size)
+        else:
+            value = misc.as_long_long(self.space, w_ob)
+            misc.write_raw_integer_data(cdata, value, self.size)
 
     def get_vararg_type(self):
         if self.size < rffi.sizeof(rffi.INT):
@@ -197,34 +201,42 @@
 
 
 class W_CTypePrimitiveUnsigned(W_CTypePrimitive):
-    _attrs_            = ['value_fits_long', 'vrangemax']
-    _immutable_fields_ = ['value_fits_long', 'vrangemax']
+    _attrs_            = ['value_fits_long', 'value_fits_ulong', 'vrangemax']
+    _immutable_fields_ = ['value_fits_long', 'value_fits_ulong', 'vrangemax']
     is_primitive_integer = True
 
     def __init__(self, *args):
         W_CTypePrimitive.__init__(self, *args)
         self.value_fits_long = self.size < rffi.sizeof(lltype.Signed)
-        if self.size < rffi.sizeof(lltype.SignedLongLong):
+        self.value_fits_ulong = self.size <= rffi.sizeof(lltype.Unsigned)
+        if self.value_fits_long:
             self.vrangemax = self._compute_vrange_max()
 
     def _compute_vrange_max(self):
         sh = self.size * 8
-        return (r_ulonglong(1) << sh) - 1
+        return (r_uint(1) << sh) - 1
 
     def int(self, cdata):
         return self.convert_to_object(cdata)
 
     def convert_from_object(self, cdata, w_ob):
-        value = misc.as_unsigned_long_long(self.space, w_ob, strict=True)
-        if self.size < rffi.sizeof(lltype.SignedLongLong):
-            if value > self.vrangemax:
-                self._overflow(w_ob)
-        misc.write_raw_integer_data(cdata, value, self.size)
+        if self.value_fits_ulong:
+            value = misc.as_unsigned_long(self.space, w_ob, strict=True)
+            if self.value_fits_long:
+                if value > self.vrangemax:
+                    self._overflow(w_ob)
+            misc.write_raw_integer_data(cdata, value, self.size)
+        else:
+            value = misc.as_unsigned_long_long(self.space, w_ob, strict=True)
+            misc.write_raw_integer_data(cdata, value, self.size)
 
     def convert_to_object(self, cdata):
-        if self.value_fits_long:
-            value = misc.read_raw_uint_data(cdata, self.size)
-            return self.space.wrap(value)
+        if self.value_fits_ulong:
+            value = misc.read_raw_ulong_data(cdata, self.size)
+            if self.value_fits_long:
+                return self.space.wrap(intmask(value))
+            else:
+                return self.space.wrap(value)    # r_uint => 'long' object
         else:
             value = misc.read_raw_unsigned_data(cdata, self.size)
             return self.space.wrap(value)    # r_ulonglong => 'long' object
@@ -240,7 +252,7 @@
     _attrs_ = []
 
     def _compute_vrange_max(self):
-        return r_ulonglong(1)
+        return r_uint(1)
 
     def _cast_result(self, intvalue):
         return r_ulonglong(intvalue != 0)
diff --git a/pypy/module/_cffi_backend/ctypeptr.py 
b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -53,7 +53,7 @@
                 isinstance(ob.ctype, W_CTypePtrOrArray)):
             value = ob._cdata
         else:
-            value = misc.as_unsigned_long_nonstrict(space, w_ob)
+            value = misc.as_unsigned_long(space, w_ob, strict=False)
             value = rffi.cast(rffi.CCHARP, value)
         return cdataobj.W_CData(space, value, self)
 
diff --git a/pypy/module/_cffi_backend/ctypestruct.py 
b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -3,7 +3,7 @@
 """
 
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.rpython.lltypesystem import rffi
+from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.rlib.objectmodel import keepalive_until_here
@@ -212,21 +212,26 @@
         #
         if isinstance(ctype, ctypeprim.W_CTypePrimitiveUnsigned):
             value_fits_long = ctype.value_fits_long
+            value_fits_ulong = ctype.value_fits_ulong
         elif isinstance(ctype, ctypeprim.W_CTypePrimitiveCharOrUniChar):
             value_fits_long = True
+            value_fits_ulong = True
         else:
             raise NotImplementedError
         #
-        if value_fits_long:
-            value = r_uint(misc.read_raw_uint_data(cdata, ctype.size))
+        if value_fits_ulong:
+            value = misc.read_raw_ulong_data(cdata, ctype.size)
             valuemask = (r_uint(1) << self.bitsize) - 1
             value = (value >> self.bitshift) & valuemask
-            return space.wrap(intmask(value))
+            if value_fits_long:
+                return space.wrap(intmask(value))
+            else:
+                return space.wrap(value)    # uint => wrapped long object
         else:
             value = misc.read_raw_unsigned_data(cdata, ctype.size)
             valuemask = (r_ulonglong(1) << self.bitsize) - 1
             value = (value >> self.bitshift) & valuemask
-            return space.wrap(value)
+            return space.wrap(value)      # ulonglong => wrapped long object
 
     def convert_bitfield_from_object(self, cdata, w_ob):
         ctype = self.ctype
diff --git a/pypy/module/_cffi_backend/misc.py 
b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -3,7 +3,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rlib.rarithmetic import r_uint, r_ulonglong
 from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.objectmodel import keepalive_until_here
+from pypy.rlib.objectmodel import keepalive_until_here, specialize
 from pypy.rlib import jit
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
@@ -46,12 +46,11 @@
             return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0])
     raise NotImplementedError("bad integer size")
 
-def read_raw_uint_data(target, size):
-    # only for types smaller than Unsigned
+def read_raw_ulong_data(target, size):
     for TP, TPP in _prim_unsigned_types:
         if size == rffi.sizeof(TP):
-            assert rffi.sizeof(TP) < rffi.sizeof(lltype.Unsigned)
-            return rffi.cast(lltype.Signed, rffi.cast(TPP,target)[0])
+            assert rffi.sizeof(TP) <= rffi.sizeof(lltype.Unsigned)
+            return rffi.cast(lltype.Unsigned, rffi.cast(TPP,target)[0])
     raise NotImplementedError("bad integer size")
 
 def read_raw_float_data(target, size):
@@ -63,6 +62,7 @@
 def read_raw_longdouble_data(target):
     return rffi.cast(rffi.LONGDOUBLEP, target)[0]
 
[email protected](1)
 def write_raw_integer_data(target, source, size):
     for TP, TPP in _prim_unsigned_types:
         if size == rffi.sizeof(TP):
@@ -151,6 +151,23 @@
     except OverflowError:
         raise OperationError(space.w_OverflowError, space.wrap(ovf_msg))
 
+def as_long(space, w_ob):
+    # Same as as_long_long(), but returning an int instead.
+    if space.is_w(space.type(w_ob), space.w_int):   # shortcut
+        return space.int_w(w_ob)
+    try:
+        bigint = space.bigint_w(w_ob)
+    except OperationError, e:
+        if not e.match(space, space.w_TypeError):
+            raise
+        if _is_a_float(space, w_ob):
+            raise
+        bigint = space.bigint_w(space.int(w_ob))
+    try:
+        return bigint.toint()
+    except OverflowError:
+        raise OperationError(space.w_OverflowError, space.wrap(ovf_msg))
+
 def as_unsigned_long_long(space, w_ob, strict):
     # (possibly) convert and cast a Python object to an unsigned long long.
     # This accepts a Python int too, and does convertions from other types of
@@ -179,22 +196,33 @@
     else:
         return bigint.ulonglongmask()
 
-neg_msg = "can't convert negative number to unsigned"
-ovf_msg = "long too big to convert"
-
-def as_unsigned_long_nonstrict(space, w_ob):
-    # optimized version of as_unsigned_long_long(strict=False) if we're
-    # only interested in an Unsigned value
+def as_unsigned_long(space, w_ob, strict):
+    # same as as_unsigned_long_long(), but returning just an Unsigned
     if space.is_w(space.type(w_ob), space.w_int):   # shortcut
         value = space.int_w(w_ob)
+        if strict and value < 0:
+            raise OperationError(space.w_OverflowError, space.wrap(neg_msg))
         return r_uint(value)
     try:
         bigint = space.bigint_w(w_ob)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
+        if strict and _is_a_float(space, w_ob):
+            raise
         bigint = space.bigint_w(space.int(w_ob))
-    return bigint.uintmask()
+    if strict:
+        try:
+            return bigint.touint()
+        except ValueError:
+            raise OperationError(space.w_OverflowError, space.wrap(neg_msg))
+        except OverflowError:
+            raise OperationError(space.w_OverflowError, space.wrap(ovf_msg))
+    else:
+        return bigint.uintmask()
+
+neg_msg = "can't convert negative number to unsigned"
+ovf_msg = "long too big to convert"
 
 # ____________________________________________________________
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to