[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