+ struct psi_jit_call *call = data;
+
+ psi_context_call(call->context, *(zend_execute_data **)args[0], *(zval **) args[1], call->impl.fn.impl);
+}
+
+static void psi_jit_callback(jit_type_t sig, void *result, void **args,
+ void *data)
+{
+ struct psi_jit_call *call = data, *impl_call = call->impl.cb.impl_call;
+ struct psi_call_frame_callback cbdata;
+
+ cbdata.cb = call->impl.cb.let_exp;
+ cbdata.argc = jit_type_num_params(sig);
+ cbdata.argv = args;
+ cbdata.rval = result;
+
+ psi_call_frame_do_callback(impl_call->impl.fn.frame, &cbdata);
+}
+
+static inline struct psi_jit_call *psi_jit_call_alloc(struct psi_context *C,
+ struct psi_decl *decl)
+{
+ size_t i, c = psi_plist_count(decl->args);
+ struct psi_jit_call *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *));
+ struct psi_decl_arg *arg;
+
+ decl->info = call;
+ call->context = C;
+ for (i = 0; psi_plist_get(decl->args, i, &arg); ++i) {
+ call->params[i] = psi_jit_decl_arg_type(arg);
+ }
+ call->params[c] = NULL;
+
+ call->signature = jit_type_create_signature(
+ psi_jit_abi(decl->abi->convention),
+ psi_jit_decl_arg_type(decl->func),
+ (jit_type_t *) call->params,
+ c, 1);
+ assert(call->signature);
+
+ return call;
+}
+
+static inline void *psi_jit_call_init_closure(struct psi_context *C,
+ struct psi_jit_call *call, struct psi_impl *impl)
+{
+ struct psi_jit_context *context = C->context;
+
+ call->impl.fn.impl = impl;
+ return call->closure = jit_closure_create(context->jit, context->signature,
+ &psi_jit_handler, call);
+}
+
+static inline void *psi_jit_call_init_callback_closure(struct psi_context *C,
+ struct psi_jit_call *call, struct psi_jit_call *impl_call,
+ struct psi_let_exp *cb)
+{
+ struct psi_jit_context *context = C->context;
+
+ call->impl.cb.let_exp = cb;
+ call->impl.cb.impl_call = impl_call;
+
+ return call->closure = jit_closure_create(context->jit, call->signature,
+ &psi_jit_callback, call);
+}
+
+static inline void psi_jit_call_free(struct psi_jit_call *call)
+{
+ jit_type_free(call->signature);
+ free(call);
+}
+
+static inline struct psi_jit_context *psi_jit_context_init(
+ struct psi_jit_context *L)
+{
+ jit_type_t params[] = {jit_type_void_ptr, jit_type_void_ptr};
+
+ if (!L) {
+ L = malloc(sizeof(*L));
+ }
+ memset(L, 0, sizeof(*L));
+
+ L->jit = jit_context_create();
+ L->signature = jit_type_create_signature(jit_abi_cdecl, jit_type_void,
+ params, 2, 1);
+
+ return L;
+}