-}
-
-static void psi_ffi_closure_free(void *c)
-{
-#ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
- ffi_closure_free(c);
-#elif HAVE_MMAP
- munmap(c, sizeof(ffi_closure));
-#endif
-}
-
-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)
-{
- unsigned argc = _sig->nargs;
- void **argv = _args;
- ffi_arg *res = _result;
- let_stmt *let;
- decl_arg *darg = let->var->arg;
- decl *decl_cb = darg->type->func;
- let_callback *cb = let->val->data.callback;
- impl_arg *iarg = cb->func->arg;
- size_t i, argc = cb->args->count;
- zval return_value, *argv = calloc(argc, sizeof(*argv));
-
- // prepare args for the userland call
- for (i = 0; i < decl_cb->args->count; ++i) {
-
- }
- for (i = 0; i < cb->args->count; ++i) {
- psi_do_set(&argv[i], cb->args->vals[i]);
- }
- zend_fcall_info_argp(iarg->val.zend.cb->fci, argc, argv);
- zend_fcall_info_call(&iarg->val.zend.cb->fci, &iarg->val.zend.cb->fcc,
- &return_value, NULL);
- // marshal return value of the userland call
- switch (cb->func->type) {
- case PSI_T_BOOLVAL:
- break;
- case PSI_T_INTVAL:
- break;
- case PSI_T_FLOATVAL:
- break;
- case PSI_T_PATHVAL:
- case PSI_T_STRVAL:
- break;
- case PSI_T_STRLEN:
- break;
- case PSI_T_ARRVAL:
- break;
- case PSI_T_OBJVAL:
- break;
- case PSI_T_CALLBACK:
- break;
- EMPTY_SWITCH_DEFAULT_CASE();
- }
- darg->ptr = psi_let_val(cb->func->type, iarg, darg->ptr, real_decl_type(darg->type)->strct, &darg->mem);
-}
-
-static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg);
-
-typedef struct PSI_LibffiContext {