X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fcontext.c;h=fe2b5bc688f76001749f26c79d984799e524cd22;hp=1887a7c0146533b2b37fce2b4b175490d19475ce;hb=b25cb3852e3c6ef6da608001585218015aaf5d3e;hpb=b4a3c33fc143fd57288fcfe0878e7a22eeaf61bf diff --git a/src/context.c b/src/context.c index 1887a7c..fe2b5bc 100644 --- a/src/context.c +++ b/src/context.c @@ -2,6 +2,8 @@ # include "config.h" #endif +#include "php_psi_stdinc.h" + #include "php.h" #ifdef HAVE_DIRENT_H @@ -23,26 +25,30 @@ #include -#include "php.h" #include "php_scandir.h" #include "php_psi.h" - +#include "calc.h" #include "libjit.h" #include "libffi.h" +#include "token.h" +#include "parser.h" + #include "php_psi_types.h" #include "php_psi_consts.h" #include "php_psi_decls.h" #include "php_psi_va_decls.h" +#include "php_psi_fn_decls.h" #include "php_psi_structs.h" +#include "php_psi_unions.h" - -PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error) +struct psi_context *psi_context_init(struct psi_context *C, struct psi_context_ops *ops, psi_context_error_func error, unsigned flags) { - PSI_Data T; + struct psi_data T; struct psi_predef_type *predef_type; struct psi_predef_const *predef_const; struct psi_predef_struct *predef_struct; + struct psi_predef_union *predef_union; struct psi_predef_decl *predef_decl; if (!C) { @@ -51,6 +57,7 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr memset(C, 0, sizeof(*C)); C->error = error; + C->flags = flags; C->ops = ops; if (ops->init) { @@ -66,7 +73,8 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr for (predef_type = &psi_predef_types[0]; predef_type->type_tag; ++predef_type) { decl_type *type = init_decl_type(predef_type->type_tag, predef_type->type_name); - decl_typedef *def = init_decl_typedef(predef_type->alias, type); + decl_var *var = init_decl_var(predef_type->alias, 0, 0); /* FIXME: indirection */ + decl_arg *def = init_decl_arg(type, var); T.defs = add_decl_typedef(T.defs, def); } @@ -83,6 +91,7 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr decl_struct *dstruct = init_decl_struct(predef_struct->var_name, dargs); dstruct->size = predef_struct->size; + dstruct->align = predef_struct->offset; for (member = &predef_struct[1]; member->type_tag; ++member) { decl_type *type; decl_var *dvar; @@ -98,6 +107,28 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr T.structs = add_decl_struct(T.structs, dstruct); predef_struct = member; } + for (predef_union = &psi_predef_unions[0]; predef_union->type_tag; ++predef_union) { + struct psi_predef_union *member; + decl_args *dargs = init_decl_args(NULL); + decl_union *dunion = init_decl_union(predef_union->var_name, dargs); + + dunion->size = predef_union->size; + dunion->align = predef_union->offset; + for (member = &predef_union[1]; member->type_tag; ++member) { + decl_type *type; + decl_var *dvar; + decl_arg *darg; + + type = init_decl_type(member->type_tag, member->type_name); + dvar = init_decl_var(member->var_name, member->pointer_level, member->array_size); + darg = init_decl_arg(type, dvar); + darg->layout = init_decl_struct_layout(member->offset, member->size); + dargs = add_decl_arg(dargs, darg); + } + + T.unions = add_decl_union(T.unions, dunion); + predef_union = member; + } for (predef_decl = &psi_predef_decls[0]; predef_decl->type_tag; ++predef_decl) { struct psi_predef_decl *farg; decl_type *ftype = init_decl_type(predef_decl->type_tag, predef_decl->type_name); @@ -137,11 +168,34 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr predef_decl = farg; } - PSI_ContextValidatePredef(C, &T); + for (predef_decl = &psi_predef_functor_decls[0]; predef_decl->type_tag; ++predef_decl) { + struct psi_predef_decl *farg; + decl_type *dtype, *ftype = init_decl_type(predef_decl->type_tag, predef_decl->type_name); + decl_var *fname = init_decl_var(predef_decl->var_name, predef_decl->pointer_level, predef_decl->array_size); + decl_arg *tdef, *func = init_decl_arg(ftype, fname); + decl_args *args = init_decl_args(NULL); + decl *decl = init_decl(init_decl_abi("default"), func, args); + + for (farg = &predef_decl[1]; farg->type_tag; ++farg) { + decl_type *arg_type = init_decl_type(farg->type_tag, farg->type_name); + decl_var *arg_var = init_decl_var(farg->var_name, farg->pointer_level, farg->array_size); + decl_arg *darg = init_decl_arg(arg_type, arg_var); + args = add_decl_arg(args, darg); + } + + dtype = init_decl_type(PSI_T_FUNCTION, fname->name); + dtype->real.func = decl; + tdef = init_decl_arg(dtype, copy_decl_var(fname)); + T.defs = add_decl_typedef(T.defs, tdef); + + predef_decl = farg; + } + + psi_context_validate_data(PSI_DATA(C), &T); C->count = 1; C->data = malloc(sizeof(*C->data)); - PSI_DataExchange(C->data, &T); + psi_data_exchange(C->data, &T); return C; } @@ -154,12 +208,11 @@ 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 *paths) +void psi_context_build(struct psi_context *C, const char *paths) { - int i, n, flags = psi_check_env("PSI_DEBUG") ? PSI_PARSER_DEBUG : 0; + int i, n; char *sep = NULL, *cpy = strdup(paths), *ptr = cpy; - struct dirent **entries = NULL; - + struct dirent **entries; do { sep = strchr(ptr, ':'); @@ -168,33 +221,34 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths) *sep = 0; } + entries = NULL; n = php_scandir(ptr, &entries, psi_select_dirent, alphasort); if (n > 0) { for (i = 0; i < n; ++i) { char psi[MAXPATHLEN]; - PSI_Parser P; + struct psi_parser P; if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", ptr, entries[i]->d_name)) { - C->error(NULL, PSI_WARNING, "Path to PSI file too long: %s/%s", + C->error(C, NULL, PSI_WARNING, "Path to PSI file too long: %s/%s", ptr, entries[i]->d_name); } - if (!PSI_ParserInit(&P, psi, C->error, flags)) { - C->error(NULL, PSI_WARNING, "Failed to init PSI parser (%s): %s", + if (!psi_parser_init(&P, psi, C->error, C->flags)) { + C->error(C, NULL, PSI_WARNING, "Failed to init PSI parser (%s): %s", psi, strerror(errno)); continue; } - while (0 < PSI_ParserScan(&P)) { - PSI_ParserParse(&P, PSI_TokenAlloc(&P)); + while (0 < psi_parser_scan(&P)) { + psi_parser_parse(&P, psi_token_alloc(&P)); if (P.num == PSI_T_EOF) { break; } } - PSI_ParserParse(&P, NULL); - PSI_ContextValidate(C, &P); - PSI_ParserDtor(&P); + psi_parser_parse(&P, NULL); + psi_context_validate(C, &P); + psi_parser_dtor(&P); } } @@ -209,24 +263,23 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths) } while (sep); - if (PSI_ContextCompile(C) && SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) { - C->error(NULL, PSI_WARNING, "Failed to register functions!"); + if (psi_context_compile(C) && SUCCESS != zend_register_functions(NULL, C->closures, NULL, MODULE_PERSISTENT)) { + C->error(C, NULL, PSI_WARNING, "Failed to register functions!"); } free(cpy); } -zend_function_entry *PSI_ContextCompile(PSI_Context *C) +zend_function_entry *psi_context_compile(struct psi_context *C) { size_t i; + zend_constant zc; - if (C->consts) { - zend_constant zc; - - zc.flags = CONST_PERSISTENT|CONST_CS; - zc.module_number = EG(current_module)->module_number; + zc.flags = CONST_PERSISTENT|CONST_CS; + zc.module_number = EG(current_module)->module_number; + if (C->consts) { for (i = 0; i < C->consts->count; ++i) { constant *c = C->consts->list[i]; @@ -247,18 +300,34 @@ zend_function_entry *PSI_ContextCompile(PSI_Context *C) zend_register_constant(&zc); } } + if (C->enums) { + for (i = 0; i < C->enums->count; ++i) { + decl_enum *e = C->enums->list[i]; + size_t j; + + for (j = 0; j < e->items->count; ++j) { + decl_enum_item *i = e->items->list[j]; + zend_string *name = strpprintf(0, "psi\\%s\\%s", e->name, i->name); + + zc.name = zend_string_dup(name, 1); + ZVAL_LONG(&zc.value, psi_long_num_exp(i->num, NULL)); + zend_register_constant(&zc); + zend_string_release(name); + } + } + } return C->closures = C->ops->compile(C); } -void PSI_ContextCall(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va) +void psi_context_call(struct psi_context *C, struct decl_callinfo *decl_call, struct impl_vararg *va) { C->ops->call(C, decl_call, va); } -void PSI_ContextDtor(PSI_Context *C) +void psi_context_dtor(struct psi_context *C) { size_t i; zend_function_entry *zfe; @@ -271,7 +340,7 @@ void PSI_ContextDtor(PSI_Context *C) if (C->data) { for (i = 0; i < C->count; ++i) { - PSI_DataDtor(&C->data[i]); + psi_data_dtor(&C->data[i]); } free(C->data); } @@ -301,6 +370,18 @@ void PSI_ContextDtor(PSI_Context *C) } free(C->structs); } + if (C->unions) { + if (C->unions->list) { + free(C->unions->list); + } + free(C->unions); + } + if (C->enums) { + if (C->enums->list) { + free(C->enums->list); + } + free(C->enums); + } if (C->decls) { if (C->decls->list) { free(C->decls->list); @@ -317,10 +398,10 @@ void PSI_ContextDtor(PSI_Context *C) memset(C, 0, sizeof(*C)); } -void PSI_ContextFree(PSI_Context **C) +void psi_context_free(struct psi_context **C) { if (*C) { - PSI_ContextDtor(*C); + psi_context_dtor(*C); free(*C); *C = NULL; }