Author: Antonio Cuni <anto.c...@gmail.com>
Branch: ffistruct
Changeset: r51275:9a7a19bfc660
Date: 2012-01-12 14:10 +0100
http://bitbucket.org/pypy/pypy/changeset/9a7a19bfc660/

Log:    use FromAppLevelConverter to handle the conversion for setfields

diff --git a/pypy/module/_ffi/interp_struct.py 
b/pypy/module/_ffi/interp_struct.py
--- a/pypy/module/_ffi/interp_struct.py
+++ b/pypy/module/_ffi/interp_struct.py
@@ -3,7 +3,7 @@
 from pypy.rlib import libffi
 from pypy.rlib import jit
 from pypy.rlib.rgc import must_be_light_finalizer
-from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_singlefloat
+from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_singlefloat, intmask
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.interpreter.gateway import interp2app, unwrap_spec
@@ -135,38 +135,14 @@
     @unwrap_spec(name=str)
     def getfield(self, space, name):
         w_ffitype, offset = 
self.structdescr.get_type_and_offset_for_field(name)
-        converter = GetFieldConverter(space, self.rawmem, offset)
-        return converter.do_and_wrap(w_ffitype)
+        field_getter = GetFieldConverter(space, self.rawmem, offset)
+        return field_getter.do_and_wrap(w_ffitype)
 
     @unwrap_spec(name=str)
     def setfield(self, space, name, w_value):
         w_ffitype, offset = 
self.structdescr.get_type_and_offset_for_field(name)
-        if w_ffitype.is_longlong():
-            value = space.truncatedlonglong_w(w_value)
-            libffi.struct_setfield_longlong(w_ffitype.ffitype, self.rawmem, 
offset, value)
-            return
-        #
-        if w_ffitype.is_signed() or w_ffitype.is_unsigned() or 
w_ffitype.is_pointer():
-            value = space.truncatedint_w(w_value)
-            libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, offset, 
value)
-            return
-        #
-        if w_ffitype.is_char() or w_ffitype.is_unichar():
-            value = space.int_w(space.ord(w_value))
-            libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, offset, 
value)
-            return
-        #
-        if w_ffitype.is_double():
-            value = space.float_w(w_value)
-            libffi.struct_setfield_float(w_ffitype.ffitype, self.rawmem, 
offset, value)
-            return
-        #
-        if w_ffitype.is_singlefloat():
-            value = r_singlefloat(space.float_w(w_value))
-            libffi.struct_setfield_singlefloat(w_ffitype.ffitype, self.rawmem, 
offset, value)
-            return
-        #
-        raise operationerrfmt(space.w_TypeError, 'Unknown type: %s', 
w_ffitype.name)
+        field_setter = SetFieldConverter(space, self.rawmem, offset)
+        field_setter.unwrap_and_do(w_ffitype, w_value)
 
 
 class GetFieldConverter(ToAppLevelConverter):
@@ -213,7 +189,6 @@
         return libffi.struct_getfield_singlefloat(w_ffitype.ffitype, 
self.rawmem,
                                                   self.offset)
 
-
     ## def get_struct(self, w_datashape):
     ##     ...
 
@@ -221,6 +196,51 @@
     ##     ...
 
 
+class SetFieldConverter(FromAppLevelConverter):
+    """
+    A converter used by W__StructInstance to convert an app-level object to
+    the corresponding low-level value and set the field of a structure.
+    """
+
+    def __init__(self, space, rawmem, offset):
+        self.space = space
+        self.rawmem = rawmem
+        self.offset = offset
+
+    def handle_signed(self, w_ffitype, w_obj, intval):
+        libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, self.offset,
+                                   intval)
+
+    def handle_unsigned(self, w_ffitype, w_obj, uintval):
+        libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, self.offset,
+                                   intmask(uintval))
+
+    handle_pointer = handle_signed
+    handle_char = handle_signed
+    handle_unichar = handle_signed
+
+    def handle_longlong(self, w_ffitype, w_obj, longlongval):
+        libffi.struct_setfield_longlong(w_ffitype.ffitype, self.rawmem, 
self.offset,
+                                        longlongval)
+
+    def handle_float(self, w_ffitype, w_obj, floatval):
+        libffi.struct_setfield_float(w_ffitype.ffitype, self.rawmem, 
self.offset,
+                                     floatval)
+
+    def handle_singlefloat(self, w_ffitype, w_obj, singlefloatval):
+        libffi.struct_setfield_singlefloat(w_ffitype.ffitype, self.rawmem, 
self.offset,
+                                           singlefloatval)
+
+    ## def handle_struct(self, w_ffitype, w_structinstance):
+    ##     ...
+
+    ## def handle_char_p(self, w_ffitype, w_obj, strval):
+    ##     ...
+
+    ## def handle_unichar_p(self, w_ffitype, w_obj, unicodeval):
+    ##     ...
+
+
 
 
 W__StructInstance.typedef = TypeDef(
diff --git a/pypy/module/_ffi/type_converter.py 
b/pypy/module/_ffi/type_converter.py
--- a/pypy/module/_ffi/type_converter.py
+++ b/pypy/module/_ffi/type_converter.py
@@ -33,7 +33,7 @@
             pass
         elif w_ffitype.is_pointer():
             w_obj = self.convert_pointer_arg_maybe(w_obj, w_ffitype)
-            intval = intmask(space.uint_w(w_obj))
+            intval = space.truncatedint_w(w_obj)
             self.handle_pointer(w_ffitype, w_obj, intval)
         elif w_ffitype.is_unsigned():
             uintval = r_uint(space.truncatedint_w(w_obj))
@@ -58,7 +58,7 @@
     def _longlong(self, w_ffitype, w_obj):
         # a separate function, which can be seen by the jit or not,
         # depending on whether longlongs are supported
-        bigval = self.space.bigint_w(w_obj)
+        bigval = self.space.bigint_w(w_obj) # XXX, use truncatedlonglong?
         ullval = bigval.ulonglongmask()
         llval = rffi.cast(rffi.LONGLONG, ullval)
         self.handle_longlong(w_ffitype, w_obj, llval)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to