X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Fcontext.c;h=9b5730ed64736fe121866a0f04c2d807f34c233a;hb=5d02bb1fe8eb1396c316235cb887e1c570946275;hp=abe1ff64c79ade60197d11f26d34c2b462976f8f;hpb=413894839b41982ee7bb35be929cbf4431148f16;p=m6w6%2Fext-psi diff --git a/src/context.c b/src/context.c index abe1ff6..9b5730e 100644 --- a/src/context.c +++ b/src/context.c @@ -58,10 +58,64 @@ #include "php_psi_posix.h" +PHP_MINIT_FUNCTION(psi_context) +{ + unsigned flags = 0; + struct psi_context_ops *ops = NULL; + +#ifdef HAVE_LIBJIT + if (!strcasecmp(PSI_G(engine), "jit")) { + ops = psi_libjit_ops(); + } else +#endif +#ifdef HAVE_LIBFFI + ops = psi_libffi_ops(); +#endif + + if (!ops) { + php_error(E_WARNING, "No PSI engine found"); + return FAILURE; + } + + PSI_G(ops) = ops; + if (ops->load && SUCCESS != ops->load()) { + return FAILURE; + } + + if (psi_check_env("PSI_DEBUG")) { + flags |= PSI_DEBUG; + } + if (psi_check_env("PSI_SILENT")) { + flags |= PSI_SILENT; + } + + PSI_G(context) = psi_context_init(NULL, PSI_G(ops), psi_error_wrapper, flags); + psi_context_build(PSI_G(context), PSI_G(directory)); + + return SUCCESS; +} + +PHP_MSHUTDOWN_FUNCTION(psi_context) +{ + if (psi_check_env("PSI_DUMP")) { + struct psi_dump dump = {{.hn = stdout}, (psi_dump_cb) fprintf}; + + psi_context_dump(&dump, PSI_G(context)); + } + + psi_context_free(&PSI_G(context)); + + if (PSI_G(ops)->free) { + PSI_G(ops)->free(); + } + + return SUCCESS; +} + struct psi_context *psi_context_init(struct psi_context *C, struct psi_context_ops *ops, psi_error_cb error, unsigned flags) { if (!C) { - C = malloc(sizeof(*C)); + C = pemalloc(sizeof(*C), 1); } memset(C, 0, sizeof(*C)); @@ -92,11 +146,11 @@ static bool psi_context_add(struct psi_context *C, struct psi_parser *P) struct psi_data *D; struct psi_validate_scope scope = {0}; - C->data = realloc(C->data, (C->count + 1) * sizeof(*C->data)); + C->data = safe_perealloc(C->data, (C->count + 1), sizeof(*C->data), 0, 1); D = psi_data_exchange(&C->data[C->count++], PSI_DATA(P)); psi_validate_scope_ctor(&scope); - scope.defs = &P->preproc->defs; + scope.cpp = P->preproc; valid = psi_validate(&scope, PSI_DATA(C), D); psi_validate_scope_dtor(&scope); @@ -142,7 +196,7 @@ void psi_context_build(struct psi_context *C, const char *paths) psi_parser_parse(&P, I); psi_context_add(C, &P); psi_parser_dtor(&P); - free(I); + psi_parser_input_free(&I); } } @@ -157,13 +211,35 @@ void psi_context_build(struct psi_context *C, const char *paths) } while (sep); - if (psi_context_compile(C) && SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) { - C->error(PSI_DATA(C), NULL, PSI_WARNING, "Failed to register functions!"); + if (psi_context_compile(C)) { + /* zend_register_functions depends on EG(current_module) pointing into module */ + EG(current_module) = zend_hash_str_find_ptr(&module_registry, "psi", sizeof("psi") - 1); + if (SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) { + C->error(PSI_DATA(C), NULL, PSI_WARNING, "Failed to register functions!"); + } + EG(current_module) = NULL; } free(cpy); } +#include +static inline bool prefix_match(zend_string *a, zend_string *b) +{ + size_t i; + + for (i = 0; i < a->len && i < b->len; ++i) { + if (tolower(a->val[i]) != tolower(b->val[i])) { + return false; + } + if (i && a->val[i] == '_') { + break; + } + } + + return true; +} + zend_function_entry *psi_context_compile(struct psi_context *C) { zend_constant zc; @@ -176,31 +252,12 @@ zend_function_entry *psi_context_compile(struct psi_context *C) while (psi_plist_get(C->consts, i++, &c)) { - if (zend_get_constant_str(c->name, strlen(c->name))) { + if (zend_get_constant(c->name)) { continue; } - zc.name = zend_string_init(c->name, strlen(c->name), 1); - - switch (c->type->type) { - case PSI_T_BOOL: - ZVAL_BOOL(&zc.value, c->val->ival.zend.bval); - break; - case PSI_T_INT: - ZVAL_LONG(&zc.value, c->val->ival.zend.lval); - break; - case PSI_T_FLOAT: - case PSI_T_DOUBLE: - ZVAL_DOUBLE(&zc.value, c->val->ival.dval); - break; - case PSI_T_STRING: - case PSI_T_QUOTED_STRING: - ZVAL_NEW_STR(&zc.value, zend_string_copy(c->val->ival.zend.str)); - break; - default: - assert(0); - break; - } + zc.name = zend_string_copy(c->name); + psi_impl_def_val_get_zval(c->val, c->type ? c->type->type : PSI_T_MIXED, &zc.value); zend_register_constant(&zc); } @@ -217,10 +274,12 @@ zend_function_entry *psi_context_compile(struct psi_context *C) while (psi_plist_get(e->items, j++, &item)) { zend_string *name; - if (psi_decl_type_is_anon(e->name, "enum")) { - name = strpprintf(0, "psi\\%s", item->name); + if (psi_decl_type_is_anon(e->name, "enum") + || prefix_match(e->name, item->name)) { + name = strpprintf(0, "psi\\%s", item->name->val); } else { - name = strpprintf(0, "psi\\%s\\%s", e->name, item->name); + + name = strpprintf(0, "psi\\%s\\%s", e->name->val, item->name->val); } if (zend_get_constant(name)) { @@ -321,15 +380,21 @@ void psi_context_free(struct psi_context **C) } } -void psi_context_dump(struct psi_context *C, int fd) +void psi_context_dump(struct psi_dump *dump, struct psi_context *C) { - size_t i; - - dprintf(fd, "// psi.engine=%s\n// %lu files\n", + PSI_DUMP(dump, "// psi.engine=%s\n// %lu files\n", (char *) C->ops->query(C, PSI_CONTEXT_QUERY_SELF, NULL), C->count); - for (i = 0; i < C->count; ++i) { - psi_data_dump(fd, &C->data[i]); + psi_data_dump(dump, PSI_DATA(C)); + +#if 0 + if (C->flags & PSI_DEBUG) { + size_t i; + + for (i = 0; i < C->count; ++i) { + psi_data_dump(dump, &C->data[i]); + } } +#endif }