+
+struct psi_jit_context {
+ jit_context_t jit;
+ jit_type_t signature;
+ struct {
+ struct psi_jit_data **list;
+ size_t count;
+ } data;
+};
+
+struct psi_jit_call {
+ void *closure;
+ jit_type_t signature;
+ void *params[1]; /* [type1, type2, NULL, arg1, arg2] ... */
+};
+
+struct psi_jit_data {
+ struct psi_jit_context *context;
+ impl *impl;
+ zend_internal_arg_info *arginfo;
+};
+
+static inline struct psi_jit_call *psi_jit_call_alloc(struct psi_context *C, decl *decl) {
+ size_t i, c = decl->args ? decl->args->count : 0;
+ struct psi_jit_call *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *));
+
+ for (i = 0; i < c; ++i) {
+ call->params[i] = psi_jit_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];
+
+ 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);
+ ZEND_ASSERT(call->signature);
+
+ return call;
+}
+
+static inline void *psi_jit_call_init_closure(struct psi_context *C, struct psi_jit_call *call, impl *impl) {
+ struct psi_jit_context *context = C->context;
+ return call->closure = jit_closure_create(context->jit, context->signature,
+ &psi_jit_handler, impl);
+}
+
+static inline void *psi_jit_call_init_callback_closure(struct psi_context *C, struct psi_jit_call *call, let_callback *cb) {
+ struct psi_jit_context *context = C->context;
+ return call->closure = jit_closure_create(context->jit, call->signature,
+ &psi_jit_callback, cb);
+}
+
+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;
+}
+
+static inline void psi_jit_context_dtor(struct psi_jit_context *L) {
+ jit_type_free(L->signature);
+ jit_context_destroy(L->jit);
+}
+
+static inline void psi_jit_context_free(struct psi_jit_context **L) {
+ if (*L) {
+ psi_jit_context_dtor(*L);
+ free(*L);
+ *L = NULL;
+ }
+}
+
+static void psi_jit_init(struct psi_context *C)