+
+typedef struct PSI_LibjitContext {
+ jit_context_t jit;
+ jit_type_t signature;
+ struct {
+ struct PSI_LibjitData **list;
+ size_t count;
+ } data;
+} PSI_LibjitContext;
+
+typedef struct PSI_LibjitData {
+ PSI_LibjitContext *context;
+ impl *impl;
+ zend_internal_arg_info *arginfo;
+ void *closure;
+ jit_type_t signature;
+ jit_type_t params[1];
+} PSI_LibjitData;
+
+static inline PSI_LibjitData *PSI_LibjitDataAlloc(PSI_LibjitContext *context, impl *impl) {
+ size_t i, c = impl->decl->args->count;
+ PSI_LibjitData *data = malloc(sizeof(*data) + (c ? c-1 : c) * sizeof(jit_type_t));
+
+ data->context = context;
+ data->impl = impl;
+ data->arginfo = psi_internal_arginfo(impl);
+ for (i = 0; i < c; ++i) {
+ data->params[i] = psi_jit_decl_arg_type(impl->decl->args->args[i]);
+ }
+
+ data->signature = jit_type_create_signature(
+ psi_jit_abi(data->impl->decl->abi->convention),
+ psi_jit_decl_arg_type(data->impl->decl->func),
+ data->params,
+ data->impl->decl->args->count,
+ 1);
+ data->closure = jit_closure_create(context->jit, context->signature, &psi_jit_handler, data);
+
+ context->data.list = realloc(context->data.list, ++context->data.count * sizeof(*context->data.list));
+ context->data.list[context->data.count-1] = data;
+
+ return data;
+}
+
+static inline void PSI_LibjitDataFree(PSI_LibjitData *data) {
+ free(data->arginfo);
+ jit_type_free(data->signature);
+ free(data);
+}
+
+static inline PSI_LibjitContext *PSI_LibjitContextInit(PSI_LibjitContext *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_LibjitContextDtor(PSI_LibjitContext *L) {
+ size_t i;
+
+ for (i = 0; i < L->data.count; ++i) {
+ PSI_LibjitDataFree(L->data.list[i]);
+ }
+ if (L->data.list) {
+ free(L->data.list);
+ }
+ jit_type_free(L->signature);
+ jit_context_destroy(L->jit);
+}
+
+static inline void PSI_LibjitContextFree(PSI_LibjitContext **L) {
+ if (*L) {
+ PSI_LibjitContextDtor(*L);
+ free(*L);
+ *L = NULL;
+ }
+}
+
+static void psi_jit_handler(jit_type_t _sig, void *result, void **_args, void *_data)