-static void psi_ffi_handler(ffi_cif *_sig, void *_result, void **_args, void *_data)
-{
- psi_call(*(zend_execute_data **)_args[0], *(zval **)_args[1], _data);
-}
-
-static void psi_ffi_callback(ffi_cif *_sig, void *_result, void **_args, void *_data)
-{
- psi_callback(_data, _result, _sig->nargs, _args);
-}
-
-static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg);
-
-struct psi_ffi_context {
- ffi_cif signature;
- ffi_type *params[2];
-};
-
-struct psi_ffi_call {
- void *code;
- ffi_closure *closure;
- ffi_cif signature;
- void *params[1]; /* [type1, type2, NULL, arg1, arg2] ... */
-};
-
-static inline ffi_abi psi_ffi_abi(const char *convention) {
- return FFI_DEFAULT_ABI;
-}
-
-static inline struct psi_ffi_call *psi_ffi_call_alloc(struct psi_context *C, decl *decl) {
- int rc;
- size_t i, c = decl->args ? decl->args->count : 0;
- struct psi_ffi_call *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 ffi_status psi_ffi_call_init_closure(struct psi_context *C, struct psi_ffi_call *call, impl *impl) {
- struct psi_ffi_context *context = C->context;