-#ifdef PSI_HAVE_FFI_PREP_CIF_VAR
- rc = ffi_prep_cif_var(&signature, call->signature.abi,
- nfixedargs, ntotalargs,
- call->signature.rtype, (ffi_type **) params);
-#else
- /* FIXME: test in config.m4; assume we can just call anyway */
- rc = ffi_prep_cif(&signature, call->signature.abi, ntotalargs,
- call->signature.rtype, (ffi_type **) params);
-#endif
- ZEND_ASSERT(FFI_OK == rc);
- ffi_call(&signature, FFI_FN(decl_call->sym), decl_call->rval, ¶ms[ntotalargs + 1]);
- free(params);
- } else {
- ffi_call(&call->signature, FFI_FN(decl_call->sym), decl_call->rval, decl_call->args);
+ pefree(info, 1);
+ let_exp->data.callback->info = NULL;
+ }
+}
+
+static void psi_ffi_call(struct psi_call_frame *frame) {
+ struct psi_decl *decl = psi_call_frame_get_decl(frame);
+ struct psi_impl *impl = psi_call_frame_get_impl(frame);
+ struct psi_ffi_decl_info *decl_info = decl->info;
+ struct psi_ffi_impl_info *impl_info;
+ struct psi_call_frame *prev;
+
+ if (impl) {
+ impl_info = impl->info;
+ prev = impl_info->frame;
+ impl_info->frame = frame;
+ }
+ ffi_call(&decl_info->signature, FFI_FN(decl->sym),
+ psi_call_frame_get_rpointer(frame),
+ psi_call_frame_get_arg_pointers(frame));
+ if (impl) {
+ impl_info->frame = prev;
+ }
+}
+
+static void psi_ffi_call_va(struct psi_call_frame *frame) {
+ ffi_cif signature;
+ struct psi_call_frame *prev;
+ struct psi_decl *decl = psi_call_frame_get_decl(frame);
+ struct psi_impl *impl = psi_call_frame_get_impl(frame);
+ struct psi_ffi_decl_info *decl_info = decl->info;
+ struct psi_ffi_impl_info *impl_info;
+ size_t i, va_count, argc;
+ ffi_type **param_types;
+
+ argc = psi_plist_count(decl->args);
+ va_count = psi_call_frame_num_var_args(frame);
+ param_types = ecalloc(argc + va_count + 1, sizeof(ffi_type *));
+ memcpy(param_types, decl_info->params, argc * sizeof(ffi_type *));
+ for (i = 0; i < va_count; ++i) {
+ struct psi_call_frame_argument *frame_arg;
+
+ frame_arg = psi_call_frame_get_var_argument(frame, i);
+ param_types[argc + i] = psi_ffi_impl_type(frame_arg->va_type);
+ }
+
+ psi_ffi_prep_va(&decl_info->signature, &signature, argc, va_count, param_types);
+
+ if (impl) {
+ impl_info = impl->info;
+ prev = impl_info->frame;
+ impl_info->frame = frame;
+ }
+ ffi_call(&signature, FFI_FN(decl->sym),
+ psi_call_frame_get_rpointer(frame),
+ psi_call_frame_get_arg_pointers(frame));
+ if (impl) {
+ impl_info->frame = prev;
+ }
+
+ efree(param_types);
+}
+
+static void *psi_ffi_typeof_impl(struct psi_context *C, token_t impl_type)
+{
+ return psi_ffi_impl_type(impl_type);
+}
+
+static void *psi_ffi_typeof_decl(struct psi_context *C, token_t decl_type)
+{
+ return psi_ffi_token_type(decl_type);
+}
+
+static void *psi_ffi_copyof_type(struct psi_context *C, void *orig_type)
+{
+ ffi_type *type = pemalloc(sizeof(*type), 1);
+
+ *type = *(ffi_type *) orig_type;
+ return type;
+}
+
+static void psi_ffi_layoutof_type(struct psi_context *C, void *orig_type,
+ struct psi_layout *l)
+{
+ ffi_type *type = orig_type;
+
+ if (!type->size || !type->alignment) {
+ ffi_cif tmp;
+ ffi_prep_cif(&tmp, FFI_DEFAULT_ABI, 0, type, NULL);