[pypy-commit] pypy virtual-raw-mallocs: some refactoring to make sure that we always cast integer types to the correct signed/unsigned type when writing to cdata. It is hard to test because it does not have any visible result: the only change is that in the JIT trace the SETARRAYITEM_RAW will have the correct signed/unsigned descr, and it will allow the raw_malloc virtuals to work
antocuni
noreply at buildbot.pypy.org
Fri Dec 21 12:44:41 CET 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: virtual-raw-mallocs
Changeset: r59530:3e914132432e
Date: 2012-12-21 12:44 +0100
http://bitbucket.org/pypy/pypy/changeset/3e914132432e/
Log: some refactoring to make sure that we always cast integer types to
the correct signed/unsigned type when writing to cdata. It is hard
to test because it does not have any visible result: the only change
is that in the JIT trace the SETARRAYITEM_RAW will have the correct
signed/unsigned descr, and it will allow the raw_malloc virtuals to
work
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
@@ -134,7 +134,7 @@
# W_CTypePrimitiveSigned.convert_from_object() in order
# to write a whole 'ffi_arg'.
value = misc.as_long(space, w_res)
- misc.write_raw_integer_data(ll_res, value, SIZE_OF_FFI_ARG)
+ misc.write_raw_signed_data(ll_res, value, SIZE_OF_FFI_ARG)
return
else:
# zero extension: fill the '*result' with zeros, and (on big-
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
@@ -191,8 +191,13 @@
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)
+ def write_raw_signed_data(self, source):
+ misc.write_raw_signed_data(self._cdata, source, self.ctype.size)
+ keepalive_until_here(self)
+
+ @specialize.argtype(1)
+ def write_raw_unsigned_data(self, source):
+ misc.write_raw_unsigned_data(self._cdata, source, self.ctype.size)
keepalive_until_here(self)
def write_raw_float_data(self, source):
diff --git a/pypy/module/_cffi_backend/ctypeenum.py b/pypy/module/_cffi_backend/ctypeenum.py
--- a/pypy/module/_cffi_backend/ctypeenum.py
+++ b/pypy/module/_cffi_backend/ctypeenum.py
@@ -70,7 +70,7 @@
if space.isinstance_w(w_ob, space.w_str):
value = self.convert_enum_string_to_int(space.str_w(w_ob))
value = r_ulonglong(value)
- misc.write_raw_integer_data(cdata, value, self.size)
+ misc.write_raw_signed_data(cdata, value, self.size)
else:
raise self._convert_error("str or int", w_ob)
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
@@ -63,7 +63,7 @@
else:
value = self._cast_generic(w_ob)
w_cdata = cdataobj.W_CDataMem(space, self.size, self)
- w_cdata.write_raw_integer_data(value)
+ self.write_raw_integer_data(w_cdata, value)
return w_cdata
def _cast_result(self, intvalue):
@@ -94,6 +94,9 @@
from pypy.module._cffi_backend import newtype
return newtype.new_primitive_type(self.space, "int")
+ def write_raw_integer_data(self, w_cdata, value):
+ w_cdata.write_raw_unsigned_data(value)
+
class W_CTypePrimitiveChar(W_CTypePrimitiveCharOrUniChar):
_attrs_ = []
@@ -189,10 +192,10 @@
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)
+ misc.write_raw_signed_data(cdata, value, self.size)
else:
value = misc.as_long_long(self.space, w_ob)
- misc.write_raw_integer_data(cdata, value, self.size)
+ misc.write_raw_signed_data(cdata, value, self.size)
def get_vararg_type(self):
if self.size < rffi.sizeof(rffi.INT):
@@ -200,6 +203,9 @@
return newtype.new_primitive_type(self.space, "int")
return self
+ def write_raw_integer_data(self, w_cdata, value):
+ w_cdata.write_raw_signed_data(value)
+
class W_CTypePrimitiveUnsigned(W_CTypePrimitive):
_attrs_ = ['value_fits_long', 'value_fits_ulong', 'vrangemax']
@@ -226,10 +232,10 @@
if self.value_fits_long:
if value > self.vrangemax:
self._overflow(w_ob)
- misc.write_raw_integer_data(cdata, value, self.size)
+ misc.write_raw_unsigned_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)
+ misc.write_raw_unsigned_data(cdata, value, self.size)
def convert_to_object(self, cdata):
if self.value_fits_ulong:
@@ -248,6 +254,9 @@
return newtype.new_primitive_type(self.space, "int")
return self
+ def write_raw_integer_data(self, w_cdata, value):
+ w_cdata.write_raw_unsigned_data(value)
+
class W_CTypePrimitiveBool(W_CTypePrimitiveUnsigned):
_attrs_ = []
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
@@ -241,11 +241,13 @@
#
value = misc.as_long_long(space, w_ob)
if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned):
+ is_signed = True
fmin = -(r_longlong(1) << (self.bitsize-1))
fmax = (r_longlong(1) << (self.bitsize-1)) - 1
if fmax == 0:
fmax = 1 # special case to let "int x:1" receive "1"
else:
+ is_signed = False
fmin = r_longlong(0)
fmax = r_longlong((r_ulonglong(1) << self.bitsize) - 1)
if value < fmin or value > fmax:
@@ -257,7 +259,10 @@
rawvalue = r_ulonglong(value) << self.bitshift
rawfielddata = misc.read_raw_unsigned_data(cdata, ctype.size)
rawfielddata = (rawfielddata & ~rawmask) | (rawvalue & rawmask)
- misc.write_raw_integer_data(cdata, rawfielddata, ctype.size)
+ if is_signed:
+ misc.write_raw_signed_data(cdata, rawfielddata, ctype.size)
+ else:
+ misc.write_raw_unsigned_data(cdata, rawfielddata, ctype.size)
W_CField.typedef = TypeDef(
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
@@ -63,13 +63,22 @@
return rffi.cast(rffi.LONGDOUBLEP, target)[0]
@specialize.argtype(1)
-def write_raw_integer_data(target, source, size):
+def write_raw_unsigned_data(target, source, size):
for TP, TPP in _prim_unsigned_types:
if size == rffi.sizeof(TP):
rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
return
raise NotImplementedError("bad integer size")
+ at specialize.argtype(1)
+def write_raw_signed_data(target, source, size):
+ for TP, TPP in _prim_signed_types:
+ if size == rffi.sizeof(TP):
+ rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+ return
+ raise NotImplementedError("bad integer size")
+
+
def write_raw_float_data(target, source, size):
for TP, TPP in _prim_float_types:
if size == rffi.sizeof(TP):
More information about the pypy-commit
mailing list