Author: Antonio Cuni <anto.c...@gmail.com> Branch: ffistruct Changeset: r47179:4003bd45c5ff Date: 2011-09-09 11:46 +0200 http://bitbucket.org/pypy/pypy/changeset/4003bd45c5ff/
Log: refactor the interface for struct_{get,set}field. Now we pass the ffitype at runtime, and the values are handled as lltype.Signed. struct_{get,set}field take care of doing cast of the correct LLTYPE diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py --- a/pypy/rlib/clibffi.py +++ b/pypy/rlib/clibffi.py @@ -231,6 +231,9 @@ lltype.Bool : _unsigned_type_for(lltype.Bool), } +ffitype_map = unrolling_iterable(TYPE_MAP.iteritems()) + + def external(name, args, result, **kwds): return rffi.llexternal(name, args, result, compilation_info=eci, **kwds) diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py --- a/pypy/rlib/libffi.py +++ b/pypy/rlib/libffi.py @@ -414,9 +414,33 @@ # ====================================================================== +def struct_getfield_int(ffitype, addr, offset): + """ + Return the field of type ``ffitype`` at ``addr+offset``, widened to + lltype.Signed. + """ + for TYPE, ffitype2 in clibffi.ffitype_map: + if ffitype is ffitype2: + value = _struct_getfield(TYPE, addr, offset) + return rffi.cast(lltype.Signed, value) + assert False, "cannot find the given ffitype" + +def struct_setfield_int(ffitype, addr, offset, value): + """ + Set the field of type ``ffitype`` at ``addr+offset``. ``value`` is of + type lltype.Signed, and it's automatically converted to the right type. + """ + for TYPE, ffitype2 in clibffi.ffitype_map: + if ffitype is ffitype2: + value = rffi.cast(TYPE, value) + _struct_setfield(TYPE, addr, offset, value) + return + assert False, "cannot find the given ffitype" + + @jit.dont_look_inside @specialize.arg(0) -def struct_getfield(TYPE, addr, offset): +def _struct_getfield(TYPE, addr, offset): """ Read the field of type TYPE at addr+offset. addr is of type rffi.VOIDP, offset is an int. @@ -428,9 +452,9 @@ @jit.dont_look_inside @specialize.arg(0) -def struct_setfield(TYPE, addr, offset, value): +def _struct_setfield(TYPE, addr, offset, value): """ - Read the field of type TYPE at addr+offset. + Write the field of type TYPE at addr+offset. addr is of type rffi.VOIDP, offset is an int. """ addr = rffi.ptradd(addr, offset) diff --git a/pypy/rlib/test/test_libffi.py b/pypy/rlib/test/test_libffi.py --- a/pypy/rlib/test/test_libffi.py +++ b/pypy/rlib/test/test_libffi.py @@ -5,7 +5,7 @@ from pypy.rlib.rarithmetic import r_singlefloat, r_longlong, r_ulonglong from pypy.rlib.test.test_clibffi import BaseFfiTest, get_libm_name, make_struct_ffitype_e from pypy.rlib.libffi import CDLL, Func, get_libc_name, ArgChain, types -from pypy.rlib.libffi import IS_32_BIT, struct_getfield, struct_setfield +from pypy.rlib.libffi import IS_32_BIT, struct_getfield_int, struct_setfield_int class TestLibffiMisc(BaseFfiTest): @@ -54,18 +54,22 @@ def test_struct_fields(self): longsize = 4 if IS_32_BIT else 8 - POINT = lltype.Struct('POINT', ('x', rffi.LONG), ('y', rffi.LONG)) + POINT = lltype.Struct('POINT', + ('x', rffi.LONG), + ('y', rffi.SHORT) + ) + y_ofs = longsize p = lltype.malloc(POINT, flavor='raw') p.x = 42 - p.y = 43 + p.y = rffi.cast(rffi.SHORT, -1) addr = rffi.cast(rffi.VOIDP, p) - assert struct_getfield(rffi.LONG, addr, 0) == 42 - assert struct_getfield(rffi.LONG, addr, longsize) == 43 + assert struct_getfield_int(types.slong, addr, 0) == 42 + assert struct_getfield_int(types.sshort, addr, y_ofs) == -1 # - struct_setfield(rffi.LONG, addr, 0, 123) - struct_setfield(rffi.LONG, addr, longsize, 321) - assert p.x == 123 - assert p.y == 321 + struct_setfield_int(types.slong, addr, 0, 43) + struct_setfield_int(types.sshort, addr, y_ofs, 0x1234FFFE) # 0x1234 is masked out + assert p.x == 43 + assert p.y == -2 # lltype.free(p, flavor='raw') _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit