-typedef struct PSI_LibffiCall {
- void *code;
- ffi_closure *closure;
- ffi_cif signature;
- void *params[1]; /* [type1, type2, NULL, arg1, arg2] ... */
-} PSI_LibffiCall;
-
-static inline PSI_LibffiCall *PSI_LibffiCallAlloc(PSI_Context *C, decl *decl) {
- int rc;
- size_t i, c = decl->args ? decl->args->count : 0;
- PSI_LibffiCall *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *));
-
- for (i = 0; i < c; ++i) {
- call->params[i] = psi_ffi_decl_arg_type(decl->args->args[i]);
- }
- call->params[c] = NULL;
-
- decl->call.info = call;
- decl->call.rval = &decl->func->ptr;
- decl->call.argc = c;
- decl->call.args = (void **) &call->params[c+1];
-
- rc = ffi_prep_cif(&call->signature, psi_ffi_abi(decl->abi->convention),
- c, psi_ffi_decl_arg_type(decl->func), (ffi_type **) call->params);
- ZEND_ASSERT(FFI_OK == rc);
-
- return call;
-}
-
-static inline void PSI_LibffiCallInitClosure(PSI_Context *C, PSI_LibffiCall *call, impl *impl) {
- PSI_LibffiContext *context = C->context;
- int rc;
-
- call->closure = psi_ffi_closure_alloc(sizeof(ffi_closure), &call->code);
- ZEND_ASSERT(call->closure != NULL);
-
-#if PSI_HAVE_FFI_PREP_CLOSURE_LOC
- rc = ffi_prep_closure_loc(
- call->closure,
- &context->signature,
- psi_ffi_handler,
- impl,
- call->code);
-
-#elif PSI_HAVE_FFI_PREP_CLOSURE
- rc = ffi_prep_closure(call->code, &context->signature, psi_ffi_handler, impl);
-#else
-# error "Neither ffi_prep_closure() nor ffi_prep_closure_loc() available"
-#endif
- ZEND_ASSERT(FFI_OK == rc);
-}
-
-static inline void PSI_LibffiCallFree(PSI_LibffiCall *call) {
- if (call->closure) {
- psi_ffi_closure_free(call->closure);
- }
- free(call);
-}
-
-static inline PSI_LibffiContext *PSI_LibffiContextInit(PSI_LibffiContext *L) {