PageRenderTime 4ms CodeModel.GetById 1ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

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