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