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)
}
}
-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;
}
--- /dev/null
+#include <sys/param.h>
+#include <dirent.h>
+#include <fnmatch.h>
+#include <errno.h>
+
+#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;
+ }
+}
+
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+#ifndef _PSI_LIBJIT_H
+#define _PSI_LIBJIT_H
+
+PSI_ContextOps *PSI_Libjit(void);
+
+#endif
#endif
#include <jit/jit.h>
-#include <dirent.h>
-#include <fnmatch.h>
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_scandir.h"
#include "php_psi.h"
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;
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)