24 #if defined DISABLE_FFI || defined HOST_DOS || (!defined HOST_X86 && !defined HOST_X86_64)
35 #define FB_THREADCALL_MAX_ELEMS 1024
37 typedef struct _FBTHREADCALL
42 ffi_type **ffi_arg_types;
64 static void freeStruct( ffi_type *arg )
67 ffi_type **elem = arg->elements;
69 while( *elem !=
NULL )
72 if ( i >= FB_THREADCALL_MAX_ELEMS )
76 if( (*elem)->type == FFI_TYPE_STRUCT )
83 free( arg->elements );
87 static ffi_type *getArgument( va_list *args_list );
89 static ffi_type *getStruct( va_list *args_list )
91 int num_elems = va_arg( (*args_list),
int );
95 ffi_type *ffi_arg = (ffi_type *)malloc(
sizeof( ffi_type ) );
97 ffi_arg->alignment = 0;
98 ffi_arg->type = FFI_TYPE_STRUCT;
100 (ffi_type **)malloc(
sizeof( ffi_type * ) * ( num_elems + 1 ) );
101 ffi_arg->elements[num_elems] =
NULL;
104 for( i=0; i<num_elems; i++ )
106 ffi_arg->elements[i] = getArgument( args_list );
107 if( ffi_arg->elements[i] ==
NULL )
112 if( ffi_arg->elements[j]->type == FFI_TYPE_STRUCT )
113 freeStruct( ffi_arg );
115 free( ffi_arg->elements );
124 static ffi_type *getArgument( va_list *args_list )
126 int arg_type = va_arg( (*args_list),
int );
156 ffi_args = (ffi_type **)malloc(
sizeof( ffi_type * ) * num_args );
157 values = (
void **)malloc(
sizeof(
void * ) * num_args );
159 va_start(args_list, num_args);
162 for( i=0; i<num_args; i++ )
164 ffi_args[i] = getArgument( &args_list );
165 if( ffi_args[i] ==
NULL )
170 if( ffi_args[i]->type == FFI_TYPE_STRUCT )
171 freeStruct( ffi_args[i] );
175 values[i] = va_arg( args_list,
void * );
180 param = malloc(
sizeof( FBTHREADCALL ) );
183 param->num_args = num_args;
184 param->ffi_arg_types = ffi_args;
185 param->values = values;
193 FBTHREADCALL *info = ( FBTHREADCALL * )param;
194 ffi_status status = FFI_OK;
200 abi = FFI_DEFAULT_ABI;
213 if( status == FFI_OK )
215 status = ffi_prep_cif(
224 if( status == FFI_OK )
225 ffi_call( &cif, FFI_FN( info->proc ),
NULL, info->values );
229 for( i=0; i<info->num_args; i++ )
231 if( info->ffi_arg_types[i]->type == FFI_TYPE_STRUCT )
232 freeStruct( info->ffi_arg_types[i] );
234 free( info->values );
235 free( info->ffi_arg_types );