/src/wrappers/ffi/library/ffi_call.e

http://github.com/tybor/Liberty · Specman e · 132 lines · 56 code · 10 blank · 66 comment · 2 complexity · f96d1dc1a797e2a7d1fc1fe199718082 MD5 · raw file

  1. class FFI_CALL
  2. -- A Foreign Function Interface call.
  3. -- Libffi' assumes that you have a pointer to the function you wish to
  4. -- call and that you know the number and types of arguments to pass it, as
  5. -- well as the return type of the function.
  6. -- The first thing you must do is create an ffi_cif object that matches
  7. -- the signature of the function you wish to call. This is a separate step
  8. -- because it is common to make multiple calls using a single ffi_cif. The
  9. -- cif in ffi_cif stands for Call InterFace. To prepare a call interface
  10. -- object, use the function ffi_prep_cif.
  11. inherit
  12. C_STRUCT
  13. EIFFEL_OWNED
  14. insert
  15. FFI_TYPES
  16. FFI_CIF_STRUCT
  17. FFI_EXTERNALS
  18. FFI_MORE_EXTERNALS -- this is hand-written, those other inserts are generated
  19. create {ANY}
  20. prepare
  21. feature {ANY} -- Preparation of a call
  22. prepare (a_function: POINTER; a_return_type: POINTER; some_argument_types: ARRAYED_COLLECTION[POINTER])
  23. -- Initializes Current call according to the given parameters.
  24. -- Functions with variable number of arguments (also known as varargs) are not supported.
  25. -- `a_return_type' must be a pointer to an ffi_type structure that describes the return type of the function. See FFI_TYPES.
  26. -- `some_argument_types' contains the types of arguments. May be Void
  27. -- FFI allows to use several different ABI conventions, but they are highly
  28. -- platform-dependent. TODO: support different ABIs.
  29. -- `status' is updated and will be either is_ok if everything worked
  30. -- properly; is_bad__abi if the ABI is invalid (see above); its value may
  31. -- be "FFI_BAD_TYPEDEF" if one of the arguments is incorrect; TODO: this
  32. -- value should belong to FFI_STATUSENUM but currently it is not found in
  33. -- the code.
  34. require
  35. a_function.is_not_null
  36. a_return_type.is_not_null
  37. some_argument_types /= Void implies not some_argument_types.is_empty
  38. -- TODO: reactivate the following preconditions when they will not make the compiler produce wrong code anymore. Paolo 2010-03-19
  39. -- is_valid_type(a_return_type)
  40. -- some_argument_types=Void or else
  41. -- some_argument_types.for_all(agent is_valid_type)
  42. local
  43. args: POINTER; count: NATURAL_32
  44. do
  45. handle := malloc(struct_size) -- Also allocate works
  46. function := a_function
  47. argument_types := some_argument_types
  48. if argument_types /= Void then
  49. args := argument_types.to_external
  50. count := argument_types.count.to_natural_32
  51. else
  52. check
  53. args.is_null
  54. count = 0.to_natural_32
  55. end
  56. end
  57. status.change_value(ffi_prep_cif(handle, default_abi, count, a_return_type, args))
  58. check
  59. not status.is_bad_abi
  60. end
  61. ensure
  62. function_set: function = a_function
  63. -- Note: someone may want to turn this into invariant Actually they
  64. -- are right, it is an invariant. But since we do not offer a feature
  65. -- to change function value we only need to check that this creation
  66. -- feature correctly set it.
  67. end
  68. invoke (a_result: POINTER; some_values: ARRAYED_COLLECTION[POINTER])
  69. -- Calls `function' according to the description of Current.
  70. -- `a_result' shall point to a chunk of memory that will hold the
  71. -- result of the function call. This must be large enough to hold the
  72. -- result and must be suitably aligned; it is the caller's
  73. -- responsibility to ensure this. If Current declares that the function
  74. -- returns void (using ffi_type_void), then `a_result' is ignored. If
  75. -- `a_result' is NULL then the return value is discarded.
  76. -- `some_values' shall point to a vector of "void *" pointers that
  77. -- point to the memory locations holding the argument values for a
  78. -- call. If Current declares that the function has no arguments (i.e.,
  79. -- nargs was 0), then avalues is ignored.
  80. -- TODO: reactivate the following preconditions when they will not make the compiler produce wrong code anymore. Paolo 2010-03-19
  81. -- require
  82. -- parameterless_shall_be_called_without_parameters: some_values=Void implies argument_types=Void
  83. -- correct_number_of_paramenters: some_values/=Void implies argument_types.count = some_values.count
  84. local
  85. h, f, r, v: POINTER
  86. do
  87. h := handle
  88. f := function
  89. r := a_result
  90. if some_values /= Void then
  91. v := some_values.to_external
  92. end
  93. ffi_call(h, f, r, v)
  94. end
  95. feature {ANY} -- Status
  96. status: FFI_STATUS_ENUM
  97. -- The status of Current call.
  98. function: POINTER
  99. -- The address of the function that will be called
  100. argument_types: ARRAYED_COLLECTION[POINTER]
  101. -- Pointers to the structures describing the function that will be called
  102. end -- class FFI_CALL
  103. -- Liberty Eiffel FFI wrappers - Copyright (C) 2012-2017: Cyril Adrian, Paolo Redaelli
  104. --
  105. -- Permission is hereby granted, free of charge, to any person obtaining
  106. -- a copy of this software and associated documentation files (the
  107. -- ``Software''), to deal in the Software without restriction, including
  108. -- without limitation the rights to use, copy, modify, merge, publish,
  109. -- distribute, sublicense, and/or sell copies of the Software, and to
  110. -- permit persons to whom the Software is furnished to do so, subject to
  111. -- the following conditions:
  112. --
  113. -- The above copyright notice and this permission notice shall be included
  114. -- in all copies or substantial portions of the Software.
  115. --
  116. -- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
  117. -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  118. -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  119. -- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  120. -- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  121. -- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  122. -- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.