[pypy-commit] pypy ffistruct: use FromAppLevelConverter to handle the conversion for setfields
antocuni
noreply at buildbot.pypy.org
Thu Jan 12 14:28:34 CET 2012
Author: Antonio Cuni <anto.cuni at 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)
More information about the pypy-commit
mailing list