+ call->impl.fn.frame = frame;
+ jit_apply(call->signature, decl->sym, args, psi_plist_count(decl->args), rval);
+ call->impl.fn.frame = prev;
+}
+
+static void psi_jit_call_va(struct psi_context *C, struct psi_call_frame *frame,
+ struct psi_decl *decl, void *rval, void **args, size_t va_count,
+ void **va_types)
+{
+ struct psi_jit_call *info = decl->info;
+ struct psi_call_frame *prev = info->impl.fn.frame;
+ size_t argc = psi_plist_count(decl->args);
+ jit_type_t signature;
+ jit_type_t *param_types = ecalloc(argc + va_count + 1, sizeof(jit_type_t));
+
+ memcpy(param_types, info->params, argc * sizeof(jit_type_t));
+ memcpy(param_types + argc, va_types, va_count * sizeof(jit_type_t));
+
+ signature = jit_type_create_signature(jit_abi_vararg,
+ jit_type_get_return(info->signature), param_types, argc + va_count,
+ 1);
+ assert(signature);
+
+ info->impl.fn.frame = frame;
+ jit_apply(signature, decl->sym, args, argc, rval);
+ info->impl.fn.frame = prev;
+ jit_type_free(signature);
+ efree(param_types);
+}
+
+static void *psi_jit_query(struct psi_context *C, enum psi_context_query q,
+ void *arg)
+{
+ switch (q) {
+ case PSI_CONTEXT_QUERY_SELF:
+ return "jit";
+ case PSI_CONTEXT_QUERY_TYPE:
+ return psi_jit_impl_type(*(token_t *) arg);
+ }
+ return NULL;
+}
+
+static struct psi_context_ops ops = {psi_jit_init, psi_jit_dtor,
+ psi_jit_compile, psi_jit_call, psi_jit_call_va, psi_jit_query};
+
+struct psi_context_ops *psi_libjit_ops(void)