From 5359ad5c181e5772f350fe1cba060cbed3a05b91 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 25 Aug 2016 12:19:01 +0200 Subject: [PATCH] api refactoring --- Makefile.frag | 22 +- config.m4 | 13 +- php_psi.h | 4 +- src/context.c | 42 +- src/context.h | 46 +- src/context_dump.c | 12 +- src/context_validate.c | 66 +- src/data.c | 44 + src/data.h | 31 + src/engine.c | 55 +- src/engine.h | 3 - src/libffi.c | 64 +- src/libffi.h | 2 +- src/libjit.c | 78 +- src/libjit.h | 2 +- src/module.c | 35 +- src/parser.h | 1701 +------------------------------- src/parser.re | 47 +- src/parser_def.h | 52 +- src/parser_proc.inc | 6 + src/parser_proc.y | 50 +- src/token.c | 142 +++ src/token.h | 87 ++ src/types.h | 140 +++ src/types/const_type.h | 21 + src/types/constant.h | 25 + src/types/constants.h | 28 + src/types/decl.h | 29 + src/types/decl_abi.h | 23 + src/types/decl_arg.h | 38 + src/types/decl_args.h | 36 + src/types/decl_callinfo.h | 12 + src/types/decl_enum.h | 29 + src/types/decl_enum_item.h | 31 + src/types/decl_enum_items.h | 42 + src/types/decl_enums.h | 30 + src/types/decl_file.h | 19 + src/types/decl_libs.h | 27 + src/types/decl_struct.h | 37 + src/types/decl_struct_layout.h | 21 + src/types/decl_structs.h | 28 + src/types/decl_type.h | 39 + src/types/decl_typedefs.h | 28 + src/types/decl_union.h | 29 + src/types/decl_unions.h | 28 + src/types/decl_var.h | 39 + src/types/decl_vars.h | 35 + src/types/decls.h | 28 + src/types/free_call.h | 27 + src/types/free_calls.h | 35 + src/types/free_stmt.h | 19 + src/types/impl.h | 23 + src/types/impl_arg.h | 38 + src/types/impl_args.h | 39 + src/types/impl_def_val.h | 21 + src/types/impl_func.h | 31 + src/types/impl_stmt.h | 40 + src/types/impl_stmts.h | 75 ++ src/types/impl_type.h | 22 + src/types/impl_val.h | 34 + src/types/impl_var.h | 37 + src/types/impls.h | 28 + src/types/let_callback.h | 26 + src/types/let_calloc.h | 22 + src/types/let_func.h | 27 + src/types/let_stmt.h | 27 + src/types/let_val.h | 80 ++ src/types/num_exp.h | 85 ++ src/types/return_stmt.h | 24 + src/types/set_func.h | 28 + src/types/set_stmt.h | 23 + src/types/set_value.h | 45 + src/types/set_values.h | 40 + 73 files changed, 2349 insertions(+), 1993 deletions(-) create mode 100644 src/data.c create mode 100644 src/data.h create mode 100644 src/token.c create mode 100644 src/token.h create mode 100644 src/types.h create mode 100644 src/types/const_type.h create mode 100644 src/types/constant.h create mode 100644 src/types/constants.h create mode 100644 src/types/decl.h create mode 100644 src/types/decl_abi.h create mode 100644 src/types/decl_arg.h create mode 100644 src/types/decl_args.h create mode 100644 src/types/decl_callinfo.h create mode 100644 src/types/decl_enum.h create mode 100644 src/types/decl_enum_item.h create mode 100644 src/types/decl_enum_items.h create mode 100644 src/types/decl_enums.h create mode 100644 src/types/decl_file.h create mode 100644 src/types/decl_libs.h create mode 100644 src/types/decl_struct.h create mode 100644 src/types/decl_struct_layout.h create mode 100644 src/types/decl_structs.h create mode 100644 src/types/decl_type.h create mode 100644 src/types/decl_typedefs.h create mode 100644 src/types/decl_union.h create mode 100644 src/types/decl_unions.h create mode 100644 src/types/decl_var.h create mode 100644 src/types/decl_vars.h create mode 100644 src/types/decls.h create mode 100644 src/types/free_call.h create mode 100644 src/types/free_calls.h create mode 100644 src/types/free_stmt.h create mode 100644 src/types/impl.h create mode 100644 src/types/impl_arg.h create mode 100644 src/types/impl_args.h create mode 100644 src/types/impl_def_val.h create mode 100644 src/types/impl_func.h create mode 100644 src/types/impl_stmt.h create mode 100644 src/types/impl_stmts.h create mode 100644 src/types/impl_type.h create mode 100644 src/types/impl_val.h create mode 100644 src/types/impl_var.h create mode 100644 src/types/impls.h create mode 100644 src/types/let_callback.h create mode 100644 src/types/let_calloc.h create mode 100644 src/types/let_func.h create mode 100644 src/types/let_stmt.h create mode 100644 src/types/let_val.h create mode 100644 src/types/num_exp.h create mode 100644 src/types/return_stmt.h create mode 100644 src/types/set_func.h create mode 100644 src/types/set_stmt.h create mode 100644 src/types/set_value.h create mode 100644 src/types/set_values.h diff --git a/Makefile.frag b/Makefile.frag index 6bb4061..bcdaa40 100644 --- a/Makefile.frag +++ b/Makefile.frag @@ -7,7 +7,7 @@ $(PHP_PSI_BUILDDIR)/%.h: $(PHP_PSI_SRCDIR)/src/%.h @cat >$@ <$< install-headers: psi-build-headers -clean: psi-clean-headers +clean: psi-clean .PHONY: psi-build-headers psi-build-headers: $(PHP_PSI_HEADERS) @@ -16,6 +16,19 @@ psi-build-headers: $(PHP_PSI_HEADERS) psi-clean-headers: -rm -f $(PHP_PSI_HEADERS) +.PHONY: psi-clean-sources +psi-clean-sources: + -rm -f $(PHP_PSI_BUILDDIR)/src/*o + -rm -f $(PHP_PSI_SRCDIR)/src/parser.c $(PHP_PSI_SRCDIR)/src/parser_proc.c $(PHP_PSI_SRCDIR)/src/parser_proc.y + +.PHONY: psi-clean-aux +psi-clean-aux: + -rm -f lempar.c lemon.c lemon + +.PHONY: psi-clean +psi-clean: psi-clean-headers psi-clean-sources psi-clean-aux + + lempar.c: curl -sSo $@ "http://www.sqlite.org/src/raw/tool/lempar.c?name=3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7" @@ -27,15 +40,14 @@ lemon.c: $(PHP_PSI_SRCDIR)/src/parser_proc.h: $(PHP_PSI_SRCDIR)/src/parser_proc.c -$(PHP_PSI_SRCDIR)/src/%.c: $(PHP_PSI_SRCDIR)/src/parser.h $(PHP_PSI_SRCDIR)/src/parser_proc.h - touch $@ -$(PHP_PSI_SRCDIR)/src/parser_proc.y: $(PHP_PSI_SRCDIR)/src/parser_def.h $(PHP_PSI_SRCDIR)/src/parser.h +$(PHP_PSI_SRCDIR)/src/parser_proc.inc: +$(PHP_PSI_SRCDIR)/src/parser_proc.y: $(PHP_PSI_SRCDIR)/src/parser_def.h $(PHP_PSI_SRCDIR)/src/parser_proc.inc cat $(PHP_PSI_SRCDIR)/src/parser_proc.inc >$@ $(CPP) -P -DGENERATE $< >>$@ $(PHP_PSI_SRCDIR)/src/parser_proc.c: $(PHP_PSI_SRCDIR)/src/parser_proc.y $(LEMON) $(LEMON) -c $< -$(PHP_PSI_SRCDIR)/src/parser.re: $(PHP_PSI_SRCDIR)/src/parser.h $(PHP_PSI_SRCDIR)/src/parser_proc.h +$(PHP_PSI_SRCDIR)/src/parser.re: $(PHP_PSI_SRCDIR)/src/parser_proc.h touch $@ $(PHP_PSI_SRCDIR)/src/parser.c: $(PHP_PSI_SRCDIR)/src/parser.re $(RE2C) -o $@ $< diff --git a/config.m4 b/config.m4 index e42e3bf..f9cf24d 100644 --- a/config.m4 +++ b/config.m4 @@ -113,12 +113,13 @@ if test "$PHP_PSI" != no; then PHP_ADD_INCLUDE($PHP_PSI_SRCDIR/src) PHP_ADD_BUILD_DIR($PHP_PSI_BUILDDIR/src) - PHP_PSI_HEADERS=`(cd $PHP_PSI_SRCDIR/src && echo *.h)` - PHP_PSI_SOURCES= # parser* should come first - PHP_PSI_SOURCES="$PHP_PSI_SOURCES src/parser_proc.c src/parser.c" - PHP_PSI_SOURCES="$PHP_PSI_SOURCES src/libjit.c src/libffi.c src/engine.c" - PHP_PSI_SOURCES="$PHP_PSI_SOURCES src/marshal.c src/calc.c src/module.c" - PHP_PSI_SOURCES="$PHP_PSI_SOURCES `(cd $PHP_PSI_SRCDIR && echo src/context*.c)`" + PHP_PSI_HEADERS=`(cd $PHP_PSI_SRCDIR/src && ls *.h types/*.h)` + # parser* should come first + PHP_PSI_SOURCES=" \ + src/parser_proc.c \ + src/parser.c \ + `(cd $PHP_PSI_SRCDIR && ls src/*.c | $EGREP -v '^src/parser')` \ + " PHP_NEW_EXTENSION(psi, $PHP_PSI_SOURCES, $ext_shared) PHP_INSTALL_HEADERS(ext/psi, php_psi.h $PHP_PSI_HEADERS) diff --git a/php_psi.h b/php_psi.h index 3d68d58..84dc1b7 100644 --- a/php_psi.h +++ b/php_psi.h @@ -20,7 +20,7 @@ extern zend_module_entry psi_module_entry; #include "context.h" -void psi_error_wrapper(void *context, PSI_Token *t, int type, const char *msg, ...); +void psi_error_wrapper(void *context, struct psi_token *t, int type, const char *msg, ...); void psi_error(int type, const char *fn, unsigned ln, const char *msg, ...); void psi_verror(int type, const char *fn, unsigned ln, const char *msg, va_list argv); @@ -47,7 +47,7 @@ PHP_PSI_API zend_class_entry *psi_object_get_class_entry(); ZEND_BEGIN_MODULE_GLOBALS(psi) char *engine; char *directory; - PSI_Context context; + struct psi_context context; ZEND_END_MODULE_GLOBALS(psi); ZEND_EXTERN_MODULE_GLOBALS(psi); diff --git a/src/context.c b/src/context.c index 5585dfe..805309d 100644 --- a/src/context.c +++ b/src/context.c @@ -25,13 +25,15 @@ #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" @@ -39,9 +41,9 @@ #include "php_psi_structs.h" #include "php_psi_unions.h" -PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error, unsigned flags) +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; @@ -165,11 +167,11 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr predef_decl = farg; } - PSI_ContextValidateData(PSI_DATA(C), &T); + 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; } @@ -182,7 +184,7 @@ 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; char *sep = NULL, *cpy = strdup(paths), *ptr = cpy; @@ -201,28 +203,28 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths) 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(C, NULL, PSI_WARNING, "Path to PSI file too long: %s/%s", ptr, entries[i]->d_name); } - if (!PSI_ParserInit(&P, psi, C->error, C->flags)) { + 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); } } @@ -237,7 +239,7 @@ 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)) { + 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!"); } @@ -245,7 +247,7 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths) } -zend_function_entry *PSI_ContextCompile(PSI_Context *C) +zend_function_entry *psi_context_compile(struct psi_context *C) { size_t i; zend_constant zc; @@ -295,13 +297,13 @@ zend_function_entry *PSI_ContextCompile(PSI_Context *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; @@ -314,7 +316,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); } @@ -372,10 +374,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; } diff --git a/src/context.h b/src/context.h index 6de7389..d2ff1b3 100644 --- a/src/context.h +++ b/src/context.h @@ -1,39 +1,43 @@ #ifndef _PSI_CONTEXT_H #define _PSI_CONTEXT_H -#include "parser.h" +struct psi_context; +struct psi_token; +struct psi_parser; +struct decl_callinfo; +struct impl_vararg; #define PSI_ERROR 16 #define PSI_WARNING 32 -typedef void (*PSI_ContextErrorFunc)(void *context, PSI_Token *token, int type, const char *msg, ...); +typedef void (*psi_context_error_func)(void *context, struct psi_token *token, int type, const char *msg, ...); -typedef struct PSI_Context PSI_Context; -typedef struct PSI_ContextOps PSI_ContextOps; -struct PSI_ContextOps { - void (*init)(PSI_Context *C); - void (*dtor)(PSI_Context *C); - zend_function_entry *(*compile)(PSI_Context *C); - void (*call)(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va); +struct psi_context_ops { + void (*init)(struct psi_context *C); + void (*dtor)(struct psi_context *C); + zend_function_entry *(*compile)(struct psi_context *C); + void (*call)(struct psi_context *C, struct decl_callinfo *decl_call, struct impl_vararg *va); }; -struct PSI_Context { +#include "data.h" + +struct psi_context { PSI_DATA_MEMBERS; void *context; - struct PSI_ContextOps *ops; + struct psi_context_ops *ops; zend_function_entry *closures; - PSI_Data *data; + struct psi_data *data; size_t count; }; -PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErrorFunc error, unsigned flags); -void PSI_ContextBuild(PSI_Context *C, const char *path); -int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P); -int PSI_ContextValidateData(PSI_Data *C, PSI_Data *D); -zend_function_entry *PSI_ContextCompile(PSI_Context *C); -void PSI_ContextCall(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va); -void PSI_ContextDump(PSI_Context *C, int fd); -void PSI_ContextDtor(PSI_Context *C); -void PSI_ContextFree(PSI_Context **C); +struct psi_context *psi_context_init(struct psi_context *C, struct psi_context_ops *ops, psi_context_error_func error, unsigned flags); +void psi_context_build(struct psi_context *C, const char *path); +int psi_context_validate(struct psi_context *C, struct psi_parser *P); +int psi_context_validate_data(struct psi_data *C, struct psi_data *D); +zend_function_entry *psi_context_compile(struct psi_context *C); +void psi_context_call(struct psi_context *C, struct decl_callinfo *decl_call, struct impl_vararg *va); +void psi_context_dump(struct psi_context *C, int fd); +void psi_context_dtor(struct psi_context *C); +void psi_context_free(struct psi_context **C); #endif diff --git a/src/context_dump.c b/src/context_dump.c index f138671..1f40e4f 100644 --- a/src/context_dump.c +++ b/src/context_dump.c @@ -1,6 +1,12 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "php.h" #include "php_psi.h" +#include "types.h" + #include "libjit.h" #include "libffi.h" @@ -497,15 +503,15 @@ static inline void dump_impls(int fd, impls *impls) { } } -void PSI_ContextDump(PSI_Context *C, int fd) +void psi_context_dump(struct psi_context *C, int fd) { #ifdef HAVE_LIBJIT - if (C->ops == PSI_Libjit()) { + if (C->ops == psi_libjit_ops()) { dprintf(fd, "// psi.engine=jit\n"); } #endif #ifdef HAVE_LIBFFI - if (C->ops == PSI_Libffi()) { + if (C->ops == psi_libffi_ops()) { dprintf(fd, "// psi.engine=ffi\n"); } #endif diff --git a/src/context_validate.c b/src/context_validate.c index f088b59..8add34d 100644 --- a/src/context_validate.c +++ b/src/context_validate.c @@ -18,7 +18,7 @@ #include "marshal.h" #include "engine.h" -static int validate_lib(PSI_Data *data, void **dlopened) { +static int validate_lib(struct psi_data *data, void **dlopened) { char lib[MAXPATHLEN]; const char *ptr = data->psi.file.ln; size_t len; @@ -128,12 +128,12 @@ static inline int locate_decl_type_decl(decls *decls, decl_type *type) { return 0; } -static inline int validate_decl_nodl(PSI_Data *data, decl *decl); -static inline int validate_decl_struct(PSI_Data *data, decl_struct *s); -static inline int validate_decl_union(PSI_Data *data, decl_union *u); -static inline int validate_decl_enum(PSI_Data *data, decl_enum *e); +static inline int validate_decl_nodl(struct psi_data *data, decl *decl); +static inline int validate_decl_struct(struct psi_data *data, decl_struct *s); +static inline int validate_decl_union(struct psi_data *data, decl_union *u); +static inline int validate_decl_enum(struct psi_data *data, decl_enum *e); -static inline int validate_decl_type(PSI_Data *data, decl_type *type, decl_arg *def) { +static inline int validate_decl_type(struct psi_data *data, decl_type *type, decl_arg *def) { if (weak_decl_type(type)) { if (!locate_decl_type_alias(data->defs, type)) { return 0; @@ -171,7 +171,7 @@ static inline int validate_decl_type(PSI_Data *data, decl_type *type, decl_arg * } return 1; } -static inline int validate_decl_typedef(PSI_Data *data, decl_arg *def) { +static inline int validate_decl_typedef(struct psi_data *data, decl_arg *def) { if (!validate_decl_type(data, def->type, def)) { const char *pre; @@ -199,12 +199,12 @@ static inline int validate_decl_typedef(PSI_Data *data, decl_arg *def) { return 1; } -static inline int validate_constant(PSI_Data *data, constant *c) { +static inline int validate_constant(struct psi_data *data, constant *c) { /* FIXME */ return 1; } -static inline int validate_decl_arg(PSI_Data *data, decl_arg *arg) { +static inline int validate_decl_arg(struct psi_data *data, decl_arg *arg) { if (!validate_decl_type(data, arg->type, NULL)) { data->error(data, arg->type->token, PSI_WARNING, "Cannot use '%s' as type for '%s'", @@ -243,7 +243,7 @@ static inline void psi_sort_struct_args(void **args, size_t count) { psi_sort_struct_arg_cmp, psi_sort_struct_arg_swp); } -static inline int validate_decl_struct_darg(PSI_Data *data, decl_arg *darg, void *current) { +static inline int validate_decl_struct_darg(struct psi_data *data, decl_arg *darg, void *current) { decl_type *real = real_decl_type(darg->type); /* pre-validate any structs/unions/enums */ @@ -394,7 +394,7 @@ static inline size_t align_decl_arg(decl_arg *darg, size_t *pos, size_t *len) { return align; } -static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) { +static inline int validate_decl_struct(struct psi_data *data, decl_struct *s) { size_t i, pos, len, size, align; if (!s->size && !s->args->count) { @@ -465,7 +465,7 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) { return 1; } -static inline int validate_decl_union(PSI_Data *data, decl_union *u) { +static inline int validate_decl_union(struct psi_data *data, decl_union *u) { size_t i, pos, len, size = 0, align; if (!u->size && !u->args->count) { @@ -537,7 +537,7 @@ static const char * const abi_ccs[] = { "stdcall", "fastcall", }; -static inline int validate_decl_abi(PSI_Data *data, decl_abi *abi) { +static inline int validate_decl_abi(struct psi_data *data, decl_abi *abi) { size_t i; for (i = 0; i < sizeof(abi_ccs)/sizeof(char*); ++i) { @@ -547,7 +547,7 @@ static inline int validate_decl_abi(PSI_Data *data, decl_abi *abi) { } return 0; } -static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_arg *func) +static inline int validate_decl_func(struct psi_data *data, void *dl, decl *decl, decl_arg *func) { struct psi_func_redir *redir; @@ -574,7 +574,7 @@ static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_ } return 1; } -static inline int validate_decl_nodl(PSI_Data *data, decl *decl) { +static inline int validate_decl_nodl(struct psi_data *data, decl *decl) { if (!validate_decl_abi(data, decl->abi)) { data->error(data, decl->abi->token, PSI_WARNING, "Invalid calling convention: '%s'", decl->abi->token->text); @@ -594,7 +594,7 @@ static inline int validate_decl_nodl(PSI_Data *data, decl *decl) { } return 1; } -static inline int validate_decl(PSI_Data *data, void *dl, decl *decl) { +static inline int validate_decl(struct psi_data *data, void *dl, decl *decl) { if (!validate_decl_nodl(data, decl)) { return 0; } @@ -669,7 +669,7 @@ static inline decl_enum_item *locate_num_exp_enum_item(num_exp *exp, decl_enums } return NULL; } -static inline int validate_num_exp(PSI_Data *data, num_exp *exp, decl_args *dargs, decl_arg *func, decl_enum *enm) { +static inline int validate_num_exp(struct psi_data *data, num_exp *exp, decl_args *dargs, decl_arg *func, decl_enum *enm) { if (exp->operand) { switch (exp->operator) { case PSI_T_PLUS: @@ -715,7 +715,7 @@ static inline int validate_num_exp(PSI_Data *data, num_exp *exp, decl_args *darg } } -static inline int validate_decl_enum(PSI_Data *data, decl_enum *e) { +static inline int validate_decl_enum(struct psi_data *data, decl_enum *e) { size_t j; if (!e->items || !e->items->count) { @@ -782,7 +782,7 @@ static inline void decl_var_arg_v(decl_args *args, va_list argp) { } } } -static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg *ref, decl_args *ref_list) { +static inline int validate_set_value_ex(struct psi_data *data, set_value *set, decl_arg *ref, decl_args *ref_list) { size_t i; decl_type *ref_type; decl_var *set_var = set->vars->vars[0]; @@ -856,7 +856,7 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg return 1; } -static inline int validate_set_value(PSI_Data *data, set_value *set, ...) { +static inline int validate_set_value(struct psi_data *data, set_value *set, ...) { va_list argp; decl_args args = {0}; int check; @@ -885,7 +885,7 @@ static inline decl *locate_impl_decl(decls *decls, return_stmt *ret) { return NULL; } -static inline int validate_impl_ret_stmt(PSI_Data *data, impl *impl) { +static inline int validate_impl_ret_stmt(struct psi_data *data, impl *impl) { return_stmt *ret; /* we must have exactly one ret stmt delcaring the native func to call */ @@ -936,7 +936,7 @@ static inline impl_arg *locate_impl_var_arg(impl_var *var, impl_args *args) { return NULL; } -static inline int validate_let_func(PSI_Data *data, let_func *func, impl *impl) { +static inline int validate_let_func(struct psi_data *data, let_func *func, impl *impl) { if (impl->func->args) { if (!locate_impl_var_arg(func->var, impl->func->args)) { data->error(data, func->var->token, PSI_WARNING, @@ -961,7 +961,7 @@ static inline int validate_let_func(PSI_Data *data, let_func *func, impl *impl) return 1; } -static inline int validate_let_callback(PSI_Data *data, decl_var *cb_var, let_callback *cb, impl *impl) { +static inline int validate_let_callback(struct psi_data *data, decl_var *cb_var, let_callback *cb, impl *impl) { size_t i; decl *cb_func; decl_type *cb_type = real_decl_type(cb_var->arg->type); @@ -990,7 +990,7 @@ static inline int validate_let_callback(PSI_Data *data, decl_var *cb_var, let_ca return 1; } -static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) { +static inline int validate_impl_let_stmts(struct psi_data *data, impl *impl) { size_t i, j; /* we can have multiple let stmts */ @@ -1078,7 +1078,7 @@ static inline int validate_impl_let_stmts(PSI_Data *data, impl *impl) { return 1; } -static inline int validate_impl_set_stmts(PSI_Data *data, impl *impl) { +static inline int validate_impl_set_stmts(struct psi_data *data, impl *impl) { size_t i, j, k; /* we can have any count of set stmts; processing out vars */ /* check that set stmts reference known variables */ @@ -1162,7 +1162,7 @@ static inline decl *locate_free_decl(decls *decls, free_call *f) { return NULL; } -static inline int validate_impl_free_stmts(PSI_Data *data, impl *impl) { +static inline int validate_impl_free_stmts(struct psi_data *data, impl *impl) { size_t i, j, k, l; /* we can have any count of free stmts; freeing any out vars */ for (i = 0; i < impl->stmts->fre.count; ++i) { @@ -1214,7 +1214,7 @@ static inline int validate_impl_free_stmts(PSI_Data *data, impl *impl) { } return 1; } -static inline int validate_impl_stmts(PSI_Data *data, impl *impl) { +static inline int validate_impl_stmts(struct psi_data *data, impl *impl) { if (!impl->stmts) { data->error(data, impl->func->token, PSI_WARNING, "Missing body for implementation %s!", @@ -1239,7 +1239,7 @@ static inline int validate_impl_stmts(PSI_Data *data, impl *impl) { return 1; } -static inline int validate_impl_args(PSI_Data *data, impl *impl) { +static inline int validate_impl_args(struct psi_data *data, impl *impl) { int def = 0; size_t i; @@ -1260,7 +1260,7 @@ static inline int validate_impl_args(PSI_Data *data, impl *impl) { return 1; } -static inline int validate_impl(PSI_Data *data, impl *impl) { +static inline int validate_impl(struct psi_data *data, impl *impl) { if (!validate_impl_args(data, impl)) { return 0; } @@ -1268,9 +1268,9 @@ static inline int validate_impl(PSI_Data *data, impl *impl) { } -int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) +int psi_context_validate(struct psi_context *C, struct psi_parser *P) { - PSI_Data *D; + struct psi_data *D; void *dlopened = NULL; size_t i, count = C->count++, check_round, check_count; decl_typedefs *check_defs = P->defs; @@ -1280,7 +1280,7 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) unsigned silent = C->flags & PSI_PARSER_SILENT; C->data = realloc(C->data, C->count * sizeof(*C->data)); - D = PSI_DataExchange(&C->data[count], PSI_DATA(P)); + D = psi_data_exchange(&C->data[count], PSI_DATA(P)); #define REVALIDATE(what) do { \ if (check_round && check_ ##what) { \ @@ -1376,7 +1376,7 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) return 1; } -int PSI_ContextValidateData(PSI_Data *dest, PSI_Data *source) +int psi_context_validate_data(struct psi_data *dest, struct psi_data *source) { size_t i; int errors = 0; diff --git a/src/data.c b/src/data.c new file mode 100644 index 0000000..860387d --- /dev/null +++ b/src/data.c @@ -0,0 +1,44 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# include "php_config.h" +#endif + +#include + +#include "data.h" + +struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src) { + if (!dest) { + dest = malloc(sizeof(*dest)); + } + memcpy(dest, src, sizeof(*dest)); + memset(src, 0, sizeof(*src)); + return dest; +} + +void psi_data_dtor(struct psi_data *data) { + if (data->consts) { + free_constants(data->consts); + } + if (data->defs) { + free_decl_typedefs(data->defs); + } + if (data->structs) { + free_decl_structs(data->structs); + } + if (data->unions) { + free_decl_unions(data->unions); + } + if (data->enums) { + free_decl_enums(data->enums); + } + if (data->decls) { + free_decls(data->decls); + } + if (data->impls) { + free_impls(data->impls); + } + free_decl_file(&data->psi.file); +} + diff --git a/src/data.h b/src/data.h new file mode 100644 index 0000000..cc497fb --- /dev/null +++ b/src/data.h @@ -0,0 +1,31 @@ +#ifndef _PSI_DATA_H +#define _PSI_DATA_H + +#include "types.h" + +#define PSI_DATA(D) ((struct psi_data *) (D)) + +#define PSI_DATA_MEMBERS \ + constants *consts; \ + decl_typedefs *defs; \ + decl_structs *structs; \ + decl_unions *unions; \ + decl_enums *enums; \ + decls *decls; \ + impls *impls; \ + union { \ + decl_file file; \ + decl_libs libs; \ + } psi; \ + psi_error_cb error; \ + unsigned errors; \ + unsigned flags + +struct psi_data { + PSI_DATA_MEMBERS; +}; + +struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src); +void psi_data_dtor(struct psi_data *data); + +#endif diff --git a/src/engine.c b/src/engine.c index a4bf0d7..38cdb0e 100644 --- a/src/engine.c +++ b/src/engine.c @@ -12,57 +12,6 @@ #include "calc.h" #include "marshal.h" -size_t psi_t_alignment(token_t t) -{ -#define PSI_ALIGNOF(T) case PSI_T_## T: return ALIGNOF_## T ##_T; - switch (t) { - PSI_ALIGNOF(INT8); - PSI_ALIGNOF(UINT8); - PSI_ALIGNOF(INT16); - PSI_ALIGNOF(UINT16); - PSI_ALIGNOF(INT32); - PSI_ALIGNOF(UINT32); - PSI_ALIGNOF(INT64); - PSI_ALIGNOF(UINT64); - case PSI_T_FLOAT: - return ALIGNOF_FLOAT; - case PSI_T_DOUBLE: - return ALIGNOF_DOUBLE; - case PSI_T_POINTER: - case PSI_T_FUNCTION: - return ALIGNOF_VOID_P; - case PSI_T_ENUM: - return ALIGNOF_INT; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return 0; -} - -size_t psi_t_size(token_t t) -{ -#define PSI_SIZEOF(T) case PSI_T_## T : return SIZEOF_## T ##_T; - switch (t) { - PSI_SIZEOF(INT8); - PSI_SIZEOF(UINT8); - PSI_SIZEOF(INT16); - PSI_SIZEOF(UINT16); - PSI_SIZEOF(INT32); - PSI_SIZEOF(UINT32); - PSI_SIZEOF(INT64); - PSI_SIZEOF(UINT64); - case PSI_T_FLOAT: - return SIZEOF_FLOAT; - case PSI_T_DOUBLE: - return SIZEOF_DOUBLE; - case PSI_T_POINTER: - case PSI_T_FUNCTION: - return SIZEOF_VOID_P; - case PSI_T_ENUM: - return SIZEOF_INT; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return 0; -} int psi_internal_type(impl_type *type) { @@ -329,7 +278,7 @@ static inline void psi_do_free(free_stmt *fre) } /* FIXME: check in validate_* that free functions return scalar */ - PSI_ContextCall(&PSI_G(context), &f->decl->call, NULL); + psi_context_call(&PSI_G(context), &f->decl->call, NULL); } } @@ -520,7 +469,7 @@ ZEND_RESULT_CODE psi_call(zend_execute_data *execute_data, zval *return_value, i } } - PSI_ContextCall(&PSI_G(context), &impl->decl->call, va); + psi_context_call(&PSI_G(context), &impl->decl->call, va); psi_do_return(return_value, impl->stmts->ret.list[0]); for (i = 0; i < impl->stmts->set.count; ++i) { diff --git a/src/engine.h b/src/engine.h index 3aa78a4..e8d86ff 100644 --- a/src/engine.h +++ b/src/engine.h @@ -1,9 +1,6 @@ #ifndef _PSI_ENGINE_H #define _PSI_ENGINE_H -size_t psi_t_alignment(token_t t); -size_t psi_t_size(token_t t); - static inline size_t psi_align(size_t s, size_t a) { return ((s - 1) | (a - 1)) + 1; } diff --git a/src/libffi.c b/src/libffi.c index 627c97f..2dbe0bc 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -7,7 +7,7 @@ #ifdef HAVE_LIBFFI #include "php_psi.h" -#include "libffi.h" +#include "ffi.h" #include "engine.h" #undef PACKAGE @@ -83,26 +83,26 @@ static void psi_ffi_callback(ffi_cif *_sig, void *_result, void **_args, void *_ static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg); -typedef struct PSI_LibffiContext { +struct psi_ffi_context { ffi_cif signature; ffi_type *params[2]; -} PSI_LibffiContext; +}; -typedef struct PSI_LibffiCall { +struct psi_ffi_call { void *code; ffi_closure *closure; ffi_cif signature; void *params[1]; /* [type1, type2, NULL, arg1, arg2] ... */ -} PSI_LibffiCall; +}; static inline ffi_abi psi_ffi_abi(const char *convention) { return FFI_DEFAULT_ABI; } -static inline PSI_LibffiCall *PSI_LibffiCallAlloc(PSI_Context *C, decl *decl) { +static inline struct psi_ffi_call *psi_ffi_call_alloc(struct psi_context *C, decl *decl) { int rc; size_t i, c = decl->args ? decl->args->count : 0; - PSI_LibffiCall *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *)); + struct psi_ffi_call *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *)); for (i = 0; i < c; ++i) { call->params[i] = psi_ffi_decl_arg_type(decl->args->args[i]); @@ -121,17 +121,17 @@ static inline PSI_LibffiCall *PSI_LibffiCallAlloc(PSI_Context *C, decl *decl) { return call; } -static inline ffi_status PSI_LibffiCallInitClosure(PSI_Context *C, PSI_LibffiCall *call, impl *impl) { - PSI_LibffiContext *context = C->context; +static inline ffi_status psi_ffi_call_init_closure(struct psi_context *C, struct psi_ffi_call *call, impl *impl) { + struct psi_ffi_context *context = C->context; return psi_ffi_prep_closure(&call->closure, &call->code, &context->signature, psi_ffi_handler, impl); } -static inline ffi_status PSI_LibffiCallInitCallbackClosure(PSI_Context *C, PSI_LibffiCall *call, let_callback *cb) { +static inline ffi_status psi_ffi_call_init_callback_closure(struct psi_context *C, struct psi_ffi_call *call, let_callback *cb) { return psi_ffi_prep_closure(&call->closure, &call->code, &call->signature, psi_ffi_callback, cb); } -static inline void PSI_LibffiCallFree(PSI_LibffiCall *call) { +static inline void psi_ffi_call_free(struct psi_ffi_call *call) { if (call->closure) { psi_ffi_closure_free(call->closure); } @@ -300,7 +300,7 @@ static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg) { } -static inline PSI_LibffiContext *PSI_LibffiContextInit(PSI_LibffiContext *L) { +static inline struct psi_ffi_context *psi_ffi_context_init(struct psi_ffi_context *L) { ffi_status rc; if (!L) { @@ -316,19 +316,19 @@ static inline PSI_LibffiContext *PSI_LibffiContextInit(PSI_LibffiContext *L) { return L; } -static inline void PSI_LibffiContextFree(PSI_LibffiContext **L) { +static inline void psi_ffi_context_free(struct psi_ffi_context **L) { if (*L) { free(*L); *L = NULL; } } -static void psi_ffi_init(PSI_Context *C) +static void psi_ffi_init(struct psi_context *C) { - C->context = PSI_LibffiContextInit(NULL); + C->context = psi_ffi_context_init(NULL); } -static void psi_ffi_dtor(PSI_Context *C) +static void psi_ffi_dtor(struct psi_context *C) { if (C->decls) { size_t i; @@ -337,7 +337,7 @@ static void psi_ffi_dtor(PSI_Context *C) decl *decl = C->decls->list[i]; if (decl->call.info) { - PSI_LibffiCallFree(decl->call.info); + psi_ffi_call_free(decl->call.info); } } @@ -355,16 +355,16 @@ static void psi_ffi_dtor(PSI_Context *C) let_callback *cb = let->val->data.callback; if (cb->decl && cb->decl->call.info) { - PSI_LibffiCallFree(cb->decl->call.info); + psi_ffi_call_free(cb->decl->call.info); } } } } } - PSI_LibffiContextFree((void *) &C->context); + psi_ffi_context_free((void *) &C->context); } -static zend_function_entry *psi_ffi_compile(PSI_Context *C) +static zend_function_entry *psi_ffi_compile(struct psi_context *C) { size_t c, i, j = 0; zend_function_entry *zfe; @@ -376,16 +376,16 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C) zfe = calloc(C->impls->count + 1, sizeof(*zfe)); for (i = 0; i < C->impls->count; ++i) { zend_function_entry *zf = &zfe[j]; - PSI_LibffiCall *call; + struct psi_ffi_call *call; impl *impl = C->impls->list[i]; if (!impl->decl) { continue; } - if ((call = PSI_LibffiCallAlloc(C, impl->decl))) { - if (FFI_OK != PSI_LibffiCallInitClosure(C, call, impl)) { - PSI_LibffiCallFree(call); + if ((call = psi_ffi_call_alloc(C, impl->decl))) { + if (FFI_OK != psi_ffi_call_init_closure(C, call, impl)) { + psi_ffi_call_free(call); continue; } } @@ -402,9 +402,9 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C) if (let->val && let->val->kind == PSI_LET_CALLBACK) { let_callback *cb = let->val->data.callback; - if ((call = PSI_LibffiCallAlloc(C, cb->decl))) { - if (FFI_OK != PSI_LibffiCallInitCallbackClosure(C, call, cb)) { - PSI_LibffiCallFree(call); + if ((call = psi_ffi_call_alloc(C, cb->decl))) { + if (FFI_OK != psi_ffi_call_init_callback_closure(C, call, cb)) { + psi_ffi_call_free(call); continue; } @@ -421,14 +421,14 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C) continue; } - PSI_LibffiCallAlloc(C, decl); + psi_ffi_call_alloc(C, decl); } return zfe; } -static void psi_ffi_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va) { - PSI_LibffiCall *call = decl_call->info; +static void psi_ffi_call(struct psi_context *C, decl_callinfo *decl_call, impl_vararg *va) { + struct psi_ffi_call *call = decl_call->info; if (va) { ffi_status rc; @@ -461,14 +461,14 @@ static void psi_ffi_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg * } } -static PSI_ContextOps ops = { +static struct psi_context_ops ops = { psi_ffi_init, psi_ffi_dtor, psi_ffi_compile, psi_ffi_call, }; -PSI_ContextOps *PSI_Libffi(void) +struct psi_context_ops *psi_libffi_ops(void) { return &ops; } diff --git a/src/libffi.h b/src/libffi.h index 4b36b30..8db73ee 100644 --- a/src/libffi.h +++ b/src/libffi.h @@ -4,7 +4,7 @@ #include "context.h" #ifdef HAVE_LIBFFI -PSI_ContextOps *PSI_Libffi(void); +struct psi_context_ops *psi_libffi_ops(void); #endif #endif diff --git a/src/libjit.c b/src/libjit.c index 62540cc..b6022c5 100644 --- a/src/libjit.c +++ b/src/libjit.c @@ -175,30 +175,30 @@ static inline jit_type_t psi_jit_decl_arg_type(decl_arg *darg) { } } -typedef struct PSI_LibjitContext { +struct psi_jit_context { jit_context_t jit; jit_type_t signature; struct { - struct PSI_LibjitData **list; + struct psi_jit_data **list; size_t count; } data; -} PSI_LibjitContext; +}; -typedef struct PSI_LibjitCall { +struct psi_jit_call { void *closure; jit_type_t signature; void *params[1]; /* [type1, type2, NULL, arg1, arg2] ... */ -} PSI_LibjitCall; +}; -typedef struct PSI_LibjitData { - PSI_LibjitContext *context; +struct psi_jit_data { + struct psi_jit_context *context; impl *impl; zend_internal_arg_info *arginfo; -} PSI_LibjitData; +}; -static inline PSI_LibjitCall *PSI_LibjitCallAlloc(PSI_Context *C, decl *decl) { +static inline struct psi_jit_call *psi_jit_call_alloc(struct psi_context *C, decl *decl) { size_t i, c = decl->args ? decl->args->count : 0; - PSI_LibjitCall *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *)); + struct psi_jit_call *call = calloc(1, sizeof(*call) + 2 * c * sizeof(void *)); for (i = 0; i < c; ++i) { call->params[i] = psi_jit_decl_arg_type(decl->args->args[i]); @@ -219,24 +219,24 @@ static inline PSI_LibjitCall *PSI_LibjitCallAlloc(PSI_Context *C, decl *decl) { return call; } -static inline void *PSI_LibjitCallInitClosure(PSI_Context *C, PSI_LibjitCall *call, impl *impl) { - PSI_LibjitContext *context = C->context; +static inline void *psi_jit_call_init_closure(struct psi_context *C, struct psi_jit_call *call, impl *impl) { + struct psi_jit_context *context = C->context; return call->closure = jit_closure_create(context->jit, context->signature, &psi_jit_handler, impl); } -static inline void *PSI_LibjitCallInitCallbackClosure(PSI_Context *C, PSI_LibjitCall *call, let_callback *cb) { - PSI_LibjitContext *context = C->context; +static inline void *psi_jit_call_init_callback_closure(struct psi_context *C, struct psi_jit_call *call, let_callback *cb) { + struct psi_jit_context *context = C->context; return call->closure = jit_closure_create(context->jit, call->signature, &psi_jit_callback, cb); } -static inline void PSI_LibjitCallFree(PSI_LibjitCall *call) { +static inline void psi_jit_call_free(struct psi_jit_call *call) { jit_type_free(call->signature); free(call); } -static inline PSI_LibjitContext *PSI_LibjitContextInit(PSI_LibjitContext *L) { +static inline struct psi_jit_context *psi_jit_context_init(struct psi_jit_context *L) { jit_type_t params[] = { jit_type_void_ptr, jit_type_void_ptr @@ -254,25 +254,25 @@ static inline PSI_LibjitContext *PSI_LibjitContextInit(PSI_LibjitContext *L) { return L; } -static inline void PSI_LibjitContextDtor(PSI_LibjitContext *L) { +static inline void psi_jit_context_dtor(struct psi_jit_context *L) { jit_type_free(L->signature); jit_context_destroy(L->jit); } -static inline void PSI_LibjitContextFree(PSI_LibjitContext **L) { +static inline void psi_jit_context_free(struct psi_jit_context **L) { if (*L) { - PSI_LibjitContextDtor(*L); + psi_jit_context_dtor(*L); free(*L); *L = NULL; } } -static void psi_jit_init(PSI_Context *C) +static void psi_jit_init(struct psi_context *C) { - C->context = PSI_LibjitContextInit(NULL); + C->context = psi_jit_context_init(NULL); } -static void psi_jit_dtor(PSI_Context *C) +static void psi_jit_dtor(struct psi_context *C) { if (C->decls) { size_t i; @@ -281,7 +281,7 @@ static void psi_jit_dtor(PSI_Context *C) decl *decl = C->decls->list[i]; if (decl->call.info) { - PSI_LibjitCallFree(decl->call.info); + psi_jit_call_free(decl->call.info); } } } @@ -298,20 +298,20 @@ static void psi_jit_dtor(PSI_Context *C) let_callback *cb = let->val->data.callback; if (cb->decl && cb->decl->call.info) { - PSI_LibjitCallFree(cb->decl->call.info); + psi_jit_call_free(cb->decl->call.info); } } } } } - PSI_LibjitContextFree((void *) &C->context); + psi_jit_context_free((void *) &C->context); } -static zend_function_entry *psi_jit_compile(PSI_Context *C) +static zend_function_entry *psi_jit_compile(struct psi_context *C) { size_t c, i, j = 0; zend_function_entry *zfe; - PSI_LibjitContext *ctx = C->context; + struct psi_jit_context *ctx = C->context; if (!C->impls) { return NULL; @@ -322,16 +322,16 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C) for (i = 0; i < C->impls->count; ++i) { zend_function_entry *zf = &zfe[j]; - PSI_LibjitCall *call; + struct psi_jit_call *call; impl *impl = C->impls->list[i]; if (!impl->decl) { continue; } - if ((call = PSI_LibjitCallAlloc(C, impl->decl))) { - if (!PSI_LibjitCallInitClosure(C, call, impl)) { - PSI_LibjitCallFree(call); + if ((call = psi_jit_call_alloc(C, impl->decl))) { + if (!psi_jit_call_init_closure(C, call, impl)) { + psi_jit_call_free(call); continue; } } @@ -348,9 +348,9 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C) if (let->val && let->val->kind == PSI_LET_CALLBACK) { let_callback *cb = let->val->data.callback; - if ((call = PSI_LibjitCallAlloc(C, cb->decl))) { - if (!PSI_LibjitCallInitCallbackClosure(C, call, cb)) { - PSI_LibjitCallFree(call); + if ((call = psi_jit_call_alloc(C, cb->decl))) { + if (!psi_jit_call_init_callback_closure(C, call, cb)) { + psi_jit_call_free(call); continue; } @@ -367,7 +367,7 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C) continue; } - PSI_LibjitCallAlloc(C, decl); + psi_jit_call_alloc(C, decl); } jit_context_build_end(ctx->jit); @@ -375,8 +375,8 @@ static zend_function_entry *psi_jit_compile(PSI_Context *C) return zfe; } -static void psi_jit_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg *va) { - PSI_LibjitCall *call = decl_call->info; +static void psi_jit_call(struct psi_context *C, decl_callinfo *decl_call, impl_vararg *va) { + struct psi_jit_call *call = decl_call->info; if (va) { jit_type_t signature; @@ -408,14 +408,14 @@ static void psi_jit_call(PSI_Context *C, decl_callinfo *decl_call, impl_vararg * } } -static PSI_ContextOps ops = { +static struct psi_context_ops ops = { psi_jit_init, psi_jit_dtor, psi_jit_compile, psi_jit_call, }; -PSI_ContextOps *PSI_Libjit(void) +struct psi_context_ops *psi_libjit_ops(void) { return &ops; } diff --git a/src/libjit.h b/src/libjit.h index 3cd4b28..602fc51 100644 --- a/src/libjit.h +++ b/src/libjit.h @@ -4,7 +4,7 @@ #include "context.h" #ifdef HAVE_LIBJIT -PSI_ContextOps *PSI_Libjit(void); +struct psi_context_ops *psi_libjit_ops(void); #endif #endif diff --git a/src/module.c b/src/module.c index aff784d..33e3ae2 100644 --- a/src/module.c +++ b/src/module.c @@ -1,4 +1,3 @@ - #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -10,6 +9,8 @@ #include "zend_operators.h" #include "php_psi.h" +#include "token.h" +#include "parser.h" #if HAVE_LIBJIT # include "libjit.h" @@ -37,7 +38,7 @@ zend_class_entry *psi_object_get_class_entry() return psi_class_entry; } -void psi_error_wrapper(void *context, PSI_Token *t, int type, const char *msg, ...) +void psi_error_wrapper(void *context, struct psi_token *t, int type, const char *msg, ...) { va_list argv; const char *fn = NULL; @@ -119,7 +120,7 @@ static PHP_FUNCTION(psi_dump) { RETURN_FALSE; } } - PSI_ContextDump(&PSI_G(context), fd); + psi_context_dump(&PSI_G(context), fd); } ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate, 0, 0, 1) @@ -127,35 +128,35 @@ ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate, 0, 0, 1) ZEND_END_ARG_INFO(); static PHP_FUNCTION(psi_validate) { zend_string *file; - PSI_Parser P; + struct psi_parser P; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file)) { return; } - if (!PSI_ParserInit(&P, file->val, psi_error_wrapper, 0)) { + if (!psi_parser_init(&P, file->val, psi_error_wrapper, 0)) { RETURN_FALSE; } - 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_parser_parse(&P, NULL); - if (0 == PSI_ContextValidateData(NULL, PSI_DATA(&P)) && !P.errors) { + if (0 == psi_context_validate_data(NULL, PSI_DATA(&P)) && !P.errors) { RETVAL_TRUE; } else { RETVAL_FALSE; } - PSI_ParserDtor(&P); + psi_parser_dtor(&P); } static PHP_MINIT_FUNCTION(psi) { - PSI_ContextOps *ops = NULL; + struct psi_context_ops *ops = NULL; zend_class_entry ce = {0}; unsigned flags = psi_check_env("PSI_DEBUG") ? PSI_PARSER_DEBUG : ( psi_check_env("PSI_SILENT") ? PSI_PARSER_SILENT : 0); @@ -173,11 +174,11 @@ static PHP_MINIT_FUNCTION(psi) #ifdef HAVE_LIBJIT if (!strcasecmp(PSI_G(engine), "jit")) { - ops = PSI_Libjit(); + ops = psi_libjit_ops(); } else #endif #ifdef HAVE_LIBFFI - ops = PSI_Libffi(); + ops = psi_libffi_ops(); #endif if (!ops) { @@ -185,11 +186,11 @@ static PHP_MINIT_FUNCTION(psi) return FAILURE; } - PSI_ContextInit(&PSI_G(context), ops, psi_error_wrapper, flags); - PSI_ContextBuild(&PSI_G(context), PSI_G(directory)); + psi_context_init(&PSI_G(context), ops, psi_error_wrapper, flags); + psi_context_build(&PSI_G(context), PSI_G(directory)); if (psi_check_env("PSI_DUMP")) { - PSI_ContextDump(&PSI_G(context), STDOUT_FILENO); + psi_context_dump(&PSI_G(context), STDOUT_FILENO); } return SUCCESS; @@ -197,7 +198,7 @@ static PHP_MINIT_FUNCTION(psi) static PHP_MSHUTDOWN_FUNCTION(psi) { - PSI_ContextDtor(&PSI_G(context)); + psi_context_dtor(&PSI_G(context)); UNREGISTER_INI_ENTRIES(); diff --git a/src/parser.h b/src/parser.h index c99c266..5851ee6 100644 --- a/src/parser.h +++ b/src/parser.h @@ -6,1709 +6,32 @@ #include #include -#include -#include /* fcall */ - #include "parser_proc.h" #define BSIZE 256 -#define PSI_T_POINTER PSI_T_ASTERISK -#define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16) - -typedef int token_t; - -size_t psi_t_alignment(token_t); -size_t psi_t_size(token_t); - -typedef struct PSI_Token { - token_t type; - unsigned size, line, col; - char *text, *file; - char buf[1]; -} PSI_Token; - -static inline PSI_Token *PSI_TokenCopy(PSI_Token *src); - -typedef struct zend_fcall { - zend_fcall_info fci; - zend_fcall_info_cache fcc; -} zend_fcall; - -typedef union impl_val { - char cval; - int8_t i8; - uint8_t u8; - short sval; - int16_t i16; - uint16_t u16; - int ival; - int32_t i32; - uint32_t u32; - long lval; - int64_t i64; - uint64_t u64; - float fval; - double dval; -#ifdef HAVE_LONG_DOUBLE - long double ldval; -#endif - union { - zend_bool bval; - zend_long lval; - zend_string *str; - zend_fcall *cb; - } zend; - void *ptr; -} impl_val; - -typedef struct decl_type { - PSI_Token *token; - char *name; - token_t type; - union { - struct decl_arg *def; - struct decl_struct *strct; - struct decl_union *unn; - struct decl_enum *enm; - struct decl *func; - } real; -} decl_type; - -static inline decl_type *init_decl_type(token_t type, const char *name) { - decl_type *t = calloc(1, sizeof(*t)); - t->type = type; - t->name = strdup(name); - return t; -} - -static inline int weak_decl_type(decl_type *type) { - switch (type->type) { - case PSI_T_CHAR: - case PSI_T_SHORT: - case PSI_T_INT: - case PSI_T_LONG: - case PSI_T_NAME: - return type->type; - default: - return 0; - } -} - -static inline void free_decl(struct decl *decl); -static inline void free_decl_type(decl_type *type) { - if (type->token) { - free(type->token); - } - if (type->type == PSI_T_FUNCTION) { - free_decl(type->real.func); - } - free(type->name); - free(type); -} - -typedef struct decl_var { - PSI_Token *token; - char *name; - unsigned pointer_level; - unsigned array_size; - struct decl_arg *arg; -} decl_var; - -static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) { - decl_var *v = calloc(1, sizeof(*v)); - v->name = (char *) strdup((const char *) name); - v->pointer_level = pl; - v->array_size = as; - return v; -} - -static inline decl_var *copy_decl_var(decl_var *src) { - decl_var *dest = calloc(1, sizeof(*dest)); - - memcpy(dest, src, sizeof(*dest)); - dest->name = strdup(dest->name); - if (dest->token) { - dest->token = PSI_TokenCopy(dest->token); - } - return dest; -} - -static inline void free_decl_var(decl_var *var) { - if (var->token) { - free(var->token); - } - free(var->name); - free(var); -} - -typedef struct decl_struct_layout { - size_t pos; - size_t len; -} decl_struct_layout; - -static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) { - decl_struct_layout *l = calloc(1, sizeof(*l)); - ZEND_ASSERT(pos+len); - l->pos = pos; - l->len = len; - return l; -} - -static inline void free_decl_struct_layout(decl_struct_layout *l) { - free(l); -} - -typedef struct decl_arg { - PSI_Token *token; - decl_type *type; - decl_var *var; - decl_struct_layout *layout; - impl_val val; - void *ptr; - void *let; - void *mem; -} decl_arg; - -static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) { - decl_arg *arg = calloc(1, sizeof(*arg)); - arg->token = var->token; - arg->type = type; - arg->var = var; - var->arg = arg; - arg->ptr = &arg->val; - arg->let = arg->ptr; - return arg; -} - -static inline void free_decl_arg(decl_arg *arg) { - if (arg->token && arg->token != arg->var->token) { - free(arg->token); - } - free_decl_type(arg->type); - free_decl_var(arg->var); - if (arg->layout) { - free_decl_struct_layout(arg->layout); - } - free(arg); -} - -static inline decl_type *real_decl_type(decl_type *type) { - while (weak_decl_type(type)) { - type = type->real.def->type; - } - return type; -} - -typedef struct decl_typedefs { - size_t count; - decl_arg **list; -} decl_typedefs; - -static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_arg *def) { - if (!defs) { - defs = calloc(1, sizeof(*defs)); - } - defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list)); - defs->list[defs->count-1] = def; - return defs; -} - -static void free_decl_typedefs(decl_typedefs *defs) { - size_t i; - - for (i = 0; i < defs->count; ++i) { - free_decl_arg(defs->list[i]); - } - free(defs->list); - free(defs); -} - -typedef struct decl_vars { - decl_var **vars; - size_t count; -} decl_vars; - -static inline decl_vars *init_decl_vars(decl_var *var) { - decl_vars *vars = calloc(1, sizeof(*vars)); - if (var) { - vars->count = 1; - vars->vars = calloc(1, sizeof(*vars->vars)); - vars->vars[0] = var; - } - return vars; -} - -static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) { - vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars)); - vars->vars[vars->count-1] = var; - return vars; -} - -static inline void free_decl_vars(decl_vars *vars) { - size_t i; - - for (i = 0; i < vars->count; ++i) { - free_decl_var(vars->vars[i]); - } - free(vars->vars); - free(vars); -} - -typedef struct decl_args { - decl_arg **args; - size_t count; - unsigned varargs:1; -} decl_args; - -static inline decl_args *init_decl_args(decl_arg *arg) { - decl_args *args = calloc(1, sizeof(*args)); - if (arg) { - args->count = 1; - args->args = calloc(1, sizeof(*args->args)); - args->args[0] = arg; - } - return args; -} - -static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) { - args->args = realloc(args->args, ++args->count * sizeof(*args->args)); - args->args[args->count-1] = arg; - return args; -} - -static inline void free_decl_args(decl_args *args) { - size_t i; - - for (i = 0; i < args->count; ++i) { - free_decl_arg(args->args[i]); - } - free(args->args); - free(args); -} - -typedef struct decl_abi { - PSI_Token *token; - char *convention; -} decl_abi; - -static inline decl_abi *init_decl_abi(const char *convention) { - decl_abi *abi = calloc(1, sizeof(*abi)); - abi->convention = strdup(convention); - return abi; -} - -static inline void free_decl_abi(decl_abi *abi) { - if (abi->token) { - free(abi->token); - } - free(abi->convention); - free(abi); -} - -typedef struct decl_callinfo { - void *sym; - void *info; - size_t argc; - void **args; - void **rval; -} decl_callinfo; - -typedef struct decl { - decl_abi *abi; - decl_arg *func; - decl_args *args; - struct impl *impl; - decl_callinfo call; -} decl; - -static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) { - decl *d = calloc(1, sizeof(*d)); - d->abi = abi; - d->func = func; - d->args = args; - return d; -} - -static inline void free_decl(decl *d) { - free_decl_abi(d->abi); - free_decl_arg(d->func); - if (d->args) { - free_decl_args(d->args); - } - free(d); -} - -typedef struct decls { - size_t count; - decl **list; -} decls; - -static inline decls *add_decl(decls *decls, decl *decl) { - if (!decls) { - decls = calloc(1, sizeof(*decls)); - } - decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list)); - decls->list[decls->count-1] = decl; - return decls; -} - -static inline void free_decls(decls *decls) { - size_t i; - - for (i = 0; i < decls->count; ++i) { - free_decl(decls->list[i]); - } - free(decls->list); - free(decls); -} - - -typedef struct decl_struct { - PSI_Token *token; - char *name; - decl_args *args; - size_t size; - size_t align; - struct { - void *type; - void (*dtor)(void *type); - } engine; -} decl_struct; - -static inline decl_struct *init_decl_struct(const char *name, decl_args *args) { - decl_struct *s = calloc(1, sizeof(*s)); - s->name = strdup(name); - s->args = args; - return s; -} - -static inline void free_decl_struct(decl_struct *s) { - if (s->token) { - free(s->token); - } - if (s->args) { - free_decl_args(s->args); - } - if (s->engine.type && s->engine.dtor) { - s->engine.dtor(s->engine.type); - } - free(s->name); - free(s); -} - -typedef struct decl_structs { - size_t count; - decl_struct **list; -} decl_structs; - -static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) { - if (!ss) { - ss = calloc(1, sizeof(*ss)); - } - ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list)); - ss->list[ss->count-1] = s; - return ss; -} - -static inline void free_decl_structs(decl_structs *ss) { - size_t i; - - for (i = 0; i < ss->count; ++i) { - free_decl_struct(ss->list[i]); - } - free(ss->list); - free(ss); -} - -typedef struct decl_union { - PSI_Token *token; - char *name; - decl_args *args; - size_t size; - size_t align; -} decl_union; - -static inline decl_union *init_decl_union(const char *name, decl_args *args) { - decl_union *u = calloc(1, sizeof(*u)); - u->name = strdup(name); - u->args = args; - return u; -} - -static inline void free_decl_union(decl_union *u) { - if (u->token) { - free(u->token); - } - if (u->args) { - free_decl_args(u->args); - } - free(u->name); - free(u); -} - -typedef struct decl_unions { - decl_union **list; - size_t count; -} decl_unions; - -static inline decl_unions *add_decl_union(decl_unions *uu, decl_union *u) { - if (!uu) { - uu = calloc(1, sizeof(*uu)); - } - uu->list = realloc(uu->list, ++uu->count * sizeof(*uu->list)); - uu->list[uu->count-1] = u; - return uu; -} - -static inline void free_decl_unions(decl_unions *uu) { - size_t i; - - for (i = 0; i < uu->count; ++i) { - free_decl_union(uu->list[i]); - } - free(uu->list); - free(uu); -} - -typedef struct impl_type { - char *name; - token_t type; -} impl_type; - -static inline impl_type *init_impl_type(token_t type, const char *name) { - impl_type *t = calloc(1, sizeof(*t)); - - t->type = type; - t->name = strdup(name); - return t; -} - -static inline void free_impl_type(impl_type *type) { - free(type->name); - free(type); -} - -typedef struct impl_var { - PSI_Token *token; - char *name; - struct impl_arg *arg; - unsigned reference:1; -} impl_var; - -static inline impl_var *init_impl_var(const char *name, int is_reference) { - impl_var *var = calloc(1, sizeof(*var)); - var->name = strdup(name); - var->reference = is_reference; - return var; -} - -static inline impl_var *copy_impl_var(impl_var *var) { - impl_var *cpy = malloc(sizeof(*cpy)); - - memcpy(cpy, var, sizeof(*cpy)); - cpy->name = strdup(cpy->name); - if (cpy->token) { - cpy->token = PSI_TokenCopy(cpy->token); - } - return cpy; -} - -static inline void free_impl_var(impl_var *var) { - if (var->token) { - free(var->token); - } - free(var->name); - free(var); -} - -typedef struct impl_def_val { - token_t type; - char *text; -} impl_def_val; - -static inline impl_def_val *init_impl_def_val(token_t t, const char *text) { - impl_def_val *def = calloc(1, sizeof(*def)); - def->type = t; - def->text = strdup(text); - return def; -} - -static inline void free_impl_def_val(impl_def_val *def) { - free(def->text); - free(def); -} - -typedef struct const_type { - token_t type; - char *name; -} const_type; - -static inline const_type *init_const_type(token_t type, const char *name) { - const_type *ct = calloc(1, sizeof(*ct)); - ct->type = type; - ct->name = strdup(name); - return ct; -} - -static inline void free_const_type(const_type *type) { - free(type->name); - free(type); -} - -typedef struct constant { - const_type *type; - char *name; - impl_def_val *val; -} constant; - -static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) { - constant *c = calloc(1, sizeof(*c)); - c->type = type; - c->name = strdup(name); - c->val = val; - return c; -} - -static inline void free_constant(constant *constant) { - free_const_type(constant->type); - free(constant->name); - free_impl_def_val(constant->val); - free(constant); -} - -typedef struct constants { - size_t count; - constant **list; -} constants; - -static inline constants *add_constant(constants *constants, constant *constant) { - if (!constants) { - constants = calloc(1, sizeof(*constants)); - } - constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list)); - constants->list[constants->count-1] = constant; - return constants; -} - -static inline void free_constants(constants *c) { - size_t i; - - for (i = 0; i < c->count; ++i) { - free_constant(c->list[i]); - } - free(c->list); - free(c); -} - -typedef struct impl_arg { - impl_type *type; - impl_var *var; - impl_def_val *def; - impl_val val; - zval *_zv; -} impl_arg; - -static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) { - impl_arg *arg = calloc(1, sizeof(*arg)); - arg->type = type; - arg->var = var; - arg->var->arg = arg; - arg->def = def; - return arg; -} - -static inline void free_impl_arg(impl_arg *arg) { - free_impl_type(arg->type); - free_impl_var(arg->var); - if (arg->def) { - free_impl_def_val(arg->def); - } - free(arg); -} - -typedef struct impl_vararg { - impl_arg *name; - struct impl_args *args; - token_t *types; - impl_val *values; - void **free_list; -} impl_vararg; - -typedef struct impl_args { - impl_arg **args; - size_t count; - impl_vararg vararg; -} impl_args; - -static inline impl_args *init_impl_args(impl_arg *arg) { - impl_args *args = calloc(1, sizeof(*args)); - if (arg) { - args->count = 1; - args->args = calloc(1, sizeof(*args->args)); - args->args[0] = arg; - } - return args; -} - -static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) { - args->args = realloc(args->args, ++args->count * sizeof(*args->args)); - args->args[args->count-1] = arg; - return args; -} - -static inline void free_impl_args(impl_args *args) { - size_t i; - - for (i = 0; i < args->count; ++i) { - free_impl_arg(args->args[i]); - } - if (args->vararg.name) { - free_impl_arg(args->vararg.name); - } - free(args->args); - free(args); -} - -typedef struct impl_func { - PSI_Token *token; - char *name; - impl_args *args; - impl_type *return_type; - unsigned return_reference:1; -} impl_func; - -static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) { - impl_func *func = calloc(1, sizeof(*func)); - func->name = strdup(name); - func->args = args ? args : init_impl_args(NULL); - func->return_type = type; - func->return_reference = ret_reference; - return func; -} - -static inline void free_impl_func(impl_func *f) { - if (f->token) { - free(f->token); - } - free_impl_type(f->return_type); - free_impl_args(f->args); - free(f->name); - free(f); -} - -typedef struct num_exp { - PSI_Token *token; - token_t t; - union { - char *numb; - constant *cnst; - decl_var *dvar; - struct decl_enum_item *enm; - } u; - token_t operator; - int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res); - struct num_exp *operand; -} num_exp; - -static inline num_exp *init_num_exp(token_t t, void *num) { - num_exp *exp = calloc(1, sizeof(*exp)); - switch (exp->t = t) { - case PSI_T_NUMBER: - case PSI_T_NSNAME: - exp->u.numb = strdup(num); - break; - case PSI_T_NAME: - exp->u.dvar = num; - break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return exp; -} - -static inline num_exp *copy_num_exp(num_exp *exp) { - decl_var *dvar; - num_exp *num = calloc(1, sizeof(*num)); - - memcpy(num, exp, sizeof(*num)); - - if (num->token) { - num->token = PSI_TokenCopy(num->token); - } - if (num->operand) { - num->operand = copy_num_exp(num->operand); - } - switch (num->t) { - case PSI_T_NUMBER: - case PSI_T_NSNAME: - num->u.numb = strdup(num->u.numb); - break; - case PSI_T_NAME: - dvar = init_decl_var(num->u.dvar->name, num->u.dvar->pointer_level, num->u.dvar->array_size); - dvar->arg = num->u.dvar->arg; - if (num->u.dvar->token) { - dvar->token = PSI_TokenCopy(num->u.dvar->token); - } - num->u.dvar = dvar; - break; - } - return num; -} - -static inline void free_num_exp(num_exp *exp) { - if (exp->token) { - free(exp->token); - } - switch (exp->t) { - case PSI_T_NUMBER: - free(exp->u.numb); - break; - case PSI_T_NSNAME: - break; - case PSI_T_NAME: - free_decl_var(exp->u.dvar); - break; - case PSI_T_ENUM: - break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - if (exp->operand) { - free_num_exp(exp->operand); - } - free(exp); -} - -typedef struct decl_enum_item { - PSI_Token *token; - char *name; - num_exp *num; - num_exp inc; - struct decl_enum_item *prev; -} decl_enum_item; - -static inline decl_enum_item *init_decl_enum_item(const char *name, num_exp *num) { - decl_enum_item *i = calloc(1, sizeof(*i)); - - i->name = strdup(name); - i->num = num; - return i; -} - -static inline void free_decl_enum_item(decl_enum_item *i) { - if (i->token) { - free(i->token); - } - if (i->num && i->num != &i->inc) { - free_num_exp(i->num); - } - free(i->name); - free(i); -} - -typedef struct decl_enum_items { - decl_enum_item **list; - size_t count; -} decl_enum_items; - -static inline decl_enum_items *init_decl_enum_items(decl_enum_item *i) { - decl_enum_items *l = calloc(1, sizeof(*l)); - - if (i) { - l->count = 1; - l->list = calloc(1, sizeof(*l->list)); - l->list[0] = i; - } - return l; -} - -static inline decl_enum_items *add_decl_enum_item(decl_enum_items *l, decl_enum_item *i) { - l->list = realloc(l->list, sizeof(*l->list) * (l->count + 1)); - l->list[l->count] = i; - if (l->count) { - i->prev = l->list[l->count - 1]; - } - ++l->count; - return l; -} - -static inline void free_decl_enum_items(decl_enum_items *l) { - if (l->list) { - size_t j; - - for (j = 0; j < l->count; ++j) { - free_decl_enum_item(l->list[j]); - } - free(l->list); - } - free(l); -} - -typedef struct decl_enum { - PSI_Token *token; - char *name; - decl_enum_items *items; -} decl_enum; - -static inline decl_enum *init_decl_enum(const char *name, decl_enum_items *l) { - decl_enum *e = calloc(1, sizeof(*e)); - - e->name = strdup(name); - e->items = l; - return e; -} - -static inline void free_decl_enum(decl_enum *e) { - if (e->token) { - free(e->token); - } - if (e->items) { - free_decl_enum_items(e->items); - } - free(e->name); - free(e); -} - -typedef struct decl_enums { - decl_enum **list; - size_t count; -} decl_enums; +#include "token.h" +#include "types.h" +#include "data.h" -static inline decl_enums* add_decl_enum(decl_enums *es, decl_enum *e) { - if (!es) { - es = calloc(1, sizeof(*es)); - } - es->list = realloc(es->list, ++es->count * sizeof(*es->list)); - es->list[es->count-1] = e; - return es; -} - -static inline void free_decl_enums(decl_enums *es) { - if (es->list) { - size_t j; - - for (j = 0; j < es->count; ++j) { - free_decl_enum(es->list[j]); - } - } - free(es->list); - free(es); -} - -typedef struct let_calloc { - num_exp *nmemb; - num_exp *size; -} let_calloc; - -static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) { - let_calloc *alloc = calloc(1, sizeof(*alloc)); - alloc->nmemb = nmemb; - alloc->size = size; - return alloc; -} - -static inline void free_let_calloc(let_calloc *alloc) { - free_num_exp(alloc->nmemb); - free_num_exp(alloc->size); - free(alloc); -} - -typedef struct let_callback { - struct let_func *func; - struct set_values *args; - decl *decl; -} let_callback; - -static inline void free_let_func(struct let_func *func); -static inline void free_set_values(struct set_values *vals); -static inline let_callback *init_let_callback(struct let_func *func, struct set_values *args) { - let_callback *cb = calloc(1, sizeof(*cb)); - - cb->func = func; - cb->args = args; - return cb; -} - -static inline void free_let_callback(let_callback *cb) { - free_let_func(cb->func); - free_set_values(cb->args); - free(cb); -} - -typedef impl_val *(*let_func_handler)(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free); - -typedef struct let_func { - token_t type; - char *name; - impl_var *var; - let_func_handler handler; -} let_func; - -static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) { - let_func *func = calloc(1, sizeof(*func)); - func->type = type; - func->name = strdup(name); - func->var = var; - return func; -} - -static inline void free_let_func(let_func *func) { - free_impl_var(func->var); - free(func->name); - free(func); -} - -enum let_val_kind { - PSI_LET_NULL, - PSI_LET_NUMEXP, - PSI_LET_CALLOC, - PSI_LET_CALLBACK, - PSI_LET_FUNC, - PSI_LET_TMP, -}; -#define PSI_LET_REFERENCE 0x1; -typedef struct let_val { - enum let_val_kind kind; - union { - num_exp *num; - let_calloc *alloc; - let_callback *callback; - let_func *func; - decl_var *var; - } data; - union { - struct { - unsigned is_reference:1; - } one; - unsigned all; - } flags; -} let_val; - -static inline let_val *init_let_val(enum let_val_kind kind, void *data) { - let_val *let = calloc(1, sizeof(*let)); - switch (let->kind = kind) { - case PSI_LET_NULL: - break; - case PSI_LET_NUMEXP: - let->data.num = data; - break; - case PSI_LET_CALLOC: - let->data.alloc = data; - break; - case PSI_LET_CALLBACK: - let->data.callback = data; - break; - case PSI_LET_FUNC: - let->data.func = data; - break; - case PSI_LET_TMP: - let->data.var = data; - break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - return let; -} - -static inline void free_let_val(let_val *let) { - switch (let->kind) { - case PSI_LET_NULL: - break; - case PSI_LET_NUMEXP: - free_num_exp(let->data.num); - break; - case PSI_LET_CALLOC: - free_let_calloc(let->data.alloc); - break; - case PSI_LET_CALLBACK: - free_let_callback(let->data.callback); - break; - case PSI_LET_FUNC: - free_let_func(let->data.func); - break; - case PSI_LET_TMP: - free_decl_var(let->data.var); - break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - free(let); -} - -typedef struct let_stmt { - decl_var *var; - let_val *val; -} let_stmt; - -static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) { - let_stmt *let = calloc(1, sizeof(*let)); - let->var = var; - let->val = val; - return let; -} - -static inline void free_let_stmt(let_stmt *stmt) { - if (stmt->val) { - if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) { - free_decl_arg(stmt->var->arg); - } - free_let_val(stmt->val); - } - free_decl_var(stmt->var); - free(stmt); -} - -struct set_value; - -typedef struct set_func { - PSI_Token *token; - token_t type; - char *name; - void (*handler)(zval *, struct set_value *set, impl_val *ret_val); -} set_func; - -static inline set_func *init_set_func(token_t type, const char *name) { - set_func *func = calloc(1, sizeof(*func)); - func->type = type; - func->name = strdup(name); - return func; -} - -static inline void free_set_func(set_func *func) { - if (func->token) { - free(func->token); - } - free(func->name); - free(func); -} - -typedef struct set_value { - set_func *func; - decl_vars *vars; - num_exp *num; - struct { - struct set_value *set; - impl_val *val; - } outer; - struct set_values *inner; -} set_value; - -typedef struct set_values { - set_value **vals; - size_t count; -} set_values; - - -static inline set_value *init_set_value(set_func *func, decl_vars *vars) { - set_value *val = calloc(1, sizeof(*val)); - val->func = func; - val->vars = vars; - return val; -} - -static inline set_values *add_set_value(set_values *vals, set_value *val); -static inline set_value *add_inner_set_value(set_value *val, set_value *inner) { - val->inner = add_set_value(val->inner, inner); - inner->outer.set = val; - return val; -} - -static inline void free_set_value(set_value *val) { - if (val->func) { - free_set_func(val->func); - } - if (val->vars) { - free_decl_vars(val->vars); - } - if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) { - free_set_values(val->inner); - } - if (val->num) { - free_num_exp(val->num); - } - free(val); -} - -static inline set_values *init_set_values(set_value *val) { - set_values *vals = calloc(1, sizeof(*vals)); - if (val) { - vals->count = 1; - vals->vals = calloc(1, sizeof(val)); - vals->vals[0] = val; - } - return vals; -} - -static inline set_values *add_set_value(set_values *vals, set_value *val) { - if (!vals) { - vals = calloc(1, sizeof(*vals)); - } - vals->vals = realloc(vals->vals, ++vals->count * sizeof(val)); - vals->vals[vals->count-1] = val; - return vals; -} - -static inline void free_set_values(set_values *vals) { - if (vals->vals) { - size_t i; - - for (i = 0; i < vals->count; ++i) { - free_set_value(vals->vals[i]); - } - free(vals->vals); - } - free(vals); -} - -typedef struct set_stmt { - impl_var *var; - set_value *val; - impl_arg *arg; -} set_stmt; - -static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) { - set_stmt *set = calloc(1, sizeof(*set)); - set->var = var; - set->val = val; - return set; -} - -static inline void free_set_stmt(set_stmt *set) { - free_impl_var(set->var); - free_set_value(set->val); - free(set); -} - -typedef struct return_stmt { - PSI_Token *token; - set_value *set; - decl_arg *decl; -} return_stmt; - -static inline return_stmt *init_return_stmt(set_value *val) { - return_stmt *ret = calloc(1, sizeof(*ret)); - ret->set = val; - return ret; -} - -static inline void free_return_stmt(return_stmt *ret) { - if (ret->token) { - free(ret->token); - } - free_set_value(ret->set); - free(ret); -} - -typedef struct free_call { - PSI_Token *token; - char *func; - decl_vars *vars; - decl *decl; -} free_call; - -static inline free_call *init_free_call(const char *func, decl_vars *vars) { - free_call *f = calloc(1, sizeof(*f)); - f->func = strdup(func); - f->vars = vars; - return f; -} - -static inline void free_free_call(free_call *f) { - if (f->token) { - free(f->token); - } - free(f->func); - free_decl_vars(f->vars); - free(f); -} - -typedef struct free_calls { - free_call **list; - size_t count; -} free_calls; - -static inline free_calls *init_free_calls(free_call *f) { - free_calls *fcs = calloc(1, sizeof(*fcs)); - if (f) { - fcs->count = 1; - fcs->list = calloc(1, sizeof(*fcs->list)); - fcs->list[0] = f; - } - return fcs; -} - -static inline void free_free_calls(free_calls *fcs) { - size_t i; - - for (i = 0; i < fcs->count; ++i) { - free_free_call(fcs->list[i]); - } - free(fcs->list); - free(fcs); -} - -static inline free_calls *add_free_call(free_calls *fcs, free_call *f) { - fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list)); - fcs->list[fcs->count-1] = f; - return fcs; -} - -typedef struct free_stmt { - free_calls *calls; -} free_stmt; - -static inline free_stmt *init_free_stmt(free_calls *calls) { - free_stmt *f = calloc(1, sizeof(*f)); - f->calls = calls; - return f; -} - -static inline void free_free_stmt(free_stmt *f) { - free_free_calls(f->calls); - free(f); -} - -typedef struct impl_stmt { - token_t type; - union { - let_stmt *let; - set_stmt *set; - return_stmt *ret; - free_stmt *fre; - void *ptr; - } s; -} impl_stmt; - -static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) { - impl_stmt *stmt = calloc(1, sizeof(*stmt)); - stmt->type = type; - stmt->s.ptr = ptr; - return stmt; -} - -static inline void free_impl_stmt(impl_stmt *stmt) { - switch (stmt->type) { - case PSI_T_LET: - free_let_stmt(stmt->s.let); - break; - case PSI_T_SET: - free_set_stmt(stmt->s.set); - break; - case PSI_T_RETURN: - free_return_stmt(stmt->s.ret); - break; - case PSI_T_FREE: - free_free_stmt(stmt->s.fre); - break; - } - free(stmt); -} - -typedef struct impl_stmts { - struct { - return_stmt **list; - size_t count; - } ret; - struct { - let_stmt **list; - size_t count; - } let; - struct { - set_stmt **list; - size_t count; - } set; - struct { - free_stmt **list; - size_t count; - } fre; -} impl_stmts; - -static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) { - list = realloc(list, count * sizeof(list)); - ((void **)list)[count-1] = stmt; - return list; -} - -static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) { - switch (stmt->type) { - case PSI_T_RETURN: - stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret); - break; - case PSI_T_LET: - stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let); - break; - case PSI_T_SET: - stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set); - break; - case PSI_T_FREE: - stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre); - break; - } - free(stmt); - return stmts; -} - -static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) { - impl_stmts *stmts = calloc(1, sizeof(*stmts)); - return add_impl_stmt(stmts, stmt); -} - -static inline void free_impl_stmts(impl_stmts *stmts) { - size_t i; - - for (i = 0; i < stmts->let.count; ++i) { - free_let_stmt(stmts->let.list[i]); - } - free(stmts->let.list); - for (i = 0; i < stmts->ret.count; ++i) { - free_return_stmt(stmts->ret.list[i]); - } - free(stmts->ret.list); - for (i = 0; i < stmts->set.count; ++i) { - free_set_stmt(stmts->set.list[i]); - } - free(stmts->set.list); - for (i = 0; i < stmts->fre.count; ++i) { - free_free_stmt(stmts->fre.list[i]); - } - free(stmts->fre.list); - free(stmts); -} - -typedef struct impl { - impl_func *func; - impl_stmts *stmts; - decl *decl; -} impl; - -static inline impl *init_impl(impl_func *func, impl_stmts *stmts) { - impl *i = calloc(1, sizeof(*i)); - i->func = func; - i->stmts = stmts; - return i; -} - -static inline void free_impl(impl *impl) { - free_impl_func(impl->func); - free_impl_stmts(impl->stmts); - free(impl); -} - -typedef struct impls { - size_t count; - impl **list; -} impls; - -static inline impls *add_impl(impls *impls, impl *impl) { - if (!impls) { - impls = calloc(1, sizeof(*impls)); - } - impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list)); - impls->list[impls->count-1] = impl; - return impls; -} - -static void free_impls(impls *impls) { - size_t i; - - for (i = 0; i < impls->count; ++i) { - free_impl(impls->list[i]); - } - free(impls->list); - free(impls); -} - -typedef struct decl_file { - char *ln; - char *fn; -} decl_file; - -static inline void free_decl_file(decl_file *file) { - if (file->ln) { - free(file->ln); - } - if (file->fn) { - free(file->fn); - } - memset(file, 0, sizeof(*file)); -} - -typedef struct decl_libs { - void **dl; - size_t count; -} decl_libs; - -static inline void free_decl_libs(decl_libs *libs) { - if (libs->dl) { - size_t i; - for (i = 0; i < libs->count; ++i) { - if (libs->dl[i]) { - dlclose(libs->dl[i]); - } - } - free(libs->dl); - } - memset(libs, 0, sizeof(*libs)); -} - -static inline void add_decl_lib(decl_libs *libs, void *dlopened) { - libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl)); - libs->dl[libs->count-1] = dlopened; -} - -static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) { - unsigned i; - - ZEND_ASSERT(var->arg->var != var); -#if 0 - fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n", - var->name, var->pointer_level, var->arg->var->pointer_level, - var->array_size, var->arg->var->array_size, ret_val); -#endif - for (i = 0; i < var->pointer_level; ++i) { -#if 0 - fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr); -#endif - ret_val = *(void **) ret_val; - } - return ret_val; -} - -static inline impl_val *enref_impl_val(void *ptr, decl_var *var) { - impl_val *val, *val_ptr; - unsigned i; - - ZEND_ASSERT(var->arg->var == var); -#if 0 - fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n", - var->name, var->pointer_level, var->arg->var->pointer_level, - var->array_size, var->arg->var->array_size); -#endif - if (!var->pointer_level ){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) { - return ptr; - } - - val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *)); - for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) { -#if 0 - fprintf(stderr, "++\n"); -#endif - val_ptr->ptr = (void **) val_ptr + 1; - val_ptr = val_ptr->ptr; - } - val_ptr->ptr = ptr; - return val; -} - -static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) { - void *ptr = (char *) struct_ptr + set_arg->layout->pos; -#if 0 - fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr); -#endif - return ptr; -} - - -#define PSI_ERROR 16 -#define PSI_WARNING 32 -typedef void (*psi_error_cb)(void *context, PSI_Token *token, int type, const char *msg, ...); - -#define PSI_DATA(D) ((PSI_Data *) (D)) -#define PSI_DATA_MEMBERS \ - constants *consts; \ - decl_typedefs *defs; \ - decl_structs *structs; \ - decl_unions *unions; \ - decl_enums *enums; \ - decls *decls; \ - impls *impls; \ - union { \ - decl_file file; \ - decl_libs libs; \ - } psi; \ - psi_error_cb error; \ - unsigned errors; \ - unsigned flags -typedef struct PSI_Data { - PSI_DATA_MEMBERS; -} PSI_Data; - -static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) { - if (!dest) { - dest = malloc(sizeof(*dest)); - } - memcpy(dest, src, sizeof(*dest)); - memset(src, 0, sizeof(*src)); - return dest; -} - -static inline void PSI_DataDtor(PSI_Data *data) { - if (data->consts) { - free_constants(data->consts); - } - if (data->defs) { - free_decl_typedefs(data->defs); - } - if (data->structs) { - free_decl_structs(data->structs); - } - if (data->unions) { - free_decl_unions(data->unions); - } - if (data->enums) { - free_decl_enums(data->enums); - } - if (data->decls) { - free_decls(data->decls); - } - if (data->impls) { - free_impls(data->impls); - } - free_decl_file(&data->psi.file); -} - -typedef struct PSI_Parser { +struct psi_parser { PSI_DATA_MEMBERS; FILE *fp; token_t num; void *proc; unsigned line, col; char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE]; -} PSI_Parser; - -static inline size_t PSI_TokenAllocSize(size_t token_len, size_t fname_len) { - return sizeof(PSI_Token) + token_len + fname_len + 2; -} - -static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) { - PSI_Token *T; - size_t token_len, fname_len; - token_t token_typ; - - if (P->cur < P->tok) { - return NULL; - } - - token_typ = P->num; - token_len = P->cur - P->tok; - fname_len = strlen(P->psi.file.fn); - - T = calloc(1, PSI_TokenAllocSize(token_len, fname_len)); - T->type = token_typ; - T->size = token_len; - T->text = &T->buf[0]; - T->file = &T->buf[token_len + 1]; - T->line = P->line; - T->col = P->col; - - memcpy(T->text, P->tok, token_len); - memcpy(T->file, P->psi.file.fn, fname_len); - - return T; -} - -static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) { - size_t strct_len = PSI_TokenAllocSize(src->size, strlen(src->file)); - PSI_Token *ptr = malloc(strct_len); - - memcpy(ptr, src, strct_len); - - ptr->text = &ptr->buf[0]; - ptr->file = &ptr->buf[ptr->size + 1]; - - return ptr; -} - -static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) { - va_list argv; - unsigned i; - PSI_Token *T = NULL; - - va_start(argv, argc); - for (i = 0; i < argc; ++i) { - PSI_Token *arg = va_arg(argv, PSI_Token *); - - if (T) { - size_t token_len = T->size, fname_len = strlen(T->file); - - T = realloc(T, PSI_TokenAllocSize(T->size += arg->size + 1, fname_len)); - T->text = &T->buf[0]; - T->file = &T->buf[T->size + 1]; - T->buf[token_len] = ' '; - memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1); - memcpy(&T->buf[token_len + 1], arg->text, arg->size + 1); - } else { - T = PSI_TokenCopy(arg); - T->type = PSI_T_NAME; - } - } - va_end(argv); - - return T; -} - -static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) { - va_list argv; - unsigned i; - - va_start(argv, argc); - for (i = 0; i < argc; ++i) { - char *str = va_arg(argv, char *); - size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file); - - T = realloc(T, PSI_TokenAllocSize(T->size += str_len + 1, fname_len)); - T->text = &T->buf[0]; - T->file = &T->buf[T->size + 1]; - T->buf[token_len] = ' '; - memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1); - memcpy(&T->buf[token_len + 1], str, str_len + 1); - } - va_end(argv); - - return T; -} - -char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen); -static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) { - php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to))); - return T; -} - -static inline uint64_t psi_hash(char *digest_buf, ...) -{ - uint64_t hash = 5381; - uint8_t c; - const uint8_t *ptr; - va_list argv; - - va_start(argv, digest_buf); - while ((ptr = va_arg(argv, const uint8_t *))) { - while ((c = *ptr++)) { - hash = ((hash << 5) + hash) + c; - } - } - va_end(argv); - - if (digest_buf) { - sprintf(digest_buf, "%" PRIx64, hash); - } - - return hash; -} - -static inline uint64_t PSI_TokenHash(PSI_Token *t, char *digest_buf) { - char loc_buf[48]; - - sprintf(loc_buf, "%u%u", t->line, t->col); - return psi_hash(digest_buf, t->file, loc_buf, NULL); -} +}; #define PSI_PARSER_DEBUG 0x1 #define PSI_PARSER_SILENT 0x2 -PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags); -void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...); -size_t PSI_ParserFill(PSI_Parser *P, size_t n); -token_t PSI_ParserScan(PSI_Parser *P); -void PSI_ParserParse(PSI_Parser *P, PSI_Token *src); -void PSI_ParserDtor(PSI_Parser *P); -void PSI_ParserFree(PSI_Parser **P); +struct psi_parser *psi_parser_init(struct psi_parser *P, const char *filename, psi_error_cb error, unsigned flags); +void psi_parser_syntax_error(struct psi_parser *P, const char *fn, size_t ln, const char *msg, ...); +size_t psi_parser_fill(struct psi_parser *P, size_t n); +token_t psi_parser_scan(struct psi_parser *P); +void psi_parser_parse(struct psi_parser *P, struct psi_token *src); +void psi_parser_dtor(struct psi_parser *P); +void psi_parser_free(struct psi_parser **P); #endif diff --git a/src/parser.re b/src/parser.re index 10279ed..3cfe130 100644 --- a/src/parser.re +++ b/src/parser.re @@ -1,18 +1,25 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# include "php_config.h" +#endif + #include #include #include #include #include -#include "parser.h" #include "parser_proc.h" -void *PSI_ParserProcAlloc(void*(unsigned long)); -void PSI_ParserProcFree(void*, void(*)(void*)); -void PSI_ParserProc(void *, token_t, PSI_Token *, PSI_Parser *); -void PSI_ParserProcTrace(FILE *, const char*); +#include "parser.h" + +void *psi_parser_proc_Alloc(void*(unsigned long)); +void psi_parser_proc_Free(void*, void(*)(void*)); +void psi_parser_proc_(void *, token_t, struct psi_token *, struct psi_parser *); +void psi_parser_proc_Trace(FILE *, const char*); -PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags) +struct psi_parser *psi_parser_init(struct psi_parser *P, const char *filename, psi_error_cb error, unsigned flags) { FILE *fp; @@ -37,18 +44,18 @@ PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb err P->line = 1; P->error = error; P->flags = flags; - P->proc = PSI_ParserProcAlloc(malloc); + P->proc = psi_parser_proc_Alloc(malloc); if (flags & PSI_PARSER_DEBUG) { - PSI_ParserProcTrace(stderr, "PSI> "); + psi_parser_proc_Trace(stderr, "PSI> "); } - PSI_ParserFill(P, 0); + psi_parser_fill(P, 0); return P; } -size_t PSI_ParserFill(PSI_Parser *P, size_t n) +size_t psi_parser_fill(struct psi_parser *P, size_t n) { if (P->flags & PSI_PARSER_DEBUG) { fprintf(stderr, "PSI> Fill: n=%zu\n", n); @@ -89,32 +96,32 @@ size_t PSI_ParserFill(PSI_Parser *P, size_t n) return P->lim - P->cur; } -void PSI_ParserParse(PSI_Parser *P, PSI_Token *T) +void psi_parser_parse(struct psi_parser *P, struct psi_token *T) { if (T) { - PSI_ParserProc(P->proc, T->type, T, P); + psi_parser_proc_(P->proc, T->type, T, P); } else { - PSI_ParserProc(P->proc, 0, NULL, P); + psi_parser_proc_(P->proc, 0, NULL, P); } } -void PSI_ParserDtor(PSI_Parser *P) +void psi_parser_dtor(struct psi_parser *P) { - PSI_ParserProcFree(P->proc, free); + psi_parser_proc_Free(P->proc, free); if (P->fp) { fclose(P->fp); } - PSI_DataDtor((PSI_Data *) P); + psi_data_dtor(PSI_DATA(P)); memset(P, 0, sizeof(*P)); } -void PSI_ParserFree(PSI_Parser **P) +void psi_parser_free(struct psi_parser **P) { if (*P) { - PSI_ParserDtor(*P); + psi_parser_dtor(*P); free(*P); *P = NULL; } @@ -145,7 +152,7 @@ void PSI_ParserFree(PSI_Parser **P) ++P->line; \ goto label -token_t PSI_ParserScan(PSI_Parser *P) +token_t psi_parser_scan(struct psi_parser *P) { for (;;) { ADDCOLS; @@ -157,7 +164,7 @@ token_t PSI_ParserScan(PSI_Parser *P) re2c:define:YYCURSOR = P->cur; re2c:define:YYLIMIT = P->lim; re2c:define:YYMARKER = P->mrk; - re2c:define:YYFILL = "{ if (!PSI_ParserFill(P,@@)) RETURN(PSI_T_EOF); }"; + re2c:define:YYFILL = "{ if (!psi_parser_fill(P,@@)) RETURN(PSI_T_EOF); }"; re2c:yyfill:parameter = 0; B = [^a-zA-Z0-9_]; diff --git a/src/parser_def.h b/src/parser_def.h index e286bcd..f7d7d06 100644 --- a/src/parser_def.h +++ b/src/parser_def.h @@ -20,13 +20,13 @@ #define DEF(dn, dv) #define LET(nt, rule) #define PARSE(nt, rule) \ - static void COUNTED(nt) (PSI_Parser *P rule) + static void COUNTED(nt) (struct psi_parser *P rule) #define PARSE_NAMED(nt, nt_name, rule) \ - static void COUNTED(nt) (PSI_Parser *P NAMED(nt, nt_name) rule) + static void COUNTED(nt) (struct psi_parser *P NAMED(nt, nt_name) rule) #define PARSE_TYPED(nt, nt_name, rule) \ - static void COUNTED(nt) (PSI_Parser *P TYPED(nt, nt_name) rule) + static void COUNTED(nt) (struct psi_parser *P TYPED(nt, nt_name) rule) #define TOKEN(t) -#define NAMED(t, name) , PSI_Token *name +#define NAMED(t, name) , struct psi_token *name #define TYPED(t, name) , TOKEN_TYPE_NAME(t) name #define TOKEN_TYPE_NAME(token) _##token##_type #define TOKEN_TYPE(token, type) typedef type TOKEN_TYPE_NAME(token); @@ -37,12 +37,12 @@ DEF(%include, { void psi_error(int, const char *, int, const char *, ...); }) -DEF(%name, PSI_ParserProc) +DEF(%name, psi_parser_proc_) DEF(%token_prefix, PSI_T_) -DEF(%token_type, {PSI_Token *}) +DEF(%token_type, {struct psi_token *}) DEF(%token_destructor, {free($$);}) DEF(%default_destructor, {(void)P;}) -DEF(%extra_argument, {PSI_Parser *P}) +DEF(%extra_argument, {struct psi_parser *P}) /* TOKEN is defined inside syntax_error */ DEF(%syntax_error, { @@ -253,8 +253,8 @@ PARSE_NAMED(enum_name, n, } else { char digest[17]; - PSI_TokenHash(E, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@"); + psi_token_hash(E, digest); + n = psi_token_translit(psi_token_append(E, 1, digest), " ", "@"); } } @@ -300,8 +300,8 @@ PARSE_NAMED(union_name, n, } else { char digest[17]; - PSI_TokenHash(U, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@"); + psi_token_hash(U, digest); + n = psi_token_translit(psi_token_append(U, 1, digest), " ", "@"); } } @@ -314,8 +314,8 @@ PARSE_NAMED(struct_name, n, } else { char digest[17]; - PSI_TokenHash(S, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@"); + psi_token_hash(S, digest); + n = psi_token_translit(psi_token_append(S, 1, digest), " ", "@"); } } @@ -406,7 +406,7 @@ PARSE_TYPED(decl_typedef_body_ex, def, TYPED(decl_struct_args_block, args) TYPED(decl_var, var)) { def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var); - def->type->token = PSI_TokenCopy(N); + def->type->token = psi_token_copy(N); def->type->real.strct = init_decl_struct(N->text, args); def->type->real.strct->token = N; def->type->real.strct->align = as.pos; @@ -418,7 +418,7 @@ PARSE_TYPED(decl_typedef_body_ex, def, TYPED(decl_struct_args_block, args) TYPED(decl_var, var)) { def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var); - def->type->token = PSI_TokenCopy(N); + def->type->token = psi_token_copy(N); def->type->real.unn = init_decl_union(N->text, args); def->type->real.unn->token = N; def->type->real.unn->align = as.pos; @@ -429,7 +429,7 @@ PARSE_TYPED(decl_typedef_body_ex, def, NAMED(NAME, ALIAS)) { def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0)); def->var->token = ALIAS; - def->type->token = PSI_TokenCopy(e->token); + def->type->token = psi_token_copy(e->token); def->type->real.enm = e; } @@ -448,7 +448,7 @@ PARSE_TYPED(decl_typedef_body, def, TYPED(decl_func, func_) TYPED(decl_typedef_body_fn_args, args)) { def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var)); - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } PARSE_TYPED(decl_typedef_body, def, @@ -503,7 +503,7 @@ PARSE_TYPED(decl_typedef_body, def, copy_decl_var(func_->var) ); def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } PARSE_TYPED(decl_typedef_body, def, @@ -528,7 +528,7 @@ PARSE_TYPED(decl_typedef_body, def, copy_decl_var(func_->var) ); def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } @@ -591,7 +591,7 @@ PARSE_TYPED(decl_typedef_body, def, copy_decl_var(func_->var) ); def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } @@ -707,7 +707,7 @@ PARSE_NAMED(decl_scalar_type, type_, NAMED(SHORT, S) NAMED(decl_scalar_type_short, s)) { if (s) { - type_ = PSI_TokenCat(2, S, s); + type_ = psi_token_cat(2, S, s); free(S); free(s); } else { @@ -730,7 +730,7 @@ PARSE_NAMED(decl_scalar_type, type_, NAMED(LONG, L) NAMED(decl_scalar_type_long, l)) { if (l) { - type_ = PSI_TokenCat(2, L, l); + type_ = psi_token_cat(2, L, l); free(L); free(l); } else { @@ -748,7 +748,7 @@ PARSE_NAMED(decl_scalar_type_long, l, NAMED(LONG, L) NAMED(decl_scalar_type_long_long, ll)) { if (ll) { - l = PSI_TokenCat(2, L, ll); + l = psi_token_cat(2, L, ll); free(L); free(ll); } else { @@ -765,7 +765,7 @@ PARSE_NAMED(decl_scalar_type_long_long, ll, PARSE_TYPED(decl_type, type_, NAMED(UNSIGNED, U) NAMED(decl_scalar_type, N)) { - PSI_Token *T = PSI_TokenCat(2, U, N); + struct psi_token *T = psi_token_cat(2, U, N); type_ = init_decl_type(T->type, T->text); type_->token = T; free(U); @@ -774,7 +774,7 @@ PARSE_TYPED(decl_type, type_, PARSE_TYPED(decl_type, type_, NAMED(SIGNED, S) NAMED(decl_scalar_type, N)) { - PSI_Token *T = PSI_TokenCat(2, S, N); + struct psi_token *T = psi_token_cat(2, S, N); type_ = init_decl_type(T->type, T->text); type_->token = T; free(S); @@ -955,7 +955,7 @@ PARSE_TYPED(num_exp, exp, PARSE_TYPED(num_exp, exp, TYPED(decl_var, var)) { exp = init_num_exp(PSI_T_NAME, var); - exp->token = PSI_TokenCopy(var->token); + exp->token = psi_token_copy(var->token); } PARSE_TYPED(num_exp, exp, TYPED(num_exp, exp_) diff --git a/src/parser_proc.inc b/src/parser_proc.inc index 5d87612..81489d5 100644 --- a/src/parser_proc.inc +++ b/src/parser_proc.inc @@ -1,4 +1,10 @@ %include { +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# include "php_config.h" +#endif + #include #include #include diff --git a/src/parser_proc.y b/src/parser_proc.y index 4099877..0d0aa61 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -1,4 +1,10 @@ %include { +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# include "php_config.h" +#endif + #include #include #include @@ -8,12 +14,12 @@ #include "parser.h" } %include { void psi_error(int, const char *, int, const char *, ...); } -%name PSI_ParserProc +%name psi_parser_proc_ %token_prefix PSI_T_ -%token_type {PSI_Token *} +%token_type {struct psi_token *} %token_destructor {free($$);} %default_destructor {(void)P;} -%extra_argument {PSI_Parser *P} +%extra_argument {struct psi_parser *P} %syntax_error { ++P->errors; if (TOKEN && TOKEN->type != PSI_T_EOF) { psi_error(PSI_WARNING, TOKEN->file, TOKEN->line, "PSI syntax error: Unexpected token '%s'", TOKEN->text); } else { psi_error(PSI_WARNING, P->psi.file.fn, P->line, "PSI syntax error: Unexpected end of input"); } } %nonassoc NAME. %left PLUS MINUS. @@ -197,8 +203,8 @@ enum_name(n) ::= ENUM(E) optional_name(N). { free(E); } else { char digest[17]; - PSI_TokenHash(E, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@"); + psi_token_hash(E, digest); + n = psi_token_translit(psi_token_append(E, 1, digest), " ", "@"); } } decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. { @@ -225,8 +231,8 @@ union_name(n) ::= UNION(U) optional_name(N). { free(U); } else { char digest[17]; - PSI_TokenHash(U, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(U, 1, digest), " ", "@"); + psi_token_hash(U, digest); + n = psi_token_translit(psi_token_append(U, 1, digest), " ", "@"); } } struct_name(n) ::= STRUCT(S) optional_name(N). { @@ -235,8 +241,8 @@ struct_name(n) ::= STRUCT(S) optional_name(N). { free(S); } else { char digest[17]; - PSI_TokenHash(S, digest); - n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@"); + psi_token_hash(S, digest); + n = psi_token_translit(psi_token_append(S, 1, digest), " ", "@"); } } decl_struct_args_block(args_) ::= LBRACE struct_args(args) RBRACE. { @@ -284,7 +290,7 @@ decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. { } decl_typedef_body_ex(def) ::= struct_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). { def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var); - def->type->token = PSI_TokenCopy(N); + def->type->token = psi_token_copy(N); def->type->real.strct = init_decl_struct(N->text, args); def->type->real.strct->token = N; def->type->real.strct->align = as.pos; @@ -292,7 +298,7 @@ decl_typedef_body_ex(def) ::= struct_name(N) align_and_size(as) decl_struct_args } decl_typedef_body_ex(def) ::= union_name(N) align_and_size(as) decl_struct_args_block(args) decl_var(var). { def = init_decl_arg(init_decl_type(PSI_T_UNION, N->text), var); - def->type->token = PSI_TokenCopy(N); + def->type->token = psi_token_copy(N); def->type->real.unn = init_decl_union(N->text, args); def->type->real.unn->token = N; def->type->real.unn->align = as.pos; @@ -301,7 +307,7 @@ decl_typedef_body_ex(def) ::= union_name(N) align_and_size(as) decl_struct_args_ decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). { def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0)); def->var->token = ALIAS; - def->type->token = PSI_TokenCopy(e->token); + def->type->token = psi_token_copy(e->token); def->type->real.enm = e; } decl_typedef_body(def) ::= decl_typedef_body_ex(def_). { @@ -312,7 +318,7 @@ decl_typedef_body_fn_args(args) ::= LPAREN decl_args(args_) RPAREN. { } decl_typedef_body(def) ::= decl_func(func_) decl_typedef_body_fn_args(args). { def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var)); - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } decl_typedef_body(def) ::= decl_arg(arg). { @@ -346,7 +352,7 @@ decl_typedef_body(def) ::= VOID(T) indirection(decl_i) LPAREN indirection(type_i copy_decl_var(func_->var) ); def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(type_i) NAME(N) RPAREN decl_typedef_body_fn_args(args). { @@ -362,7 +368,7 @@ decl_typedef_body(def) ::= CONST VOID(T) pointers(decl_i) LPAREN indirection(typ copy_decl_var(func_->var) ); def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } decl_abi(abi) ::= NAME(T). { @@ -399,7 +405,7 @@ decl_typedef_body(def) ::= const_decl_type(type_) indirection(decl_i) LPAREN ind copy_decl_var(func_->var) ); def->var->pointer_level = type_i; - def->type->token = PSI_TokenCopy(func_->token); + def->type->token = psi_token_copy(func_->token); def->type->real.func = init_decl(init_decl_abi("default"), func_, args); } decl_arg(arg_) ::= VOID(T) pointers(p) NAME(N). { @@ -475,7 +481,7 @@ decl_scalar_type(type_) ::= CHAR(C). { } decl_scalar_type(type_) ::= SHORT(S) decl_scalar_type_short(s). { if (s) { - type_ = PSI_TokenCat(2, S, s); + type_ = psi_token_cat(2, S, s); free(S); free(s); } else { @@ -493,7 +499,7 @@ decl_scalar_type(type_) ::= INT(I). { } decl_scalar_type(type_) ::= LONG(L) decl_scalar_type_long(l). { if (l) { - type_ = PSI_TokenCat(2, L, l); + type_ = psi_token_cat(2, L, l); free(L); free(l); } else { @@ -508,7 +514,7 @@ decl_scalar_type_long(l) ::= DOUBLE(D). { } decl_scalar_type_long(l) ::= LONG(L) decl_scalar_type_long_long(ll). { if (ll) { - l = PSI_TokenCat(2, L, ll); + l = psi_token_cat(2, L, ll); free(L); free(ll); } else { @@ -522,14 +528,14 @@ decl_scalar_type_long_long(ll) ::= INT(I). { ll = I; } decl_type(type_) ::= UNSIGNED(U) decl_scalar_type(N). { - PSI_Token *T = PSI_TokenCat(2, U, N); + struct psi_token *T = psi_token_cat(2, U, N); type_ = init_decl_type(T->type, T->text); type_->token = T; free(U); free(N); } decl_type(type_) ::= SIGNED(S) decl_scalar_type(N). { - PSI_Token *T = PSI_TokenCat(2, S, N); + struct psi_token *T = psi_token_cat(2, S, N); type_ = init_decl_type(T->type, T->text); type_->token = T; free(S); @@ -637,7 +643,7 @@ num_exp(exp) ::= num_exp_token(tok). { } num_exp(exp) ::= decl_var(var). { exp = init_num_exp(PSI_T_NAME, var); - exp->token = PSI_TokenCopy(var->token); + exp->token = psi_token_copy(var->token); } num_exp(exp) ::= num_exp(exp_) num_exp_op_token(operator_) num_exp(operand_). { exp_->operator = operator_->type; diff --git a/src/token.c b/src/token.c new file mode 100644 index 0000000..a9675f8 --- /dev/null +++ b/src/token.c @@ -0,0 +1,142 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# include "php_config.h" +#endif + +#include +#include +#include +#include +#include + +#include "parser_proc.h" +#include "token.h" +#include "parser.h" + +size_t psi_token_alloc_size(size_t token_len, size_t fname_len) { + return sizeof(struct psi_token) + token_len + fname_len + 2; +} + +struct psi_token *psi_token_alloc(struct psi_parser *P) { + struct psi_token *T; + size_t token_len, fname_len; + token_t token_typ; + + if (P->cur < P->tok) { + return NULL; + } + + token_typ = P->num; + token_len = P->cur - P->tok; + fname_len = strlen(P->psi.file.fn); + + T = calloc(1, psi_token_alloc_size(token_len, fname_len)); + T->type = token_typ; + T->size = token_len; + T->text = &T->buf[0]; + T->file = &T->buf[token_len + 1]; + T->line = P->line; + T->col = P->col; + + memcpy(T->text, P->tok, token_len); + memcpy(T->file, P->psi.file.fn, fname_len); + + return T; +} + +struct psi_token *psi_token_copy(struct psi_token *src) { + size_t strct_len = psi_token_alloc_size(src->size, strlen(src->file)); + struct psi_token *ptr = malloc(strct_len); + + memcpy(ptr, src, strct_len); + + ptr->text = &ptr->buf[0]; + ptr->file = &ptr->buf[ptr->size + 1]; + + return ptr; +} + +struct psi_token *psi_token_cat(unsigned argc, ...) { + va_list argv; + unsigned i; + struct psi_token *T = NULL; + + va_start(argv, argc); + for (i = 0; i < argc; ++i) { + struct psi_token *arg = va_arg(argv, struct psi_token *); + + if (T) { + size_t token_len = T->size, fname_len = strlen(T->file); + + T = realloc(T, psi_token_alloc_size(T->size += arg->size + 1, fname_len)); + T->text = &T->buf[0]; + T->file = &T->buf[T->size + 1]; + T->buf[token_len] = ' '; + memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1); + memcpy(&T->buf[token_len + 1], arg->text, arg->size + 1); + } else { + T = psi_token_copy(arg); + T->type = PSI_T_NAME; + } + } + va_end(argv); + + return T; +} + +struct psi_token *psi_token_append(struct psi_token *T, unsigned argc, ...) { + va_list argv; + unsigned i; + + va_start(argv, argc); + for (i = 0; i < argc; ++i) { + char *str = va_arg(argv, char *); + size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file); + + T = realloc(T, psi_token_alloc_size(T->size += str_len + 1, fname_len)); + T->text = &T->buf[0]; + T->file = &T->buf[T->size + 1]; + T->buf[token_len] = ' '; + memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1); + memcpy(&T->buf[token_len + 1], str, str_len + 1); + } + va_end(argv); + + return T; +} + +char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen); +struct psi_token *psi_token_translit(struct psi_token *T, char *from, char *to) { + php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to))); + return T; +} + +static inline uint64_t psi_hash(char *digest_buf, ...) +{ + uint64_t hash = 5381; + uint8_t c; + const uint8_t *ptr; + va_list argv; + + va_start(argv, digest_buf); + while ((ptr = va_arg(argv, const uint8_t *))) { + while ((c = *ptr++)) { + hash = ((hash << 5) + hash) + c; + } + } + va_end(argv); + + if (digest_buf) { + sprintf(digest_buf, "%" PRIx64, hash); + } + + return hash; +} + +uint64_t psi_token_hash(struct psi_token *t, char *digest_buf) { + char loc_buf[48]; + + sprintf(loc_buf, "%u%u", t->line, t->col); + return psi_hash(digest_buf, t->file, loc_buf, NULL); +} diff --git a/src/token.h b/src/token.h new file mode 100644 index 0000000..c7ce751 --- /dev/null +++ b/src/token.h @@ -0,0 +1,87 @@ +#ifndef _PSI_TOKEN_H +#define _PSI_TOKEN_H + +#include +#include +#include +#include + +#include "parser_proc.h" + +#define PSI_T_POINTER PSI_T_ASTERISK +#define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16) + +typedef int token_t; + +static inline size_t psi_t_alignment(token_t t) +{ +#define PSI_ALIGNOF(T) case PSI_T_## T: return ALIGNOF_## T ##_T; + switch (t) { + PSI_ALIGNOF(INT8); + PSI_ALIGNOF(UINT8); + PSI_ALIGNOF(INT16); + PSI_ALIGNOF(UINT16); + PSI_ALIGNOF(INT32); + PSI_ALIGNOF(UINT32); + PSI_ALIGNOF(INT64); + PSI_ALIGNOF(UINT64); + case PSI_T_FLOAT: + return ALIGNOF_FLOAT; + case PSI_T_DOUBLE: + return ALIGNOF_DOUBLE; + case PSI_T_POINTER: + case PSI_T_FUNCTION: + return ALIGNOF_VOID_P; + case PSI_T_ENUM: + return ALIGNOF_INT; + default: + assert(0); + } + return 0; +} + +static inline size_t psi_t_size(token_t t) +{ +#define PSI_SIZEOF(T) case PSI_T_## T : return SIZEOF_## T ##_T; + switch (t) { + PSI_SIZEOF(INT8); + PSI_SIZEOF(UINT8); + PSI_SIZEOF(INT16); + PSI_SIZEOF(UINT16); + PSI_SIZEOF(INT32); + PSI_SIZEOF(UINT32); + PSI_SIZEOF(INT64); + PSI_SIZEOF(UINT64); + case PSI_T_FLOAT: + return SIZEOF_FLOAT; + case PSI_T_DOUBLE: + return SIZEOF_DOUBLE; + case PSI_T_POINTER: + case PSI_T_FUNCTION: + return SIZEOF_VOID_P; + case PSI_T_ENUM: + return SIZEOF_INT; + default: + assert(0); + } + return 0; +} + +struct psi_token { + token_t type; + unsigned size, line, col; + char *text, *file; + char buf[1]; +}; + +struct psi_parser; + +struct psi_token *psi_token_alloc(struct psi_parser *P); +size_t psi_token_alloc_size(size_t token_len, size_t fname_len); +struct psi_token *psi_token_copy(struct psi_token *src); +struct psi_token *psi_token_cat(unsigned argc, ...); +struct psi_token *psi_token_append(struct psi_token *T, unsigned argc, ...); +struct psi_token *psi_token_translit(struct psi_token *T, char *from, char *to); +uint64_t psi_token_hash(struct psi_token *t, char *digest_buf); + +#endif diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..1b91a0c --- /dev/null +++ b/src/types.h @@ -0,0 +1,140 @@ +#ifndef _PSI_TYPES_H +#define _PSI_TYPES_H + +#include "Zend/zend_API.h" +typedef struct zend_fcall { + zend_fcall_info fci; + zend_fcall_info_cache fcc; +} zend_fcall; + +#include "token.h" + +#include "types/impl_val.h" +#include "types/decl_type.h" +#include "types/decl_var.h" +#include "types/decl_struct_layout.h" +#include "types/decl_arg.h" +#include "types/decl_typedefs.h" +#include "types/decl_vars.h" +#include "types/decl_args.h" +#include "types/decl_abi.h" +#include "types/decl_callinfo.h" +#include "types/decl.h" +#include "types/decls.h" +#include "types/decl_struct.h" +#include "types/decl_structs.h" +#include "types/decl_union.h" +#include "types/decl_unions.h" +#include "types/impl_type.h" +#include "types/impl_var.h" +#include "types/impl_def_val.h" +#include "types/const_type.h" +#include "types/constant.h" +#include "types/constants.h" +#include "types/impl_arg.h" +#include "types/impl_args.h" +#include "types/impl_func.h" +#include "types/num_exp.h" +#include "types/decl_enum_item.h" +#include "types/decl_enum_items.h" +#include "types/decl_enum.h" +#include "types/decl_enums.h" +#include "types/let_calloc.h" +#include "types/let_callback.h" +#include "types/let_func.h" +#include "types/let_val.h" +#include "types/let_stmt.h" +#include "types/set_func.h" +#include "types/set_value.h" +#include "types/set_values.h" +#include "types/set_stmt.h" +#include "types/return_stmt.h" +#include "types/free_call.h" +#include "types/free_calls.h" +#include "types/free_stmt.h" +#include "types/impl_stmt.h" +#include "types/impl_stmts.h" +#include "types/impl.h" +#include "types/impls.h" +#include "types/decl_file.h" +#include "types/decl_libs.h" + + +static inline int weak_decl_type(decl_type *type) { + switch (type->type) { + case PSI_T_CHAR: + case PSI_T_SHORT: + case PSI_T_INT: + case PSI_T_LONG: + case PSI_T_NAME: + return type->type; + default: + return 0; + } +} + +static inline decl_type *real_decl_type(decl_type *type) { + while (weak_decl_type(type)) { + type = type->real.def->type; + } + return type; +} + +static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) { + unsigned i; + + ZEND_ASSERT(var->arg->var != var); +#if 0 + fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n", + var->name, var->pointer_level, var->arg->var->pointer_level, + var->array_size, var->arg->var->array_size, ret_val); +#endif + for (i = 0; i < var->pointer_level; ++i) { +#if 0 + fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr); +#endif + ret_val = *(void **) ret_val; + } + return ret_val; +} + +static inline impl_val *enref_impl_val(void *ptr, decl_var *var) { + impl_val *val, *val_ptr; + unsigned i; + + ZEND_ASSERT(var->arg->var == var); +#if 0 + fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n", + var->name, var->pointer_level, var->arg->var->pointer_level, + var->array_size, var->arg->var->array_size); +#endif + if (!var->pointer_level ){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) { + return ptr; + } + + val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *)); + for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) { +#if 0 + fprintf(stderr, "++\n"); +#endif + val_ptr->ptr = (void **) val_ptr + 1; + val_ptr = val_ptr->ptr; + } + val_ptr->ptr = ptr; + return val; +} + +static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) { + void *ptr = (char *) struct_ptr + set_arg->layout->pos; +#if 0 + fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr); +#endif + return ptr; +} + + +#define PSI_ERROR 16 +#define PSI_WARNING 32 +typedef void (*psi_error_cb)(void *context, struct psi_token *token, int type, const char *msg, ...); + +#endif diff --git a/src/types/const_type.h b/src/types/const_type.h new file mode 100644 index 0000000..af9efb7 --- /dev/null +++ b/src/types/const_type.h @@ -0,0 +1,21 @@ +#ifndef _PSI_TYPES_CONST_TYPE_H +#define _PSI_TYPES_CONST_TYPE_H + +typedef struct const_type { + token_t type; + char *name; +} const_type; + +static inline const_type *init_const_type(token_t type, const char *name) { + const_type *ct = calloc(1, sizeof(*ct)); + ct->type = type; + ct->name = strdup(name); + return ct; +} + +static inline void free_const_type(const_type *type) { + free(type->name); + free(type); +} + +#endif diff --git a/src/types/constant.h b/src/types/constant.h new file mode 100644 index 0000000..85e467b --- /dev/null +++ b/src/types/constant.h @@ -0,0 +1,25 @@ +#ifndef _PSI_TYPES_CONSTANT_H +#define _PSI_TYPES_CONSTANT_H + +typedef struct constant { + const_type *type; + char *name; + impl_def_val *val; +} constant; + +static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) { + constant *c = calloc(1, sizeof(*c)); + c->type = type; + c->name = strdup(name); + c->val = val; + return c; +} + +static inline void free_constant(constant *constant) { + free_const_type(constant->type); + free(constant->name); + free_impl_def_val(constant->val); + free(constant); +} + +#endif diff --git a/src/types/constants.h b/src/types/constants.h new file mode 100644 index 0000000..36352ab --- /dev/null +++ b/src/types/constants.h @@ -0,0 +1,28 @@ +#ifndef _PSI_TYPES_CONSTANTS_H +#define _PSI_TYPES_CONSTANTS_H + +typedef struct constants { + size_t count; + constant **list; +} constants; + +static inline constants *add_constant(constants *constants, constant *constant) { + if (!constants) { + constants = calloc(1, sizeof(*constants)); + } + constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list)); + constants->list[constants->count-1] = constant; + return constants; +} + +static inline void free_constants(constants *c) { + size_t i; + + for (i = 0; i < c->count; ++i) { + free_constant(c->list[i]); + } + free(c->list); + free(c); +} + +#endif diff --git a/src/types/decl.h b/src/types/decl.h new file mode 100644 index 0000000..0a84998 --- /dev/null +++ b/src/types/decl.h @@ -0,0 +1,29 @@ +#ifndef _PSI_TYPES_DECL_H +#define _PSI_TYPES_DECL_H + +typedef struct decl { + decl_abi *abi; + decl_arg *func; + decl_args *args; + struct impl *impl; + decl_callinfo call; +} decl; + +static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) { + decl *d = calloc(1, sizeof(*d)); + d->abi = abi; + d->func = func; + d->args = args; + return d; +} + +static inline void free_decl(decl *d) { + free_decl_abi(d->abi); + free_decl_arg(d->func); + if (d->args) { + free_decl_args(d->args); + } + free(d); +} + +#endif diff --git a/src/types/decl_abi.h b/src/types/decl_abi.h new file mode 100644 index 0000000..48731a3 --- /dev/null +++ b/src/types/decl_abi.h @@ -0,0 +1,23 @@ +#ifndef _PSI_TYPES_DECL_ABI_H +#define _PSI_TYPES_DECL_ABI_H + +typedef struct decl_abi { + struct psi_token *token; + char *convention; +} decl_abi; + +static inline decl_abi *init_decl_abi(const char *convention) { + decl_abi *abi = calloc(1, sizeof(*abi)); + abi->convention = strdup(convention); + return abi; +} + +static inline void free_decl_abi(decl_abi *abi) { + if (abi->token) { + free(abi->token); + } + free(abi->convention); + free(abi); +} + +#endif diff --git a/src/types/decl_arg.h b/src/types/decl_arg.h new file mode 100644 index 0000000..22eb0f0 --- /dev/null +++ b/src/types/decl_arg.h @@ -0,0 +1,38 @@ +#ifndef _PSI_TYPES_DECL_ARG_H +#define _PSI_TYPES_DECL_ARG_H + +typedef struct decl_arg { + struct psi_token *token; + decl_type *type; + decl_var *var; + decl_struct_layout *layout; + impl_val val; + void *ptr; + void *let; + void *mem; +} decl_arg; + +static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) { + decl_arg *arg = calloc(1, sizeof(*arg)); + arg->token = var->token; + arg->type = type; + arg->var = var; + var->arg = arg; + arg->ptr = &arg->val; + arg->let = arg->ptr; + return arg; +} + +static inline void free_decl_arg(decl_arg *arg) { + if (arg->token && arg->token != arg->var->token) { + free(arg->token); + } + free_decl_type(arg->type); + free_decl_var(arg->var); + if (arg->layout) { + free_decl_struct_layout(arg->layout); + } + free(arg); +} + +#endif diff --git a/src/types/decl_args.h b/src/types/decl_args.h new file mode 100644 index 0000000..5987520 --- /dev/null +++ b/src/types/decl_args.h @@ -0,0 +1,36 @@ +#ifndef _PSI_TYPES_DECL_ARGS_H +#define _PSI_TYPES_DECL_ARGS_H + +typedef struct decl_args { + decl_arg **args; + size_t count; + unsigned varargs:1; +} decl_args; + +static inline decl_args *init_decl_args(decl_arg *arg) { + decl_args *args = calloc(1, sizeof(*args)); + if (arg) { + args->count = 1; + args->args = calloc(1, sizeof(*args->args)); + args->args[0] = arg; + } + return args; +} + +static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) { + args->args = realloc(args->args, ++args->count * sizeof(*args->args)); + args->args[args->count-1] = arg; + return args; +} + +static inline void free_decl_args(decl_args *args) { + size_t i; + + for (i = 0; i < args->count; ++i) { + free_decl_arg(args->args[i]); + } + free(args->args); + free(args); +} + +#endif diff --git a/src/types/decl_callinfo.h b/src/types/decl_callinfo.h new file mode 100644 index 0000000..13e4262 --- /dev/null +++ b/src/types/decl_callinfo.h @@ -0,0 +1,12 @@ +#ifndef _PSI_TYPES_DECL_CALLINFO_H +#define _PSI_TYPES_DECL_CALLINFO_H + +typedef struct decl_callinfo { + void *sym; + void *info; + size_t argc; + void **args; + void **rval; +} decl_callinfo; + +#endif diff --git a/src/types/decl_enum.h b/src/types/decl_enum.h new file mode 100644 index 0000000..4a616af --- /dev/null +++ b/src/types/decl_enum.h @@ -0,0 +1,29 @@ +#ifndef _PSI_TYPES_DECL_ENUM_H +#define _PSI_TYPES_DECL_ENUM_H + +typedef struct decl_enum { + struct psi_token *token; + char *name; + decl_enum_items *items; +} decl_enum; + +static inline decl_enum *init_decl_enum(const char *name, decl_enum_items *l) { + decl_enum *e = calloc(1, sizeof(*e)); + + e->name = strdup(name); + e->items = l; + return e; +} + +static inline void free_decl_enum(decl_enum *e) { + if (e->token) { + free(e->token); + } + if (e->items) { + free_decl_enum_items(e->items); + } + free(e->name); + free(e); +} + +#endif diff --git a/src/types/decl_enum_item.h b/src/types/decl_enum_item.h new file mode 100644 index 0000000..3b976de --- /dev/null +++ b/src/types/decl_enum_item.h @@ -0,0 +1,31 @@ +#ifndef _PSI_TYPES_DECL_ENUM_ITEM_H +#define _PSI_TYPES_DECL_ENUM_ITEM_H + +typedef struct decl_enum_item { + struct psi_token *token; + char *name; + num_exp *num; + num_exp inc; + struct decl_enum_item *prev; +} decl_enum_item; + +static inline decl_enum_item *init_decl_enum_item(const char *name, num_exp *num) { + decl_enum_item *i = calloc(1, sizeof(*i)); + + i->name = strdup(name); + i->num = num; + return i; +} + +static inline void free_decl_enum_item(decl_enum_item *i) { + if (i->token) { + free(i->token); + } + if (i->num && i->num != &i->inc) { + free_num_exp(i->num); + } + free(i->name); + free(i); +} + +#endif diff --git a/src/types/decl_enum_items.h b/src/types/decl_enum_items.h new file mode 100644 index 0000000..0debc0a --- /dev/null +++ b/src/types/decl_enum_items.h @@ -0,0 +1,42 @@ +#ifndef _PSI_TYPES_DECL_ENUM_ITEMS_H +#define _PSI_TYPES_DECL_ENUM_ITEMS_H + +typedef struct decl_enum_items { + decl_enum_item **list; + size_t count; +} decl_enum_items; + +static inline decl_enum_items *init_decl_enum_items(decl_enum_item *i) { + decl_enum_items *l = calloc(1, sizeof(*l)); + + if (i) { + l->count = 1; + l->list = calloc(1, sizeof(*l->list)); + l->list[0] = i; + } + return l; +} + +static inline decl_enum_items *add_decl_enum_item(decl_enum_items *l, decl_enum_item *i) { + l->list = realloc(l->list, sizeof(*l->list) * (l->count + 1)); + l->list[l->count] = i; + if (l->count) { + i->prev = l->list[l->count - 1]; + } + ++l->count; + return l; +} + +static inline void free_decl_enum_items(decl_enum_items *l) { + if (l->list) { + size_t j; + + for (j = 0; j < l->count; ++j) { + free_decl_enum_item(l->list[j]); + } + free(l->list); + } + free(l); +} + +#endif diff --git a/src/types/decl_enums.h b/src/types/decl_enums.h new file mode 100644 index 0000000..61a3f72 --- /dev/null +++ b/src/types/decl_enums.h @@ -0,0 +1,30 @@ +#ifndef _PSI_TYPES_DECL_ENUMS_H +#define _PSI_TYPES_DECL_ENUMS_H + +typedef struct decl_enums { + decl_enum **list; + size_t count; +} decl_enums; + +static inline decl_enums* add_decl_enum(decl_enums *es, decl_enum *e) { + if (!es) { + es = calloc(1, sizeof(*es)); + } + es->list = realloc(es->list, ++es->count * sizeof(*es->list)); + es->list[es->count-1] = e; + return es; +} + +static inline void free_decl_enums(decl_enums *es) { + if (es->list) { + size_t j; + + for (j = 0; j < es->count; ++j) { + free_decl_enum(es->list[j]); + } + } + free(es->list); + free(es); +} + +#endif diff --git a/src/types/decl_file.h b/src/types/decl_file.h new file mode 100644 index 0000000..3eb314c --- /dev/null +++ b/src/types/decl_file.h @@ -0,0 +1,19 @@ +#ifndef _PSI_TYPES_DECL_FILE_H +#define _PSI_TYPES_DECL_FILE_H + +typedef struct decl_file { + char *ln; + char *fn; +} decl_file; + +static inline void free_decl_file(decl_file *file) { + if (file->ln) { + free(file->ln); + } + if (file->fn) { + free(file->fn); + } + memset(file, 0, sizeof(*file)); +} + +#endif diff --git a/src/types/decl_libs.h b/src/types/decl_libs.h new file mode 100644 index 0000000..0ac669e --- /dev/null +++ b/src/types/decl_libs.h @@ -0,0 +1,27 @@ +#ifndef _PSI_TYPES_DECL_LIBS_H +#define _PSI_TYPES_DECL_LIBS_H + +typedef struct decl_libs { + void **dl; + size_t count; +} decl_libs; + +static inline void free_decl_libs(decl_libs *libs) { + if (libs->dl) { + size_t i; + for (i = 0; i < libs->count; ++i) { + if (libs->dl[i]) { + dlclose(libs->dl[i]); + } + } + free(libs->dl); + } + memset(libs, 0, sizeof(*libs)); +} + +static inline void add_decl_lib(decl_libs *libs, void *dlopened) { + libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl)); + libs->dl[libs->count-1] = dlopened; +} + +#endif diff --git a/src/types/decl_struct.h b/src/types/decl_struct.h new file mode 100644 index 0000000..439b4e9 --- /dev/null +++ b/src/types/decl_struct.h @@ -0,0 +1,37 @@ +#ifndef _PSI_TYPES_DECL_STRUCT_H +#define _PSI_TYPES_DECL_STRUCT_H + +typedef struct decl_struct { + struct psi_token *token; + char *name; + decl_args *args; + size_t size; + size_t align; + struct { + void *type; + void (*dtor)(void *type); + } engine; +} decl_struct; + +static inline decl_struct *init_decl_struct(const char *name, decl_args *args) { + decl_struct *s = calloc(1, sizeof(*s)); + s->name = strdup(name); + s->args = args; + return s; +} + +static inline void free_decl_struct(decl_struct *s) { + if (s->token) { + free(s->token); + } + if (s->args) { + free_decl_args(s->args); + } + if (s->engine.type && s->engine.dtor) { + s->engine.dtor(s->engine.type); + } + free(s->name); + free(s); +} + +#endif diff --git a/src/types/decl_struct_layout.h b/src/types/decl_struct_layout.h new file mode 100644 index 0000000..1fcb9f0 --- /dev/null +++ b/src/types/decl_struct_layout.h @@ -0,0 +1,21 @@ +#ifndef _PSI_TYPES_DECL_STRUCT_LAYOUT_H +#define _PSI_TYPES_DECL_STRUCT_LAYOUT_H + +typedef struct decl_struct_layout { + size_t pos; + size_t len; +} decl_struct_layout; + +static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) { + decl_struct_layout *l = calloc(1, sizeof(*l)); + ZEND_ASSERT(pos+len); + l->pos = pos; + l->len = len; + return l; +} + +static inline void free_decl_struct_layout(decl_struct_layout *l) { + free(l); +} + +#endif diff --git a/src/types/decl_structs.h b/src/types/decl_structs.h new file mode 100644 index 0000000..1db3396 --- /dev/null +++ b/src/types/decl_structs.h @@ -0,0 +1,28 @@ +#ifndef _PSI_TYPES_DECL_STRUCTS_H +#define _PSI_TYPES_DECL_STRUCTS_H + +typedef struct decl_structs { + size_t count; + decl_struct **list; +} decl_structs; + +static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) { + if (!ss) { + ss = calloc(1, sizeof(*ss)); + } + ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list)); + ss->list[ss->count-1] = s; + return ss; +} + +static inline void free_decl_structs(decl_structs *ss) { + size_t i; + + for (i = 0; i < ss->count; ++i) { + free_decl_struct(ss->list[i]); + } + free(ss->list); + free(ss); +} + +#endif diff --git a/src/types/decl_type.h b/src/types/decl_type.h new file mode 100644 index 0000000..8cbb2fc --- /dev/null +++ b/src/types/decl_type.h @@ -0,0 +1,39 @@ +#ifndef _PSI_TYPES_DECL_TYPE_H +#define _PSI_TYPES_DECL_TYPE_H + +#include "parser_proc.h" + +typedef struct decl_type { + struct psi_token *token; + char *name; + token_t type; + union { + struct decl_arg *def; + struct decl_struct *strct; + struct decl_union *unn; + struct decl_enum *enm; + struct decl *func; + } real; +} decl_type; + +static inline decl_type *init_decl_type(token_t type, const char *name) { + decl_type *t = calloc(1, sizeof(*t)); + t->type = type; + t->name = strdup(name); + return t; +} + +static inline void free_decl(struct decl *decl); +static inline void free_decl_type(decl_type *type) { + if (type->token) { + free(type->token); + } + if (type->type == PSI_T_FUNCTION) { + free_decl(type->real.func); + } + free(type->name); + free(type); +} + + +#endif diff --git a/src/types/decl_typedefs.h b/src/types/decl_typedefs.h new file mode 100644 index 0000000..e58a2f5 --- /dev/null +++ b/src/types/decl_typedefs.h @@ -0,0 +1,28 @@ +#ifndef _PSI_TYPES_DECL_TYPEDEFS_H +#define _PSI_TYPES_DECL_TYPEDEFS_H + +typedef struct decl_typedefs { + size_t count; + decl_arg **list; +} decl_typedefs; + +static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_arg *def) { + if (!defs) { + defs = calloc(1, sizeof(*defs)); + } + defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list)); + defs->list[defs->count-1] = def; + return defs; +} + +static inline void free_decl_typedefs(decl_typedefs *defs) { + size_t i; + + for (i = 0; i < defs->count; ++i) { + free_decl_arg(defs->list[i]); + } + free(defs->list); + free(defs); +} + +#endif diff --git a/src/types/decl_union.h b/src/types/decl_union.h new file mode 100644 index 0000000..3bd031b --- /dev/null +++ b/src/types/decl_union.h @@ -0,0 +1,29 @@ +#ifndef _PSI_TYPES_DECL_UNION_H + +typedef struct decl_union { + struct psi_token *token; + char *name; + decl_args *args; + size_t size; + size_t align; +} decl_union; + +static inline decl_union *init_decl_union(const char *name, decl_args *args) { + decl_union *u = calloc(1, sizeof(*u)); + u->name = strdup(name); + u->args = args; + return u; +} + +static inline void free_decl_union(decl_union *u) { + if (u->token) { + free(u->token); + } + if (u->args) { + free_decl_args(u->args); + } + free(u->name); + free(u); +} + +#endif diff --git a/src/types/decl_unions.h b/src/types/decl_unions.h new file mode 100644 index 0000000..49c6b73 --- /dev/null +++ b/src/types/decl_unions.h @@ -0,0 +1,28 @@ +#ifndef _PSI_TYPES_DECL_UNOINS_H +#define _PSI_TYPES_DECL_UNOINS_H + +typedef struct decl_unions { + decl_union **list; + size_t count; +} decl_unions; + +static inline decl_unions *add_decl_union(decl_unions *uu, decl_union *u) { + if (!uu) { + uu = calloc(1, sizeof(*uu)); + } + uu->list = realloc(uu->list, ++uu->count * sizeof(*uu->list)); + uu->list[uu->count-1] = u; + return uu; +} + +static inline void free_decl_unions(decl_unions *uu) { + size_t i; + + for (i = 0; i < uu->count; ++i) { + free_decl_union(uu->list[i]); + } + free(uu->list); + free(uu); +} + +#endif diff --git a/src/types/decl_var.h b/src/types/decl_var.h new file mode 100644 index 0000000..166a69e --- /dev/null +++ b/src/types/decl_var.h @@ -0,0 +1,39 @@ +#ifndef _PSI_TYPES_DECL_VAR_H +#define _PSI_TYPES_DECL_VAR_H + +typedef struct decl_var { + struct psi_token *token; + char *name; + unsigned pointer_level; + unsigned array_size; + struct decl_arg *arg; +} decl_var; + +static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) { + decl_var *v = calloc(1, sizeof(*v)); + v->name = (char *) strdup((const char *) name); + v->pointer_level = pl; + v->array_size = as; + return v; +} + +static inline decl_var *copy_decl_var(decl_var *src) { + decl_var *dest = calloc(1, sizeof(*dest)); + + memcpy(dest, src, sizeof(*dest)); + dest->name = strdup(dest->name); + if (dest->token) { + dest->token = psi_token_copy(dest->token); + } + return dest; +} + +static inline void free_decl_var(decl_var *var) { + if (var->token) { + free(var->token); + } + free(var->name); + free(var); +} + +#endif diff --git a/src/types/decl_vars.h b/src/types/decl_vars.h new file mode 100644 index 0000000..46c65bd --- /dev/null +++ b/src/types/decl_vars.h @@ -0,0 +1,35 @@ +#ifndef _PSI_TYPES_DECL_VARS_H +#define _PSI_TYPES_DECL_VARS_H + +typedef struct decl_vars { + decl_var **vars; + size_t count; +} decl_vars; + +static inline decl_vars *init_decl_vars(decl_var *var) { + decl_vars *vars = calloc(1, sizeof(*vars)); + if (var) { + vars->count = 1; + vars->vars = calloc(1, sizeof(*vars->vars)); + vars->vars[0] = var; + } + return vars; +} + +static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) { + vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars)); + vars->vars[vars->count-1] = var; + return vars; +} + +static inline void free_decl_vars(decl_vars *vars) { + size_t i; + + for (i = 0; i < vars->count; ++i) { + free_decl_var(vars->vars[i]); + } + free(vars->vars); + free(vars); +} + +#endif diff --git a/src/types/decls.h b/src/types/decls.h new file mode 100644 index 0000000..7f40b7c --- /dev/null +++ b/src/types/decls.h @@ -0,0 +1,28 @@ +#ifndef _PSI_TYPES_DECLS_H +#define _PSI_TYPES_DECLS_H + +typedef struct decls { + size_t count; + decl **list; +} decls; + +static inline decls *add_decl(decls *decls, decl *decl) { + if (!decls) { + decls = calloc(1, sizeof(*decls)); + } + decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list)); + decls->list[decls->count-1] = decl; + return decls; +} + +static inline void free_decls(decls *decls) { + size_t i; + + for (i = 0; i < decls->count; ++i) { + free_decl(decls->list[i]); + } + free(decls->list); + free(decls); +} + +#endif diff --git a/src/types/free_call.h b/src/types/free_call.h new file mode 100644 index 0000000..fec0daa --- /dev/null +++ b/src/types/free_call.h @@ -0,0 +1,27 @@ +#ifndef _PSI_TYPES_FREE_CALL_H +#define _PSI_TYPES_FREE_CALL_H + +typedef struct free_call { + struct psi_token *token; + char *func; + decl_vars *vars; + decl *decl; +} free_call; + +static inline free_call *init_free_call(const char *func, decl_vars *vars) { + free_call *f = calloc(1, sizeof(*f)); + f->func = strdup(func); + f->vars = vars; + return f; +} + +static inline void free_free_call(free_call *f) { + if (f->token) { + free(f->token); + } + free(f->func); + free_decl_vars(f->vars); + free(f); +} + +#endif diff --git a/src/types/free_calls.h b/src/types/free_calls.h new file mode 100644 index 0000000..7d4f575 --- /dev/null +++ b/src/types/free_calls.h @@ -0,0 +1,35 @@ +#ifndef _PSI_TYPES_FREE_CALLS_H +#define _PSI_TYPES_FREE_CALLS_H + +typedef struct free_calls { + free_call **list; + size_t count; +} free_calls; + +static inline free_calls *init_free_calls(free_call *f) { + free_calls *fcs = calloc(1, sizeof(*fcs)); + if (f) { + fcs->count = 1; + fcs->list = calloc(1, sizeof(*fcs->list)); + fcs->list[0] = f; + } + return fcs; +} + +static inline void free_free_calls(free_calls *fcs) { + size_t i; + + for (i = 0; i < fcs->count; ++i) { + free_free_call(fcs->list[i]); + } + free(fcs->list); + free(fcs); +} + +static inline free_calls *add_free_call(free_calls *fcs, free_call *f) { + fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list)); + fcs->list[fcs->count-1] = f; + return fcs; +} + +#endif diff --git a/src/types/free_stmt.h b/src/types/free_stmt.h new file mode 100644 index 0000000..a5eceb8 --- /dev/null +++ b/src/types/free_stmt.h @@ -0,0 +1,19 @@ +#ifndef _PSI_TYPES_FREE_STMT_H +#define _PSI_TYPES_FREE_STMT_H + +typedef struct free_stmt { + free_calls *calls; +} free_stmt; + +static inline free_stmt *init_free_stmt(free_calls *calls) { + free_stmt *f = calloc(1, sizeof(*f)); + f->calls = calls; + return f; +} + +static inline void free_free_stmt(free_stmt *f) { + free_free_calls(f->calls); + free(f); +} + +#endif diff --git a/src/types/impl.h b/src/types/impl.h new file mode 100644 index 0000000..11270fa --- /dev/null +++ b/src/types/impl.h @@ -0,0 +1,23 @@ +#ifndef _PSI_TYPES_IMPL_H +#define _PSI_TYPES_IMPL_H + +typedef struct impl { + impl_func *func; + impl_stmts *stmts; + decl *decl; +} impl; + +static inline impl *init_impl(impl_func *func, impl_stmts *stmts) { + impl *i = calloc(1, sizeof(*i)); + i->func = func; + i->stmts = stmts; + return i; +} + +static inline void free_impl(impl *impl) { + free_impl_func(impl->func); + free_impl_stmts(impl->stmts); + free(impl); +} + +#endif diff --git a/src/types/impl_arg.h b/src/types/impl_arg.h new file mode 100644 index 0000000..4f870e0 --- /dev/null +++ b/src/types/impl_arg.h @@ -0,0 +1,38 @@ +#ifndef _PSI_TYPES_IMPL_ARG_H +#define _PSI_TYPES_IMPL_ARG_H + +typedef struct impl_arg { + impl_type *type; + impl_var *var; + impl_def_val *def; + impl_val val; + zval *_zv; +} impl_arg; + +typedef struct impl_vararg { + impl_arg *name; + struct impl_args *args; + token_t *types; + impl_val *values; + void **free_list; +} impl_vararg; + +static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) { + impl_arg *arg = calloc(1, sizeof(*arg)); + arg->type = type; + arg->var = var; + arg->var->arg = arg; + arg->def = def; + return arg; +} + +static inline void free_impl_arg(impl_arg *arg) { + free_impl_type(arg->type); + free_impl_var(arg->var); + if (arg->def) { + free_impl_def_val(arg->def); + } + free(arg); +} + +#endif diff --git a/src/types/impl_args.h b/src/types/impl_args.h new file mode 100644 index 0000000..3894405 --- /dev/null +++ b/src/types/impl_args.h @@ -0,0 +1,39 @@ +#ifndef _PSI_TYPES_IMPL_ARGS_H +#define _PSI_TYPES_IMPL_ARGS_H + +typedef struct impl_args { + impl_arg **args; + size_t count; + impl_vararg vararg; +} impl_args; + +static inline impl_args *init_impl_args(impl_arg *arg) { + impl_args *args = calloc(1, sizeof(*args)); + if (arg) { + args->count = 1; + args->args = calloc(1, sizeof(*args->args)); + args->args[0] = arg; + } + return args; +} + +static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) { + args->args = realloc(args->args, ++args->count * sizeof(*args->args)); + args->args[args->count-1] = arg; + return args; +} + +static inline void free_impl_args(impl_args *args) { + size_t i; + + for (i = 0; i < args->count; ++i) { + free_impl_arg(args->args[i]); + } + if (args->vararg.name) { + free_impl_arg(args->vararg.name); + } + free(args->args); + free(args); +} + +#endif diff --git a/src/types/impl_def_val.h b/src/types/impl_def_val.h new file mode 100644 index 0000000..189e349 --- /dev/null +++ b/src/types/impl_def_val.h @@ -0,0 +1,21 @@ +#ifndef _PSI_TYPES_IMPL_DEF_VAL_H +#define _PSI_TYPES_IMPL_DEF_VAL_H + +typedef struct impl_def_val { + token_t type; + char *text; +} impl_def_val; + +static inline impl_def_val *init_impl_def_val(token_t t, const char *text) { + impl_def_val *def = calloc(1, sizeof(*def)); + def->type = t; + def->text = strdup(text); + return def; +} + +static inline void free_impl_def_val(impl_def_val *def) { + free(def->text); + free(def); +} + +#endif diff --git a/src/types/impl_func.h b/src/types/impl_func.h new file mode 100644 index 0000000..a9d6270 --- /dev/null +++ b/src/types/impl_func.h @@ -0,0 +1,31 @@ +#ifndef _PSI_TYPES_IMPL_FUNC_H +#define _PSI_TYPES_IMPL_FUNC_H + +typedef struct impl_func { + struct psi_token *token; + char *name; + impl_args *args; + impl_type *return_type; + unsigned return_reference:1; +} impl_func; + +static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) { + impl_func *func = calloc(1, sizeof(*func)); + func->name = strdup(name); + func->args = args ? args : init_impl_args(NULL); + func->return_type = type; + func->return_reference = ret_reference; + return func; +} + +static inline void free_impl_func(impl_func *f) { + if (f->token) { + free(f->token); + } + free_impl_type(f->return_type); + free_impl_args(f->args); + free(f->name); + free(f); +} + +#endif diff --git a/src/types/impl_stmt.h b/src/types/impl_stmt.h new file mode 100644 index 0000000..c110ddd --- /dev/null +++ b/src/types/impl_stmt.h @@ -0,0 +1,40 @@ +#ifndef _PSI_TYPES_IMPL_STMT_H +#define _PSI_TYPES_IMPL_STMT_H + +typedef struct impl_stmt { + token_t type; + union { + let_stmt *let; + set_stmt *set; + return_stmt *ret; + free_stmt *fre; + void *ptr; + } s; +} impl_stmt; + +static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) { + impl_stmt *stmt = calloc(1, sizeof(*stmt)); + stmt->type = type; + stmt->s.ptr = ptr; + return stmt; +} + +static inline void free_impl_stmt(impl_stmt *stmt) { + switch (stmt->type) { + case PSI_T_LET: + free_let_stmt(stmt->s.let); + break; + case PSI_T_SET: + free_set_stmt(stmt->s.set); + break; + case PSI_T_RETURN: + free_return_stmt(stmt->s.ret); + break; + case PSI_T_FREE: + free_free_stmt(stmt->s.fre); + break; + } + free(stmt); +} + +#endif diff --git a/src/types/impl_stmts.h b/src/types/impl_stmts.h new file mode 100644 index 0000000..f7b980d --- /dev/null +++ b/src/types/impl_stmts.h @@ -0,0 +1,75 @@ +#ifndef _PSI_TYPES_IMPL_STMTS_H +#define _PSI_TYPES_IMPL_STMTS_H + +typedef struct impl_stmts { + struct { + return_stmt **list; + size_t count; + } ret; + struct { + let_stmt **list; + size_t count; + } let; + struct { + set_stmt **list; + size_t count; + } set; + struct { + free_stmt **list; + size_t count; + } fre; +} impl_stmts; + +static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) { + list = realloc(list, count * sizeof(list)); + ((void **)list)[count-1] = stmt; + return list; +} + +static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) { + switch (stmt->type) { + case PSI_T_RETURN: + stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret); + break; + case PSI_T_LET: + stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let); + break; + case PSI_T_SET: + stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set); + break; + case PSI_T_FREE: + stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre); + break; + } + free(stmt); + return stmts; +} + +static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) { + impl_stmts *stmts = calloc(1, sizeof(*stmts)); + return add_impl_stmt(stmts, stmt); +} + +static inline void free_impl_stmts(impl_stmts *stmts) { + size_t i; + + for (i = 0; i < stmts->let.count; ++i) { + free_let_stmt(stmts->let.list[i]); + } + free(stmts->let.list); + for (i = 0; i < stmts->ret.count; ++i) { + free_return_stmt(stmts->ret.list[i]); + } + free(stmts->ret.list); + for (i = 0; i < stmts->set.count; ++i) { + free_set_stmt(stmts->set.list[i]); + } + free(stmts->set.list); + for (i = 0; i < stmts->fre.count; ++i) { + free_free_stmt(stmts->fre.list[i]); + } + free(stmts->fre.list); + free(stmts); +} + +#endif diff --git a/src/types/impl_type.h b/src/types/impl_type.h new file mode 100644 index 0000000..9f7e894 --- /dev/null +++ b/src/types/impl_type.h @@ -0,0 +1,22 @@ +#ifndef _PSI_TYPES_IMPL_TYPE_H +#define _PSI_TYPES_IMPL_TYPE_H + +typedef struct impl_type { + char *name; + token_t type; +} impl_type; + +static inline impl_type *init_impl_type(token_t type, const char *name) { + impl_type *t = calloc(1, sizeof(*t)); + + t->type = type; + t->name = strdup(name); + return t; +} + +static inline void free_impl_type(impl_type *type) { + free(type->name); + free(type); +} + +#endif diff --git a/src/types/impl_val.h b/src/types/impl_val.h new file mode 100644 index 0000000..4434690 --- /dev/null +++ b/src/types/impl_val.h @@ -0,0 +1,34 @@ +#ifndef _PSI_TYPES_IMPL_VAL_H +#define _PSI_TYPES_IMPL_VAL_H + +#include "Zend/zend_types.h" + +typedef union impl_val { + char cval; + int8_t i8; + uint8_t u8; + short sval; + int16_t i16; + uint16_t u16; + int ival; + int32_t i32; + uint32_t u32; + long lval; + int64_t i64; + uint64_t u64; + float fval; + double dval; +#ifdef HAVE_LONG_DOUBLE + long double ldval; +#endif + union { + zend_bool bval; + zend_long lval; + zend_string *str; + zend_fcall *cb; + } zend; + void *ptr; +} impl_val; + + +#endif diff --git a/src/types/impl_var.h b/src/types/impl_var.h new file mode 100644 index 0000000..9b8b39b --- /dev/null +++ b/src/types/impl_var.h @@ -0,0 +1,37 @@ +#ifndef _PSI_TYPES_IMPL_VAR_H +#define _PSI_TYPES_IMPL_VAR_H + +typedef struct impl_var { + struct psi_token *token; + char *name; + struct impl_arg *arg; + unsigned reference:1; +} impl_var; + +static inline impl_var *init_impl_var(const char *name, int is_reference) { + impl_var *var = calloc(1, sizeof(*var)); + var->name = strdup(name); + var->reference = is_reference; + return var; +} + +static inline impl_var *copy_impl_var(impl_var *var) { + impl_var *cpy = malloc(sizeof(*cpy)); + + memcpy(cpy, var, sizeof(*cpy)); + cpy->name = strdup(cpy->name); + if (cpy->token) { + cpy->token = psi_token_copy(cpy->token); + } + return cpy; +} + +static inline void free_impl_var(impl_var *var) { + if (var->token) { + free(var->token); + } + free(var->name); + free(var); +} + +#endif diff --git a/src/types/impls.h b/src/types/impls.h new file mode 100644 index 0000000..8bf17fb --- /dev/null +++ b/src/types/impls.h @@ -0,0 +1,28 @@ +#ifndef _PSI_TYPES_IMPLS_H +#define _PSI_TYPES_IMPLS_H + +typedef struct impls { + size_t count; + impl **list; +} impls; + +static inline impls *add_impl(impls *impls, impl *impl) { + if (!impls) { + impls = calloc(1, sizeof(*impls)); + } + impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list)); + impls->list[impls->count-1] = impl; + return impls; +} + +static inline void free_impls(impls *impls) { + size_t i; + + for (i = 0; i < impls->count; ++i) { + free_impl(impls->list[i]); + } + free(impls->list); + free(impls); +} + +#endif diff --git a/src/types/let_callback.h b/src/types/let_callback.h new file mode 100644 index 0000000..0653b3d --- /dev/null +++ b/src/types/let_callback.h @@ -0,0 +1,26 @@ +#ifndef _PSI_TYPES_LET_CALLBACK_H +#define _PSI_TYPES_LET_CALLBACK_H + +typedef struct let_callback { + struct let_func *func; + struct set_values *args; + decl *decl; +} let_callback; + +static inline void free_let_func(struct let_func *func); +static inline void free_set_values(struct set_values *vals); +static inline let_callback *init_let_callback(struct let_func *func, struct set_values *args) { + let_callback *cb = calloc(1, sizeof(*cb)); + + cb->func = func; + cb->args = args; + return cb; +} + +static inline void free_let_callback(let_callback *cb) { + free_let_func(cb->func); + free_set_values(cb->args); + free(cb); +} + +#endif diff --git a/src/types/let_calloc.h b/src/types/let_calloc.h new file mode 100644 index 0000000..e6d3f91 --- /dev/null +++ b/src/types/let_calloc.h @@ -0,0 +1,22 @@ +#ifndef _PSI_TYPES_LET_CALLOC_H +#define _PSI_TYPES_LET_CALLOC_H + +typedef struct let_calloc { + num_exp *nmemb; + num_exp *size; +} let_calloc; + +static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) { + let_calloc *alloc = calloc(1, sizeof(*alloc)); + alloc->nmemb = nmemb; + alloc->size = size; + return alloc; +} + +static inline void free_let_calloc(let_calloc *alloc) { + free_num_exp(alloc->nmemb); + free_num_exp(alloc->size); + free(alloc); +} + +#endif diff --git a/src/types/let_func.h b/src/types/let_func.h new file mode 100644 index 0000000..526265b --- /dev/null +++ b/src/types/let_func.h @@ -0,0 +1,27 @@ +#ifndef _PSI_TYPES_LET_FUNC_H +#define _PSI_TYPES_LET_FUNC_H + +typedef impl_val *(*let_func_handler)(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free); + +typedef struct let_func { + token_t type; + char *name; + impl_var *var; + let_func_handler handler; +} let_func; + +static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) { + let_func *func = calloc(1, sizeof(*func)); + func->type = type; + func->name = strdup(name); + func->var = var; + return func; +} + +static inline void free_let_func(let_func *func) { + free_impl_var(func->var); + free(func->name); + free(func); +} + +#endif diff --git a/src/types/let_stmt.h b/src/types/let_stmt.h new file mode 100644 index 0000000..8415e49 --- /dev/null +++ b/src/types/let_stmt.h @@ -0,0 +1,27 @@ +#ifndef _PSI_TYPES_LET_STMT_H +#define _PSI_TYPES_LET_STMT_H + +typedef struct let_stmt { + decl_var *var; + let_val *val; +} let_stmt; + +static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) { + let_stmt *let = calloc(1, sizeof(*let)); + let->var = var; + let->val = val; + return let; +} + +static inline void free_let_stmt(let_stmt *stmt) { + if (stmt->val) { + if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) { + free_decl_arg(stmt->var->arg); + } + free_let_val(stmt->val); + } + free_decl_var(stmt->var); + free(stmt); +} + +#endif diff --git a/src/types/let_val.h b/src/types/let_val.h new file mode 100644 index 0000000..7d5acfd --- /dev/null +++ b/src/types/let_val.h @@ -0,0 +1,80 @@ +#ifndef _PSI_TYPES_LET_VAL_H +#define _PSI_TYPES_LET_VAL_H + + +enum let_val_kind { + PSI_LET_NULL, + PSI_LET_NUMEXP, + PSI_LET_CALLOC, + PSI_LET_CALLBACK, + PSI_LET_FUNC, + PSI_LET_TMP, +}; +#define PSI_LET_REFERENCE 0x1; +typedef struct let_val { + enum let_val_kind kind; + union { + num_exp *num; + let_calloc *alloc; + let_callback *callback; + let_func *func; + decl_var *var; + } data; + union { + struct { + unsigned is_reference:1; + } one; + unsigned all; + } flags; +} let_val; + +static inline let_val *init_let_val(enum let_val_kind kind, void *data) { + let_val *let = calloc(1, sizeof(*let)); + switch (let->kind = kind) { + case PSI_LET_NULL: + break; + case PSI_LET_NUMEXP: + let->data.num = data; + break; + case PSI_LET_CALLOC: + let->data.alloc = data; + break; + case PSI_LET_CALLBACK: + let->data.callback = data; + break; + case PSI_LET_FUNC: + let->data.func = data; + break; + case PSI_LET_TMP: + let->data.var = data; + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } + return let; +} + +static inline void free_let_val(let_val *let) { + switch (let->kind) { + case PSI_LET_NULL: + break; + case PSI_LET_NUMEXP: + free_num_exp(let->data.num); + break; + case PSI_LET_CALLOC: + free_let_calloc(let->data.alloc); + break; + case PSI_LET_CALLBACK: + free_let_callback(let->data.callback); + break; + case PSI_LET_FUNC: + free_let_func(let->data.func); + break; + case PSI_LET_TMP: + free_decl_var(let->data.var); + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } + free(let); +} + +#endif diff --git a/src/types/num_exp.h b/src/types/num_exp.h new file mode 100644 index 0000000..c54a5af --- /dev/null +++ b/src/types/num_exp.h @@ -0,0 +1,85 @@ +#ifndef _PSI_TYPES_NUM_EXP +#define _PSI_TYPES_NUM_EXP + +typedef struct num_exp { + struct psi_token *token; + token_t t; + union { + char *numb; + constant *cnst; + decl_var *dvar; + struct decl_enum_item *enm; + } u; + token_t operator; + int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res); + struct num_exp *operand; +} num_exp; + +static inline num_exp *init_num_exp(token_t t, void *num) { + num_exp *exp = calloc(1, sizeof(*exp)); + switch (exp->t = t) { + case PSI_T_NUMBER: + case PSI_T_NSNAME: + exp->u.numb = strdup(num); + break; + case PSI_T_NAME: + exp->u.dvar = num; + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } + return exp; +} + +static inline num_exp *copy_num_exp(num_exp *exp) { + decl_var *dvar; + num_exp *num = calloc(1, sizeof(*num)); + + memcpy(num, exp, sizeof(*num)); + + if (num->token) { + num->token = psi_token_copy(num->token); + } + if (num->operand) { + num->operand = copy_num_exp(num->operand); + } + switch (num->t) { + case PSI_T_NUMBER: + case PSI_T_NSNAME: + num->u.numb = strdup(num->u.numb); + break; + case PSI_T_NAME: + dvar = init_decl_var(num->u.dvar->name, num->u.dvar->pointer_level, num->u.dvar->array_size); + dvar->arg = num->u.dvar->arg; + if (num->u.dvar->token) { + dvar->token = psi_token_copy(num->u.dvar->token); + } + num->u.dvar = dvar; + break; + } + return num; +} + +static inline void free_num_exp(num_exp *exp) { + if (exp->token) { + free(exp->token); + } + switch (exp->t) { + case PSI_T_NUMBER: + free(exp->u.numb); + break; + case PSI_T_NSNAME: + break; + case PSI_T_NAME: + free_decl_var(exp->u.dvar); + break; + case PSI_T_ENUM: + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } + if (exp->operand) { + free_num_exp(exp->operand); + } + free(exp); +} + +#endif diff --git a/src/types/return_stmt.h b/src/types/return_stmt.h new file mode 100644 index 0000000..12e371e --- /dev/null +++ b/src/types/return_stmt.h @@ -0,0 +1,24 @@ +#ifndef _PSI_TYPES_RETURN_STMT_H +#define _PSI_TYPES_RETURN_STMT_H + +typedef struct return_stmt { + struct psi_token *token; + set_value *set; + decl_arg *decl; +} return_stmt; + +static inline return_stmt *init_return_stmt(set_value *val) { + return_stmt *ret = calloc(1, sizeof(*ret)); + ret->set = val; + return ret; +} + +static inline void free_return_stmt(return_stmt *ret) { + if (ret->token) { + free(ret->token); + } + free_set_value(ret->set); + free(ret); +} + +#endif diff --git a/src/types/set_func.h b/src/types/set_func.h new file mode 100644 index 0000000..54d61d3 --- /dev/null +++ b/src/types/set_func.h @@ -0,0 +1,28 @@ +#ifndef _PSI_TYPES_SET_FUNC_H +#define _PSI_TYPES_SET_FUNC_H + +struct set_value; + +typedef struct set_func { + struct psi_token *token; + token_t type; + char *name; + void (*handler)(zval *, struct set_value *set, impl_val *ret_val); +} set_func; + +static inline set_func *init_set_func(token_t type, const char *name) { + set_func *func = calloc(1, sizeof(*func)); + func->type = type; + func->name = strdup(name); + return func; +} + +static inline void free_set_func(set_func *func) { + if (func->token) { + free(func->token); + } + free(func->name); + free(func); +} + +#endif diff --git a/src/types/set_stmt.h b/src/types/set_stmt.h new file mode 100644 index 0000000..360b324 --- /dev/null +++ b/src/types/set_stmt.h @@ -0,0 +1,23 @@ +#ifndef _PSI_TYPES_SET_STMT_H +#define _PSI_TYPES_SET_STMT_H + +typedef struct set_stmt { + impl_var *var; + set_value *val; + impl_arg *arg; +} set_stmt; + +static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) { + set_stmt *set = calloc(1, sizeof(*set)); + set->var = var; + set->val = val; + return set; +} + +static inline void free_set_stmt(set_stmt *set) { + free_impl_var(set->var); + free_set_value(set->val); + free(set); +} + +#endif diff --git a/src/types/set_value.h b/src/types/set_value.h new file mode 100644 index 0000000..0b6b269 --- /dev/null +++ b/src/types/set_value.h @@ -0,0 +1,45 @@ +#ifndef _PSI_TYPES_SET_VALUE_H +#define _PSI_TYPES_SET_VALUE_H + +typedef struct set_value { + set_func *func; + decl_vars *vars; + num_exp *num; + struct { + struct set_value *set; + impl_val *val; + } outer; + struct set_values *inner; +} set_value; + +static inline set_value *init_set_value(set_func *func, decl_vars *vars) { + set_value *val = calloc(1, sizeof(*val)); + val->func = func; + val->vars = vars; + return val; +} + +static inline struct set_values *add_set_value(struct set_values *vals, struct set_value *val); +static inline set_value *add_inner_set_value(set_value *val, set_value *inner) { + val->inner = add_set_value(val->inner, inner); + inner->outer.set = val; + return val; +} + +static inline void free_set_value(set_value *val) { + if (val->func) { + free_set_func(val->func); + } + if (val->vars) { + free_decl_vars(val->vars); + } + if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) { + free_set_values(val->inner); + } + if (val->num) { + free_num_exp(val->num); + } + free(val); +} + +#endif diff --git a/src/types/set_values.h b/src/types/set_values.h new file mode 100644 index 0000000..b089372 --- /dev/null +++ b/src/types/set_values.h @@ -0,0 +1,40 @@ +#ifndef _PSI_TYPES_SET_VALUES_H +#define _PSI_TYPES_SET_VALUES_H + +typedef struct set_values { + struct set_value **vals; + size_t count; +} set_values; + +static inline set_values *init_set_values(struct set_value *val) { + set_values *vals = calloc(1, sizeof(*vals)); + if (val) { + vals->count = 1; + vals->vals = calloc(1, sizeof(val)); + vals->vals[0] = val; + } + return vals; +} + +static inline set_values *add_set_value(set_values *vals, struct set_value *val) { + if (!vals) { + vals = calloc(1, sizeof(*vals)); + } + vals->vals = realloc(vals->vals, ++vals->count * sizeof(val)); + vals->vals[vals->count-1] = val; + return vals; +} + +static inline void free_set_values(set_values *vals) { + if (vals->vals) { + size_t i; + + for (i = 0; i < vals->count; ++i) { + free_set_value(vals->vals[i]); + } + free(vals->vals); + } + free(vals); +} + +#endif -- 2.30.2