X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fcontext.c;h=987fb9abc0a45a660ba8353d25047a8e75c6feb4;hp=18e76e4db451b06fdde9f37537a6a1b09608451b;hb=7a717dad32d06fe5273ad3a9ce755908723f6685;hpb=d560a27ff8431c678d25ecf4d8190b562a766f41 diff --git a/src/context.c b/src/context.c index 18e76e4..987fb9a 100644 --- a/src/context.c +++ b/src/context.c @@ -235,19 +235,19 @@ static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_ #ifndef RTLD_NEXT # define RTLD_NEXT ((void *) -1l) #endif - decl->dlptr = dlsym(dl ?: RTLD_NEXT, func->var->name); - if (!decl->dlptr) { + decl->call.sym = dlsym(dl ?: RTLD_NEXT, func->var->name); + if (!decl->call.sym) { size_t i; for (i = 0; i < psi_predef_func_count(); ++i) { psi_predef_func *pre = &psi_predef_funcs[i]; if (!strcmp(func->var->name, pre->name)) { - decl->dlptr = pre->func; + decl->call.sym = pre->func; break; } } - if (!decl->dlptr) { + if (!decl->call.sym) { data->error(PSI_WARNING, "Failed to locate symbol '%s': %s", func->var->name, dlerror()); } @@ -368,10 +368,13 @@ static inline int validate_impl_ret_stmt(PSI_Data *data, impl *impl) { impl->func->name); return 0; } + if (!validate_set_value(data, ret->set, ret->decl)) { return 0; } + impl->decl->impl = impl; + return 1; } static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) { @@ -576,7 +579,13 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr C->error = error; C->ops = ops; - ops->init(C); + + if (ops->init) { + ops->init(C); + } + + ZEND_ASSERT(ops->call != NULL); + ZEND_ASSERT(ops->compile != NULL); /* build up predefs in a temporary PSI_Data for validation */ memset(&T, 0, sizeof(T)); @@ -728,47 +737,62 @@ static int psi_select_dirent(const struct dirent *entry) return 0 == fnmatch("*.psi", entry->d_name, FNM_CASEFOLD); } -void PSI_ContextBuild(PSI_Context *C, const char *path) +void PSI_ContextBuild(PSI_Context *C, const char *paths) { int i, n; + char *sep = NULL, *cpy = strdup(paths), *ptr = cpy; struct dirent **entries = NULL; - n = php_scandir(path, &entries, psi_select_dirent, alphasort); - if (n < 0) { - return; - } else for (i = 0; i < n; ++i) { - char psi[MAXPATHLEN]; - PSI_Parser P; + do { + sep = strchr(ptr, ':'); + + if (sep) { + *sep = 0; + } + + n = php_scandir(ptr, &entries, psi_select_dirent, alphasort); + + if (n > 0) { + for (i = 0; i < n; ++i) { + char psi[MAXPATHLEN]; + PSI_Parser P; + + if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", ptr, entries[i]->d_name)) { + C->error(PSI_WARNING, "Path to PSI file too long: %s/%s", + ptr, entries[i]->d_name); + } + if (!PSI_ParserInit(&P, psi, C->error, 0)) { + C->error(PSI_WARNING, "Failed to init PSI parser (%s): %s", + psi, strerror(errno)); + continue; + } - 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); + while (-1 != PSI_ParserScan(&P)) { + PSI_ParserParse(&P, PSI_TokenAlloc(&P)); + }; + PSI_ParserParse(&P, NULL); + PSI_ContextValidate(C, &P); + PSI_ParserDtor(&P); + } } - if (!PSI_ParserInit(&P, psi, C->error, 0)) { - C->error(PSI_WARNING, "Failed to init PSI parser (%s): %s", - psi, strerror(errno)); - continue; + + if (entries) { + for (i = 0; i < n; ++i) { + free(entries[i]); + } + free(entries); } - while (-1 != PSI_ParserScan(&P)) { - PSI_ParserParse(&P, PSI_TokenAlloc(&P)); - }; - PSI_ParserParse(&P, NULL); - PSI_ContextValidate(C, &P); - PSI_ParserDtor(&P); - } + ptr = sep + 1; + } while (sep); + if (PSI_ContextCompile(C) && SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) { C->error(PSI_WARNING, "Failed to register functions!"); } - if (entries) { - for (i = 0; i < n; ++i) { - free(entries[i]); - } - free(entries); - } + free(cpy); } @@ -803,29 +827,34 @@ zend_function_entry *PSI_ContextCompile(PSI_Context *C) } } - return C->closures = C->ops->compile(C); } -void PSI_ContextCall(PSI_Context *C, impl_val *ret_val, decl *decl, impl_val **args) +void PSI_ContextCall(PSI_Context *C, impl_val *ret_val, decl *decl) { - C->ops->call(C, ret_val, decl, args); + C->ops->call(C, ret_val, decl); } void PSI_ContextDtor(PSI_Context *C) { size_t i; + zend_function_entry *zfe; - C->ops->dtor(C); + if (C->ops->dtor) { + C->ops->dtor(C); + } free_decl_libs(&C->psi.libs); for (i = 0; i < C->count; ++i) { PSI_DataDtor(&C->data[i]); } - free(C->data); + + for (zfe = C->closures; zfe->fname; ++zfe) { + free((void *) zfe->arg_info); + } free(C->closures); if (C->consts) {