From: Michael Wallner Date: Fri, 16 Oct 2015 11:27:44 +0000 (+0200) Subject: flush X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=4a49fe2f8eb21cdeabb06acec7a0395b6708d911;p=m6w6%2Fext-psi flush --- diff --git a/php_psi.h b/php_psi.h index 0828ebe..4be4027 100644 --- a/php_psi.h +++ b/php_psi.h @@ -21,7 +21,7 @@ extern zend_module_entry psi_module_entry; ZEND_BEGIN_MODULE_GLOBALS(psi) char *directory; - void *context; + PSI_Context context; ZEND_END_MODULE_GLOBALS(psi); #define PSI_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(psi, v) diff --git a/src/compiler.c b/src/compiler.c index f2821ca..3181aea 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -35,234 +35,7 @@ void PSI_Compiler_Free(PSI_Compiler **C) } } -typedef struct PSI_ClosureData { - void *context; - impl *impl; - jit_type_t signature; - zval return_value; -} PSI_ClosureData; - -static inline PSI_ClosureData *PSI_ClosureDataAlloc(void *context, impl *impl) { - PSI_ClosureData *data = malloc(sizeof(*data)); - - data->context = context; - data->impl = impl; - - return data; -} - -static inline size_t impl_num_min_args(impl *impl) { - size_t i, n = impl->func->args->count; - - for (i = 0; i < impl->func->args->count; ++i) { - if (impl->func->args->args[i]->def) { - --n; - } - } - return n; -} - -static inline jit_abi_t psi_jit_abi(const char *convention) { - return jit_abi_cdecl; -} -static inline jit_type_t psi_jit_type(token_t t) { - switch (t) { - case PSI_T_VOID: - return jit_type_void; - case PSI_T_SINT8: - return jit_type_sbyte; - case PSI_T_UINT8: - return jit_type_ubyte; - case PSI_T_SINT16: - return jit_type_short; - case PSI_T_UINT16: - return jit_type_ushort; - case PSI_T_SINT32: - return jit_type_int; - case PSI_T_UINT32: - return jit_type_uint; - case PSI_T_SINT64: - return jit_type_long; - case PSI_T_UINT64: - return jit_type_ulong; - case PSI_T_BOOL: - return jit_type_sys_bool; - case PSI_T_CHAR: - return jit_type_sys_char; - case PSI_T_SHORT: - return jit_type_sys_short; - case PSI_T_INT: - return jit_type_sys_int; - case PSI_T_LONG: - return jit_type_sys_long; - case PSI_T_FLOAT: - return jit_type_sys_float; - case PSI_T_DOUBLE: - return jit_type_sys_double; - default: - abort(); - } -} -static inline jit_type_t psi_jit_decl_type(decl_type *type) { - return psi_jit_type(real_decl_type(type)->type); -} -static inline jit_type_t psi_jit_decl_arg_type(decl_arg *darg) { - if (darg->var->pointer_level) { - return jit_type_void_ptr; - } else { - return psi_jit_decl_type(darg->type); - } -} -static void psi_jit_closure_handler(jit_type_t _sig, void *result, void **_args, void *_data) -{ - zend_execute_data *execute_data = *(zend_execute_data **)_args[0]; - zval *return_value = *(zval **)_args[1]; - PSI_ClosureData *data = _data; - impl_arg *iarg; - size_t i; - void **arg_ptr = NULL, **arg_prm = NULL; - impl_val ret_val, *arg_val = NULL; - jit_type_t signature, *sig_prm; - - if (!data->impl->func->args->count) { - if (SUCCESS != zend_parse_parameters_none()) { - return; - } - } else - ZEND_PARSE_PARAMETERS_START(impl_num_min_args(data->impl), data->impl->func->args->count) - nextarg: - iarg = data->impl->func->args->args[_i]; - if (iarg->def) { - Z_PARAM_OPTIONAL; - } - if (PSI_T_BOOL == iarg->type->type) { - if (iarg->def) { - iarg->val.bval = iarg->def->type == PSI_T_TRUE ? 1 : 0; - } - Z_PARAM_BOOL(iarg->val.bval); - } else if (PSI_T_INT == iarg->type->type) { - if (iarg->def) { - iarg->val.lval = zend_atol(iarg->def->text, strlen(iarg->def->text)); - } - Z_PARAM_LONG(iarg->val.lval); - } else if (PSI_T_FLOAT == iarg->type->type) { - if (iarg->def) { - iarg->val.dval = zend_strtod(iarg->def->text, NULL); - } - Z_PARAM_DOUBLE(iarg->val.dval); - } else if (PSI_T_STRING == iarg->type->type) { - if (iarg->def) { - /* FIXME */ - iarg->val.str.len = strlen(iarg->def->text) - 2; - iarg->val.str.val = &iarg->def->text[1]; - } - Z_PARAM_STRING(iarg->val.str.val, iarg->val.str.len); - } else { - error_code = ZPP_ERROR_FAILURE; - break; - } - iarg->_zv = _arg; - if (_i < _max_num_args) { - goto nextarg; - } - ZEND_PARSE_PARAMETERS_END(); - - if (data->impl->decl->args->count) { - arg_ptr = malloc(data->impl->decl->args->count * sizeof(*arg_ptr)); - arg_prm = malloc(data->impl->decl->args->count * sizeof(*arg_prm)); - arg_val = malloc(data->impl->decl->args->count * sizeof(*arg_val)); - sig_prm = malloc(data->impl->decl->args->count * sizeof(*sig_prm)); - - for (i = 0; i < data->impl->decl->args->count; ++i) { - decl_arg *darg = data->impl->decl->args->args[i]; - impl_arg *iarg = darg->let->arg; - - switch (darg->let->val->func->type) { - case PSI_T_BOOLVAL: - if (iarg->type->type == PSI_T_BOOL) { - arg_val[i].bval = iarg->val.bval; - } else { - arg_val[i].bval = zend_is_true(iarg->_zv); - } - break; - case PSI_T_INTVAL: - if (iarg->type->type == PSI_T_INT) { - arg_val[i].lval = iarg->val.lval; - } else { - arg_val[i].lval = zval_get_long(iarg->_zv); - } - break; - case PSI_T_STRVAL: - if (iarg->type->type == PSI_T_STRING) { - arg_val[i].str.val = estrndup(iarg->val.str.val, iarg->val.str.len); - } else { - zend_string *zs = zval_get_string(iarg->_zv); - arg_val[i].str.val = estrndup(zs->val, zs->len); - zend_string_release(zs); - } - break; - case PSI_T_STRLEN: - if (iarg->type->type == PSI_T_STRING) { - arg_val[i].lval =iarg->val.str.len; - } else { - zend_string *zs = zval_get_string(iarg->_zv); - arg_val[i].lval = zs->len; - zend_string_release(zs); - } - break; - } - arg_ptr[i] = &arg_val[i]; - arg_prm[i] = darg->let->val->is_reference ? &arg_ptr[i] : arg_ptr[i]; - sig_prm[i] = psi_jit_decl_arg_type(darg); - } - } - - signature = jit_type_create_signature( - psi_jit_abi(data->impl->decl->abi->convention), - psi_jit_decl_arg_type(data->impl->decl->func), - sig_prm, - data->impl->decl->args->count, - 1); - jit_apply(signature, data->impl->decl->dlptr, arg_prm, data->impl->decl->args->count, &ret_val); - - switch (data->impl->stmts->ret.list[0]->func->type) { - case PSI_T_TO_STRING: - if (data->impl->decl->func->var->pointer_level) { - switch (real_decl_type(data->impl->decl->func->type)->type) { - case PSI_T_CHAR: - case PSI_T_SINT8: - case PSI_T_UINT8: - RETVAL_STRING(ret_val.str.val); - break; - } - } - break; - } -} zend_function_entry *PSI_CompilerCompile(PSI_Compiler *C) { - size_t i, j = 0; - jit_type_t signature, params[] = { - jit_type_void_ptr, - jit_type_void_ptr - }; - zend_function_entry *zfe = calloc(C->impls->count + 1, sizeof(*zfe)); - - for (i = 0; i < C->impls->count; ++i) { - zend_function_entry *zf; - PSI_ClosureData *data; - - if (!C->impls->list[i]->decl) { - continue; - } - - zf = &zfe[j++]; - data = PSI_ClosureDataAlloc(C->context, C->impls->list[i]); - signature = jit_type_create_signature(jit_abi_vararg, jit_type_void, params, 2, 1); - zf->fname = C->impls->list[i]->func->name + (C->impls->list[i]->func->name[0] == '\\'); - zf->handler = jit_closure_create(C->context, signature, &psi_jit_closure_handler, data); - } - - return zfe; } diff --git a/src/context.c b/src/context.c new file mode 100644 index 0000000..2b91f43 --- /dev/null +++ b/src/context.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include + +#include "php.h" +#include "php_scandir.h" +#include "context.h" + +PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error) +{ + if (!C) { + C = malloc(sizeof(*C)); + } + memset(C, 0, sizeof(*C)); + + C->error = error; + C->ops = ops; + ops->init(C); + + return C; +} + +static int psi_select_dirent(const struct dirent *entry) +{ +#ifndef FNM_CASEFOLD +#define FNM_CASEFOLD 0 +#endif + return 0 == fnmatch("*.psi", entry->d_name, FNM_CASEFOLD); +} + + +void PSI_ContextBuild(PSI_Context *C, const char *path) +{ + int i, n; + struct dirent **entries = NULL; + + n = php_scandir(path, &entries, psi_select_dirent, alphasort); + + if (n < 0) { + C->error(PSI_WARNING, "Failed to scan PSI directory '%s'", path); + } else for (i = 0; i < n; ++i) { + char psi[MAXPATHLEN]; + PSI_Parser P; + PSI_Validator V; + + if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", path, entries[i]->d_name)) { + C->error(PSI_WARNING, "Path to PSI file too long: %s/%s", + path, entries[i]->d_name); + } + if (!PSI_ParserInit(&P, psi, psi_error, 0)) { + C->error(PSI_WARNING, "Failed to init PSI parser (%s): %s", + psi, strerror(errno)); + continue; + } + + while (-1 != PSI_ParserScan(&P)) { + PSI_ParserParse(&P, PSI_TokenAlloc(&P)); + }; + PSI_ParserParse(&P, NULL); + + if (!PSI_ValidatorInit(&V, &P)) { + C->error(PSI_WARNING, "Failed to init PSI validator"); + break; + } + PSI_ParserDtor(&P); + + if (PSI_ValidatorValidate(&V)) { + zend_function_entry *closures = PSI_ContextCompile(C, (PSI_Data *) &V); + + if (closures && SUCCESS != zend_register_functions(NULL, closures, NULL, MODULE_PERSISTENT)) { + C->error(PSI_WARNING, "Failed to register functions!"); + } + + } + PSI_ValidatorDtor(&V); + } + if (entries) { + for (i = 0; i < n; ++i) { + free(entries[i]); + } + free(entries); + } + +} + +zend_function_entry *PSI_ContextCompile(PSI_Context *C, PSI_Data *D) +{ + size_t count = C->count++; + zend_function_entry *zfe; + + C->data = realloc(C->data, C->count * sizeof(*C->data)); + PSI_DataExchange(&C->data[count], D); + + zfe = C->ops->compile(C, &C->data[count]); + + C->closures = realloc(C->closures, C->count * sizeof(*C->closures)); + C->closures[count] = zfe; + + return zfe; +} + +void PSI_ContextDtor(PSI_Context *C) +{ + size_t i; + + C->ops->dtor(C); + + for (i = 0; i < C->count; ++i) { + PSI_DataDtor(&C->data[i]); + } + free(C->data); + + memset(C, 0, sizeof(*C)); +} + +void PSI_ContextFree(PSI_Context **C) +{ + if (*C) { + PSI_ContextDtor(*C); + free(*C); + *C = NULL; + } +} + diff --git a/src/context.h b/src/context.h new file mode 100644 index 0000000..d75c19e --- /dev/null +++ b/src/context.h @@ -0,0 +1,29 @@ +#ifndef _PSI_CONTEXT_H +#define _PSI_CONTEXT_H + +#define PSI_ERROR 16 +#define PSI_WARNING 32 +typedef void (*PSI_ContextErrorFunc)(int type, const char *msg, ...); + +typedef struct PSI_ContextOps { + void (*init)(struct PSI_Context *C); + void (*dtor)(struct PSI_Context *C); + zend_function_entry *(*compile)(struct PSI_Context *C, struct PSI_Data *D); +} PSI_ContextOps; + +typedef struct PSI_Context { + void *opaque; + PSI_ContextErrorFunc error; + struct PSI_ContextOps *ops; + struct PSI_Data *data; + zend_function_entry **closures; + size_t count; +} PSI_Context; + +PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error); +void PSI_ContextBuild(PSI_Context *C, const char *path); +zend_function_entry *PSI_ContextCompile(PSI_Context *C, PSI_Data *D); +void PSI_ContextDtor(PSI_Context *C); +void PSI_ContextFree(PSI_Context **C); + +#endif diff --git a/src/libjit.c b/src/libjit.c new file mode 100644 index 0000000..5c4a7b9 --- /dev/null +++ b/src/libjit.c @@ -0,0 +1,260 @@ +#include "php.h" +#include "libjit.h" +#include "parser_proc.h" + +static void init(PSI_Context *C) +{ + C->opaque = jit_context_create(); +} + +static void dtor(PSI_Context *C) +{ + jit_context_destroy(C->opaque); +} + +typedef struct PSI_ClosureData { + void *context; + impl *impl; + jit_type_t signature; + zval return_value; +} PSI_ClosureData; + +static inline PSI_ClosureData *PSI_ClosureDataAlloc(void *context, impl *impl) { + PSI_ClosureData *data = malloc(sizeof(*data)); + + data->context = context; + data->impl = impl; + + return data; +} + +static inline size_t impl_num_min_args(impl *impl) { + size_t i, n = impl->func->args->count; + + for (i = 0; i < impl->func->args->count; ++i) { + if (impl->func->args->args[i]->def) { + --n; + } + } + return n; +} + +static inline jit_abi_t psi_jit_abi(const char *convention) { + return jit_abi_cdecl; +} +static inline jit_type_t psi_jit_type(token_t t) { + switch (t) { + case PSI_T_VOID: + return jit_type_void; + case PSI_T_SINT8: + return jit_type_sbyte; + case PSI_T_UINT8: + return jit_type_ubyte; + case PSI_T_SINT16: + return jit_type_short; + case PSI_T_UINT16: + return jit_type_ushort; + case PSI_T_SINT32: + return jit_type_int; + case PSI_T_UINT32: + return jit_type_uint; + case PSI_T_SINT64: + return jit_type_long; + case PSI_T_UINT64: + return jit_type_ulong; + case PSI_T_BOOL: + return jit_type_sys_bool; + case PSI_T_CHAR: + return jit_type_sys_char; + case PSI_T_SHORT: + return jit_type_sys_short; + case PSI_T_INT: + return jit_type_sys_int; + case PSI_T_LONG: + return jit_type_sys_long; + case PSI_T_FLOAT: + return jit_type_sys_float; + case PSI_T_DOUBLE: + return jit_type_sys_double; + default: + abort(); + } +} +static inline jit_type_t psi_jit_decl_type(decl_type *type) { + return psi_jit_type(real_decl_type(type)->type); +} +static inline jit_type_t psi_jit_decl_arg_type(decl_arg *darg) { + if (darg->var->pointer_level) { + return jit_type_void_ptr; + } else { + return psi_jit_decl_type(darg->type); + } +} +static void handler(jit_type_t _sig, void *result, void **_args, void *_data) +{ + zend_execute_data *execute_data = *(zend_execute_data **)_args[0]; + zval *return_value = *(zval **)_args[1]; + PSI_ClosureData *data = _data; + impl_arg *iarg; + size_t i; + void **arg_ptr = NULL, **arg_prm = NULL; + impl_val ret_val, *arg_val = NULL; + jit_type_t signature, *sig_prm; + + if (!data->impl->func->args->count) { + if (SUCCESS != zend_parse_parameters_none()) { + return; + } + } else + ZEND_PARSE_PARAMETERS_START(impl_num_min_args(data->impl), data->impl->func->args->count) + nextarg: + iarg = data->impl->func->args->args[_i]; + if (iarg->def) { + Z_PARAM_OPTIONAL; + } + if (PSI_T_BOOL == iarg->type->type) { + if (iarg->def) { + iarg->val.bval = iarg->def->type == PSI_T_TRUE ? 1 : 0; + } + Z_PARAM_BOOL(iarg->val.bval); + } else if (PSI_T_INT == iarg->type->type) { + if (iarg->def) { + iarg->val.lval = zend_atol(iarg->def->text, strlen(iarg->def->text)); + } + Z_PARAM_LONG(iarg->val.lval); + } else if (PSI_T_FLOAT == iarg->type->type) { + if (iarg->def) { + iarg->val.dval = zend_strtod(iarg->def->text, NULL); + } + Z_PARAM_DOUBLE(iarg->val.dval); + } else if (PSI_T_STRING == iarg->type->type) { + if (iarg->def) { + /* FIXME */ + iarg->val.str.len = strlen(iarg->def->text) - 2; + iarg->val.str.val = &iarg->def->text[1]; + } + Z_PARAM_STRING(iarg->val.str.val, iarg->val.str.len); + } else { + error_code = ZPP_ERROR_FAILURE; + break; + } + iarg->_zv = _arg; + if (_i < _max_num_args) { + goto nextarg; + } + ZEND_PARSE_PARAMETERS_END(); + + if (data->impl->decl->args->count) { + arg_ptr = malloc(data->impl->decl->args->count * sizeof(*arg_ptr)); + arg_prm = malloc(data->impl->decl->args->count * sizeof(*arg_prm)); + arg_val = malloc(data->impl->decl->args->count * sizeof(*arg_val)); + sig_prm = malloc(data->impl->decl->args->count * sizeof(*sig_prm)); + + for (i = 0; i < data->impl->decl->args->count; ++i) { + decl_arg *darg = data->impl->decl->args->args[i]; + impl_arg *iarg = darg->let->arg; + + switch (darg->let->val->func->type) { + case PSI_T_BOOLVAL: + if (iarg->type->type == PSI_T_BOOL) { + arg_val[i].bval = iarg->val.bval; + } else { + arg_val[i].bval = zend_is_true(iarg->_zv); + } + break; + case PSI_T_INTVAL: + if (iarg->type->type == PSI_T_INT) { + arg_val[i].lval = iarg->val.lval; + } else { + arg_val[i].lval = zval_get_long(iarg->_zv); + } + break; + case PSI_T_STRVAL: + if (iarg->type->type == PSI_T_STRING) { + arg_val[i].str.val = estrndup(iarg->val.str.val, iarg->val.str.len); + } else { + zend_string *zs = zval_get_string(iarg->_zv); + arg_val[i].str.val = estrndup(zs->val, zs->len); + zend_string_release(zs); + } + break; + case PSI_T_STRLEN: + if (iarg->type->type == PSI_T_STRING) { + arg_val[i].lval =iarg->val.str.len; + } else { + zend_string *zs = zval_get_string(iarg->_zv); + arg_val[i].lval = zs->len; + zend_string_release(zs); + } + break; + } + arg_ptr[i] = &arg_val[i]; + arg_prm[i] = darg->let->val->is_reference ? &arg_ptr[i] : arg_ptr[i]; + sig_prm[i] = psi_jit_decl_arg_type(darg); + } + } + + signature = jit_type_create_signature( + psi_jit_abi(data->impl->decl->abi->convention), + psi_jit_decl_arg_type(data->impl->decl->func), + sig_prm, + data->impl->decl->args->count, + 1); + jit_apply(signature, data->impl->decl->dlptr, arg_prm, data->impl->decl->args->count, &ret_val); + + switch (data->impl->stmts->ret.list[0]->func->type) { + case PSI_T_TO_STRING: + if (data->impl->decl->func->var->pointer_level) { + switch (real_decl_type(data->impl->decl->func->type)->type) { + case PSI_T_CHAR: + case PSI_T_SINT8: + case PSI_T_UINT8: + RETVAL_STRING(ret_val.str.val); + break; + } + } + break; + } +} + +static zend_function_entry *compile(PSI_Context *C, PSI_Data *D) +{ + size_t i, j = 0; + jit_type_t signature, params[] = { + jit_type_void_ptr, + jit_type_void_ptr + }; + zend_function_entry *zfe = calloc(D->impls->count + 1, sizeof(*zfe)); + + jit_context_build_start(C->opaque); + + for (i = 0; i < D->impls->count; ++i) { + zend_function_entry *zf; + PSI_ClosureData *data; + + if (!D->impls->list[i]->decl) { + continue; + } + + zf = &zfe[j++]; + data = PSI_ClosureDataAlloc(C, D->impls->list[i]); + signature = jit_type_create_signature(jit_abi_cdecl, jit_type_void, params, 2, 1); + zf->fname = D->impls->list[i]->func->name + (D->impls->list[i]->func->name[0] == '\\'); + zf->handler = jit_closure_create(C->opaque, signature, &handler, data); + } + + jit_context_build_end(C->opaque); + + return zfe; +} + +static PSI_ContextOps ops = { + init, + dtor, + compile, +}; + +PSI_ContextOps *PSI_Libjit(void) +{ + return &ops; +} diff --git a/src/libjit.h b/src/libjit.h new file mode 100644 index 0000000..78012a6 --- /dev/null +++ b/src/libjit.h @@ -0,0 +1,6 @@ +#ifndef _PSI_LIBJIT_H +#define _PSI_LIBJIT_H + +PSI_ContextOps *PSI_Libjit(void); + +#endif diff --git a/src/module.c b/src/module.c index 69ec53d..b8109b3 100644 --- a/src/module.c +++ b/src/module.c @@ -4,13 +4,10 @@ #endif #include -#include -#include #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" -#include "php_scandir.h" #include "php_psi.h" @@ -24,7 +21,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("psi.directory", "psis", PHP_INI_ALL, OnUpdateString, directory, zend_psi_globals, psi_globals) PHP_INI_END(); -static void psi_error(int type, const char *msg, ...) +void psi_error(int type, const char *msg, ...) { char buf[0x1000]; va_list argv; @@ -36,82 +33,13 @@ static void psi_error(int type, const char *msg, ...) php_error(type, buf); } -static int psi_select_dirent(const struct dirent *entry) -{ -#ifndef FNM_CASEFOLD -#define FNM_CASEFOLD 0 -#endif - return 0 == fnmatch("*.psi", entry->d_name, FNM_CASEFOLD); -} - PHP_MINIT_FUNCTION(psi) { - jit_context_t ctx; - int i, n; - struct dirent **entries = NULL; - REGISTER_INI_ENTRIES(); - jit_init(); - - if (!(ctx = jit_context_create())) { - zend_error(E_WARNING, "Could not initialize libjit!"); - return FAILURE; - } - - PSI_G(context) = ctx; - - n = php_scandir(PSI_G(directory), &entries, psi_select_dirent, alphasort); - if (n < 0) { - php_error(E_WARNING, "Failed to scan PSI directory '%s'", PSI_G(directory)); - } else for (i = 0; i < n; ++i) { - char psi[MAXPATHLEN]; - PSI_Parser P; - PSI_Validator V; - - if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", PSI_G(directory), entries[i]->d_name)) { - php_error(E_WARNING, "Path to PSI file too long: %s/%s", - PSI_G(directory), entries[i]->d_name); - } - if (!PSI_ParserInit(&P, psi, psi_error, 0)) { - php_error(E_WARNING, "Failed to init PSI parser (%s): %s", - psi, strerror(errno)); - continue; - } - - while (-1 != PSI_ParserScan(&P)) { - PSI_ParserParse(&P, PSI_TokenAlloc(&P)); - }; - PSI_ParserParse(&P, NULL); - - if (!PSI_ValidatorInit(&V, &P)) { - php_error(E_WARNING, "Failed to init PSI validator"); - break; - } - PSI_ParserDtor(&P); - - if (PSI_ValidatorValidate(&V)) { - PSI_Compiler C; - - jit_context_build_start(ctx); - if (PSI_CompilerInit(&C, &V, ctx)) { - zend_function_entry *closures = PSI_CompilerCompile(&C); - - if (closures && SUCCESS != zend_register_functions(NULL, closures, NULL, MODULE_PERSISTENT)) { - psi_error(E_WARNING, "Failed to register functions!"); - } - //PSI_CompilerDtor(&C); - } - jit_context_build_end(ctx); - } - PSI_ValidatorDtor(&V); - } - if (entries) { - for (i = 0; i < n; ++i) { - free(entries[i]); - } - free(entries); - } + PSI_ContextInit(&PSI_G(context), PSI_Libjit(), psi_error); + PSI_ContextBuild(&PSI_G(context), PSI_G(directory)); + return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(psi)