From a0f437f26cd0f121ee911a55327a68a3544bf15f Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 20 Nov 2018 15:33:57 +0100 Subject: [PATCH] commit after reset fuckup --- .gdbinit | 2 +- php_psi.h | 45 +++++ src/call.c | 7 +- src/context.c | 30 +--- src/cpp.c | 17 -- src/cpp.h | 4 +- src/cpp_tokiter.c | 10 +- src/data.c | 51 +----- src/data.h | 12 +- src/error.h | 5 - src/marshal.c | 52 +----- src/marshal.h | 54 ++++++ src/module.c | 11 +- src/parser.c | 4 +- src/token.c | 42 ++--- src/token.h | 4 +- src/types/assert_stmt.c | 42 +++-- src/types/assert_stmt.h | 4 +- src/types/const.c | 28 ++- src/types/const.h | 2 +- src/types/cpp_exp.c | 16 +- src/types/cpp_exp.h | 2 +- src/types/cpp_macro_call.c | 10 +- src/types/cpp_macro_call.h | 2 +- src/types/cpp_macro_decl.c | 20 +-- src/types/cpp_macro_decl.h | 2 +- src/types/decl.c | 22 +-- src/types/decl.h | 2 +- src/types/decl_abi.c | 4 +- src/types/decl_abi.h | 2 +- src/types/decl_arg.h | 2 +- src/types/decl_enum.c | 12 +- src/types/decl_enum.h | 2 +- src/types/decl_enum_item.c | 8 +- src/types/decl_enum_item.h | 2 +- src/types/decl_extvar.c | 8 +- src/types/decl_extvar.h | 2 +- src/types/decl_struct.c | 6 +- src/types/decl_struct.h | 2 +- src/types/decl_type.c | 40 ++--- src/types/decl_type.h | 2 +- src/types/decl_union.c | 6 +- src/types/decl_union.h | 2 +- src/types/decl_var.c | 6 +- src/types/decl_var.h | 2 +- src/types/free_exp.c | 10 +- src/types/free_exp.h | 2 +- src/types/free_stmt.c | 10 +- src/types/free_stmt.h | 2 +- src/types/impl.c | 18 +- src/types/impl.h | 2 +- src/types/impl_arg.c | 12 +- src/types/impl_arg.h | 2 +- src/types/impl_def_val.c | 345 +++++++++++++++++++++++++++++-------- src/types/impl_def_val.h | 6 +- src/types/impl_func.c | 14 +- src/types/impl_func.h | 2 +- src/types/impl_type.c | 4 +- src/types/impl_type.h | 2 +- src/types/impl_val.h | 58 ++++--- src/types/impl_var.c | 4 +- src/types/impl_var.h | 2 +- src/types/let_callback.c | 20 +-- src/types/let_callback.h | 2 +- src/types/let_calloc.c | 12 +- src/types/let_calloc.h | 2 +- src/types/let_exp.c | 30 ++-- src/types/let_exp.h | 2 +- src/types/let_func.c | 16 +- src/types/let_func.h | 2 +- src/types/let_stmt.c | 8 +- src/types/let_stmt.h | 2 +- src/types/num_exp.c | 34 ++-- src/types/num_exp.h | 2 +- src/types/number.c | 39 +++-- src/types/number.h | 2 +- src/types/return_exp.c | 16 +- src/types/return_exp.h | 2 +- src/types/return_stmt.c | 8 +- src/types/return_stmt.h | 2 +- src/types/set_exp.c | 14 +- src/types/set_exp.h | 2 +- src/types/set_func.c | 20 +-- src/types/set_func.h | 2 +- src/types/set_stmt.c | 8 +- src/types/set_stmt.h | 2 +- 86 files changed, 785 insertions(+), 569 deletions(-) diff --git a/.gdbinit b/.gdbinit index 3956ad1..9aad1bc 100644 --- a/.gdbinit +++ b/.gdbinit @@ -40,7 +40,7 @@ define psi_decl_type_dump end define psi_decl_type_dump_args_with_layout call psi_decl_type_dump_args_with_layout(1, $arg0, 0) - echo \n + echo \n end define psi_decl_union_dump call psi_decl_union_dump(1, $arg0) diff --git a/php_psi.h b/php_psi.h index 01582c5..8d7649c 100644 --- a/php_psi.h +++ b/php_psi.h @@ -50,6 +50,51 @@ static inline int psi_check_env(const char *var) { return (set && *set && (*set != '0' || set[1])); } +#include "php_network.h" + +static inline int psi_fdopen(const char *desc) +{ + int fd = -1; + + if (desc) { + char *addr = strstr(desc, "://"); + + if (addr) { + addr += 3; + } + if (addr && *addr) { + struct sockaddr_storage sa = {0}; + socklen_t ss = 0; + int rc = php_network_parse_network_address_with_port(addr, + strlen(addr), (struct sockaddr *) &sa, &ss); + + if (SUCCESS == rc) { + int styp = strncmp(desc, "udp:", 4) + ? SOCK_STREAM + : SOCK_DGRAM; + int sfam = sa.ss_family == AF_INET6 + ? ((struct sockaddr_in6 *) &sa)->sin6_family + : ((struct sockaddr_in *) &sa)->sin_family; + + fd = socket(sfam, styp, 0); + + if (fd > 0 && 0 != connect(fd, (struct sockaddr *) &sa, ss)) { + perror(desc); + close(fd); + fd = -1; + } + } + } else if (!strcmp(desc, "stdout")) { + fd = STDOUT_FILENO; + } else if (!strcmp(desc, "stderr")) { + fd = STDERR_FILENO; + } else if (!(fd = atoi(desc)) || -1 == fcntl(fd, F_GETFD)) { + fd = open(desc, O_WRONLY|O_APPEND|O_CREAT|O_CLOEXEC, 0664); + } + } + return fd; +} + typedef struct psi_object { void *data; void (*dtor)(void *data); diff --git a/src/call.c b/src/call.c index 22516c7..57b57f0 100644 --- a/src/call.c +++ b/src/call.c @@ -30,7 +30,6 @@ #include "php.h" #include "zend_exceptions.h" -#include "ext/spl/spl_exceptions.h" struct psi_call_frame_argument *psi_call_frame_argument_init(struct psi_impl_arg *spec, impl_val *ival, zval *zptr, int is_vararg) { @@ -427,11 +426,7 @@ ZEND_RESULT_CODE psi_call_frame_do_assert(struct psi_call_frame *frame, enum psi while (psi_plist_get(frame->impl->stmts.ass, i++, &ass)) { if (ass->kind == kind) { if (!psi_assert_stmt_exec(ass, frame)) { - char *message = psi_assert_stmt_message(ass); - zend_throw_exception(kind == PSI_ASSERT_PRE - ? spl_ce_InvalidArgumentException - : spl_ce_UnexpectedValueException, message, 0); - free(message); + psi_assert_stmt_throw(ass); return FAILURE; } } diff --git a/src/context.c b/src/context.c index be8bae9..febe0bb 100644 --- a/src/context.c +++ b/src/context.c @@ -235,29 +235,7 @@ zend_function_entry *psi_context_compile(struct psi_context *C) } zc.name = zend_string_copy(c->name); - - switch (c->type ? c->type->type : c->val->type) { - case PSI_T_BOOL: - ZVAL_BOOL(&zc.value, c->val->ival.zend.bval); - break; - case PSI_T_INT: - ZVAL_LONG(&zc.value, c->val->ival.zend.lval); - break; - case PSI_T_FLOAT: - case PSI_T_DOUBLE: - ZVAL_DOUBLE(&zc.value, c->val->ival.dval); - break; - case PSI_T_STRING: - case PSI_T_QUOTED_STRING: - ZVAL_NEW_STR(&zc.value, zend_string_copy(c->val->ival.zend.str)); - if (ZSTR_IS_INTERNED(Z_STR(zc.value))) { - Z_TYPE_FLAGS(zc.value) = 0; - } - break; - default: - assert(0); - break; - } + psi_impl_def_val_get_zval(c->val, c->type ? c->type->type : PSI_T_MIXED , &zc.value); zend_register_constant(&zc); } @@ -380,8 +358,6 @@ void psi_context_free(struct psi_context **C) void psi_context_dump(struct psi_dump *dump, struct psi_context *C) { - size_t i; - PSI_DUMP(dump, "// psi.engine=%s\n// %lu files\n", (char *) C->ops->query(C, PSI_CONTEXT_QUERY_SELF, NULL), C->count); @@ -390,8 +366,10 @@ void psi_context_dump(struct psi_dump *dump, struct psi_context *C) #if 0 if (C->flags & PSI_DEBUG) { + size_t i; + for (i = 0; i < C->count; ++i) { - psi_data_dump(fd, &C->data[i]); + psi_data_dump(dump, &C->data[i]); } } #endif diff --git a/src/cpp.c b/src/cpp.c index 4982c78..9daca1b 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -114,28 +114,11 @@ static char *include_flavor[] = { "include once" }; -#if PSI_CPP_DEBUG > 1 -static int dump_def(zval *p) -{ - struct psi_cpp_macro_decl *decl = Z_PTR_P(p); - - if (decl) { - dprintf(2, "PSI: CPP decl -> #define "); - psi_cpp_macro_decl_dump(2, decl); - dprintf(2, "\n"); - } - return ZEND_HASH_APPLY_KEEP; -} -#endif - void psi_cpp_free(struct psi_cpp **cpp_ptr) { if (*cpp_ptr) { struct psi_cpp *cpp = *cpp_ptr; -#if PSI_CPP_DEBUG > 1 - zend_hash_apply(&cpp->defs, dump_def); -#endif *cpp_ptr = NULL; zend_hash_destroy(&cpp->defs); zend_hash_destroy(&cpp->once); diff --git a/src/cpp.h b/src/cpp.h index ed766e3..671d2da 100644 --- a/src/cpp.h +++ b/src/cpp.h @@ -29,7 +29,7 @@ #include "data.h" #ifndef PSI_CPP_DEBUG -# define PSI_CPP_DEBUG 1 +# define PSI_CPP_DEBUG 0 #endif struct psi_cpp { @@ -68,7 +68,7 @@ bool psi_cpp_include(struct psi_cpp *cpp, const struct psi_token *file, unsigned void psi_cpp_tokiter_reset(struct psi_cpp *cpp); bool psi_cpp_tokiter_seek(struct psi_cpp *cpp, size_t index); #if PSI_CPP_DEBUG > 1 -void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp); +void psi_cpp_tokiter_dump(struct psi_dump *dump, struct psi_cpp *cpp); #endif struct psi_token *psi_cpp_tokiter_current(struct psi_cpp *cpp); size_t psi_cpp_tokiter_index(struct psi_cpp *cpp); diff --git a/src/cpp_tokiter.c b/src/cpp_tokiter.c index c2bcb95..4f9eee3 100644 --- a/src/cpp_tokiter.c +++ b/src/cpp_tokiter.c @@ -28,7 +28,7 @@ #include "cpp.h" #include "parser.h" -void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp) +void psi_cpp_tokiter_dump(struct psi_dump *dump, struct psi_cpp *cpp) { size_t i = cpp->index; struct psi_token *T; @@ -39,14 +39,14 @@ void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp) i = 0; } while (psi_plist_get(cpp->tokens.iter, i, &T)) { - dprintf(fd, "PSI: CPP tokens %5zu %c ", i, cpp->index == i ? '*' : ' '); + PSI_DUMP(dump, "PSI: CPP tokens %5zu %c ", i, cpp->index == i ? '*' : ' '); if (T) { - psi_token_dump(fd, T); + psi_token_dump(dump, T); } else { - dprintf(fd, "TOKEN deleted\n"); + PSI_DUMP(dump, "TOKEN deleted\n"); } if (i >= cpp->index + 40) { - dprintf(fd, "PSI: CPP tokens .....\n"); + PSI_DUMP(dump, "PSI: CPP tokens .....\n"); break; } ++i; diff --git a/src/data.c b/src/data.c index 0fb9816..fb94d30 100644 --- a/src/data.c +++ b/src/data.c @@ -27,7 +27,6 @@ #include "data.h" #include "php_globals.h" -#include "php_network.h" #include #include @@ -39,50 +38,12 @@ static void psi_data_ctor_internal(struct psi_data *data, data->flags = flags; if (data->flags & PSI_DEBUG) { - char *debug = getenv("PSI_DEBUG"); + int fd = psi_fdopen(getenv("PSI_DEBUG")); - if (debug) { - int fd = -1; - char *addr = strstr(debug, "://"); - - if (addr) { - addr += 3; - } - if (addr && *addr) { - struct sockaddr_storage sa = {0}; - socklen_t ss = 0; - int rc = php_network_parse_network_address_with_port(addr, - strlen(addr), (struct sockaddr *) &sa, &ss); - - if (SUCCESS == rc) { - int styp = strncmp(debug, "udp:", 4) - ? SOCK_STREAM - : SOCK_DGRAM; - int sfam = sa.ss_family == AF_INET6 - ? ((struct sockaddr_in6 *) &sa)->sin6_family - : ((struct sockaddr_in *) &sa)->sin_family; - - fd = socket(sfam, styp, 0); - - if (fd > 0 && 0 != connect(fd, (struct sockaddr *) &sa, ss)) { - perror(debug); - close(fd); - fd = -1; - } - } - } else if (!strcmp(debug, "stdout")) { - fd = STDOUT_FILENO; - } else if (!strcmp(debug, "stderr")) { - fd = STDERR_FILENO; - } else if (!(fd = atoi(debug))) { - fd = open(debug, O_WRONLY|O_APPEND|O_CREAT|O_CLOEXEC, 0664); - } - - if (fd > 0) { - data->debug_fd = fd; - } else { - data->debug_fd = STDERR_FILENO; - } + if (fd > 0) { + data->debug_fd = fd; + } else { + data->debug_fd = STDERR_FILENO; } } } @@ -244,7 +205,7 @@ void psi_data_dump(struct psi_dump *dump, struct psi_data *D) while (psi_plist_get(D->unions, i++, &unn)) { if (!psi_decl_type_is_anon(unn->name, "union")) { - psi_decl_union_dump(fd, unn); + psi_decl_union_dump(dump, unn); PSI_DUMP(dump, "\n"); } } diff --git a/src/data.h b/src/data.h index 1d8414f..ca7bf90 100644 --- a/src/data.h +++ b/src/data.h @@ -31,12 +31,14 @@ #include "plist.h" #include "validate.h" -#define PSI_DEBUG 0x1 -#define PSI_SILENT 0x2 +#include "php_network.h" #include #include +#define PSI_DEBUG 0x1 +#define PSI_SILENT 0x2 + #ifndef RTLD_NEXT # define RTLD_NEXT ((void *) -1l) #endif @@ -80,7 +82,9 @@ again: } while(0) #define PSI_DEBUG_DUMP(ctx, dump_func, ...) do { \ if ((ctx) && (PSI_DATA(ctx)->flags & PSI_DEBUG)) { \ - dump_func(PSI_DATA(ctx)->debug_fd, __VA_ARGS__); \ + struct psi_dump dump_ = {{ .fd = PSI_DATA(ctx)->debug_fd}, \ + .fun = (psi_dump_cb) dprintf}; \ + dump_func(&dump_, __VA_ARGS__); \ } \ } while (0) @@ -121,6 +125,6 @@ struct psi_data *psi_data_ctor(struct psi_data *data, psi_error_cb error, unsign struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data, psi_error_cb error, unsigned flags); struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src); void psi_data_dtor(struct psi_data *data); -void psi_data_dump(int fd, struct psi_data *data); +void psi_data_dump(struct psi_dump *dump, struct psi_data *data); #endif diff --git a/src/error.h b/src/error.h index ebbd60b..c155d39 100644 --- a/src/error.h +++ b/src/error.h @@ -41,9 +41,4 @@ void psi_error_wrapper(struct psi_data *context, struct psi_token *t, int type, 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); -union psi_debug_ctx { - FILE *stdio; - int socket; -}; - #endif /* PSI_ERROR_H */ diff --git a/src/marshal.c b/src/marshal.c index 14f0dca..ff1ddcc 100644 --- a/src/marshal.c +++ b/src/marshal.c @@ -226,52 +226,6 @@ impl_val *psi_let_boolval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl return psi_val_boolval(tmp, real_type, boolval); } -#if HAVE_INT128 -static inline char *psi_u128_to_buf(char *buf, unsigned __int128 u128) -{ - for (*buf = 0; u128 > 0; u128 /= 10) { - *--buf = ((u128 % 10) + '0') & 0xff; - } - return buf; -} - -static inline char *psi_i128_to_buf(char *buf, __int128 i128) -{ - if (i128 < 0) { - char *res = psi_u128_to_buf(buf, ~((unsigned __int128) i128) + 1); - - *--res = '-'; - return res; - } - return psi_u128_to_buf(buf, i128); -} - -# define RETVAL_LONG_STR(V, s) do {\ - char buf[0x30] = {0}; \ - if (s && V >= ZEND_LONG_MIN && V <= ZEND_LONG_MAX) { \ - RETVAL_LONG(V); \ - } else if (!s && V <= ZEND_LONG_MAX) { \ - RETVAL_LONG(V); \ - } else if (!s && V <= ZEND_ULONG_MAX) { \ - RETVAL_STRING(zend_print_ulong_to_buf(&buf[sizeof(buf) - 1], V)); \ - } else if (s && V >= INT128_MIN && V <= INT128_MAX) { \ - RETVAL_STRING(psi_i128_to_buf(&buf[sizeof(buf) - 1], V)); \ - } else { \ - RETVAL_STRING(psi_u128_to_buf(&buf[sizeof(buf) - 1], V)); \ - } \ - } while (0) -#else -# define RETVAL_LONG_STR(V, s) do {\ - char buf[0x20] = {0}; \ - if (s && V >= ZEND_LONG_MIN && V <= ZEND_LONG_MAX) { \ - RETVAL_LONG(V); \ - } else if (!s && V <= ZEND_LONG_MAX) { \ - RETVAL_LONG(V); \ - } else { \ - RETVAL_STRING(zend_print_ulong_to_buf(&buf[sizeof(buf) - 1], V)); \ - } \ - } while (0) -#endif /* * set $ivar = to_int(*dvar) */ @@ -290,10 +244,10 @@ void psi_set_to_int(zval *return_value, struct psi_set_exp *set, impl_val *ret_v case PSI_T_INT32: RETVAL_LONG(v->i32); break; case PSI_T_UINT32: RETVAL_LONG(v->u32); break; case PSI_T_INT64: RETVAL_LONG(v->i64); break; - case PSI_T_UINT64: RETVAL_LONG_STR(v->u64, 0); break; + case PSI_T_UINT64: RETVAL_LONG_DOUBLE_STR(v->u64,); break; #ifdef HAVE_INT128 - case PSI_T_INT128: RETVAL_LONG_STR(v->i128, 1); break; - case PSI_T_UINT128: RETVAL_LONG_STR(v->u128, 0); break; + case PSI_T_INT128: RETVAL_LONG_DOUBLE_STR(v->i128, is_signed=true); break; + case PSI_T_UINT128: RETVAL_LONG_DOUBLE_STR(v->u128,); break; #endif case PSI_T_FLOAT: RETVAL_DOUBLE((double) v->fval); diff --git a/src/marshal.h b/src/marshal.h index be5b3c6..a7777d3 100644 --- a/src/marshal.h +++ b/src/marshal.h @@ -36,6 +36,60 @@ struct psi_call_frame; struct psi_impl; struct psi_impl_type; +#if HAVE_INT128 +static inline char *psi_u128_to_buf(char *buf, unsigned __int128 u128) +{ + for (*buf = 0; u128 > 0; u128 /= 10) { + *--buf = ((u128 % 10) + '0') & 0xff; + } + return buf; +} + +static inline char *psi_i128_to_buf(char *buf, __int128 i128) +{ + if (i128 < 0) { + char *res = psi_u128_to_buf(buf, ~((unsigned __int128) i128) + 1); + + *--res = '-'; + return res; + } + return psi_u128_to_buf(buf, i128); +} +#else +# define psi_u128_to_buf(b,u) zend_print_ulong_to_buf(b,u) +# define psi_i128_to_buf(b,i) zend_print_long_to_buf(b,i) +#endif + + +#define RETVAL_LONG_DOUBLE_STR(V, flags) ZVAL_LONG_DOUBLE_STR(return_value, V, flags) +# define ZVAL_LONG_DOUBLE_STR(z, V, flags) do { \ + char buf[0x20] = {0}; \ + bool is_signed = false, persistent = false; \ + flags; \ + if (is_signed) { \ + if (V >= ZEND_LONG_MIN && V <= ZEND_LONG_MAX) { \ + ZVAL_LONG(z, V); \ + } else if (V >= -(1L<<52) && V <= (1L<<53)) { \ + ZVAL_DOUBLE(z, V); \ + } else if (V < ZEND_LONG_MIN || V > ZEND_LONG_MAX) { \ + ZVAL_STRING(z, psi_i128_to_buf(&buf[sizeof(buf) - 1], V)); \ + } else { \ + ZVAL_STRING(z, zend_print_long_to_buf(&buf[sizeof(buf) - 1], V)); \ + } \ + } else { \ + if (V <= ZEND_LONG_MAX) { \ + ZVAL_LONG(z, V); \ + } else if (V <= (1L<<53)) { \ + ZVAL_DOUBLE(z, V); \ + } else if (V > ZEND_ULONG_MAX) { \ + ZVAL_STRING(z, psi_u128_to_buf(&buf[sizeof(buf) - 1], V)); \ + } else { \ + ZVAL_STRING(z, zend_print_ulong_to_buf(&buf[sizeof(buf) - 1], V)); \ + } \ + } \ +} while (0) + + zend_long psi_zval_count(zval *zvalue); zend_internal_arg_info *psi_internal_arginfo(struct psi_impl *impl); int psi_internal_type(struct psi_impl_type *type); diff --git a/src/module.c b/src/module.c index 0edd74f..08db814 100644 --- a/src/module.c +++ b/src/module.c @@ -166,19 +166,18 @@ static PHP_FUNCTION(psi_dump) { php_stream *s; zval *r = NULL; - int fd = STDOUT_FILENO; + struct psi_dump dump = {.fun = php_stream_printf}; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &r)) { return; } if (r) { php_stream_from_zval(s, r); - - if (SUCCESS != php_stream_cast(s, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void **)&fd, 1)) { - RETURN_FALSE; - } + dump.ctx.hn = s; + } else { + dump.ctx.hn = php_stream_open_wrapper("php://output", "w", REPORT_ERRORS, NULL); } - psi_context_dump(PSI_G(context), fd); + psi_context_dump(&dump, PSI_G(context)); } ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate, 0, 0, 1) diff --git a/src/parser.c b/src/parser.c index e747ed2..9475ff9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -145,7 +145,7 @@ static inline zend_string *macro_to_constant(struct psi_parser *parser, size_t i = 0; struct psi_token *tok; - smart_str_append_printf(&str, "\nconst psi\\%s = ", name->val); + smart_str_append_printf(&str, "const psi\\%s = ", name->val); if (scope->macro->exp) { impl_val res = {0}; token_t typ = psi_num_exp_exec(scope->macro->exp, &res, NULL, scope->cpp); @@ -179,7 +179,7 @@ void psi_parser_postprocess(struct psi_parser *P) scope.cpp = P->preproc; flags = P->flags; - //P->flags |= PSI_SILENT; + P->flags |= PSI_SILENT; ZEND_HASH_FOREACH_STR_KEY_PTR(&P->preproc->defs, name, scope.macro) { diff --git a/src/token.c b/src/token.c index 7b303e7..1b4cc5e 100644 --- a/src/token.c +++ b/src/token.c @@ -48,7 +48,7 @@ struct psi_token *psi_token_init(token_t token_typ, const char *token_txt, T->file = zend_string_copy(file); T->text = zend_string_init_interned(token_txt, token_len, 1); #if PSI_DEBUG_TOKEN_ALLOC - fprintf(stderr, "PSI: token_init %p\n", T); + PSI_DEBUG_PRINT(cpp->parser, "PSI: token_init %p\n", T); #endif return T; } @@ -57,7 +57,7 @@ void psi_token_free(struct psi_token **token_ptr) { if (*token_ptr) { struct psi_token *token = *token_ptr; #if PSI_DEBUG_TOKEN_ALLOC - fprintf(stderr, "PSI: token_free %p\n", token); + PSI_DEBUG_PRINT(cpp->parser, "PSI: token_free %p\n", token); #endif *token_ptr = NULL; zend_string_release(token->text); @@ -71,7 +71,7 @@ struct psi_token *psi_token_copy(struct psi_token *src) { *ptr = *src; #if PSI_DEBUG_TOKEN_ALLOC - fprintf(stderr, "PSI: token_copy %p <= %p\n", ptr, src); + PSI_DEBUG_PRINT(cpp->parser, "PSI: token_copy %p <= %p\n", ptr, src); #endif ptr->text = zend_string_copy(ptr->text); ptr->file = zend_string_copy(ptr->file); @@ -110,7 +110,7 @@ struct psi_token *psi_token_cat(const char *sep, unsigned argc, ...) { T->text = smart_str_extract(&text); #if PSI_DEBUG_TOKEN_ALLOC - fprintf(stderr, "PSI: token_cat %p\n", T); + PSI_DEBUG_PRINT(cpp->parser, "PSI: token_cat %p\n", T); #endif return T; } @@ -185,54 +185,54 @@ uint64_t psi_token_hash(struct psi_token *t, char *digest_buf) { return psi_hash(digest_buf, t->file->val, loc_buf, (char *) NULL); } -void psi_token_dump(int fd, struct psi_token *t) +void psi_token_dump(struct psi_dump *dump, struct psi_token *t) { size_t i; - dprintf(fd, "TOKEN %p (%u) ", t, t->type); + PSI_DUMP(dump, "TOKEN %p (%u) ", t, t->type); if (t->type == PSI_T_EOF) { - dprintf(fd, "EOF"); + PSI_DUMP(dump, "EOF"); } else { - dprintf(fd, "\""); + PSI_DUMP(dump, "\""); for (i = 0; i < t->text->len; ++i) { switch (t->text->val[i]) { case '\0': - dprintf(fd, "\\0"); + PSI_DUMP(dump, "\\0"); break; case '\a': - dprintf(fd, "\\a"); + PSI_DUMP(dump, "\\a"); break; case '\b': - dprintf(fd, "\\b"); + PSI_DUMP(dump, "\\b"); break; case '\f': - dprintf(fd, "\\f"); + PSI_DUMP(dump, "\\f"); break; case '\n': - dprintf(fd, "\\n"); + PSI_DUMP(dump, "\\n"); break; case '\r': - dprintf(fd, "\\r"); + PSI_DUMP(dump, "\\r"); break; case '\t': - dprintf(fd, "\\t"); + PSI_DUMP(dump, "\\t"); break; case '\v': - dprintf(fd, "\\v"); + PSI_DUMP(dump, "\\v"); break; case '"': - dprintf(fd, "\\\""); + PSI_DUMP(dump, "\\\""); break; default: if (isprint(t->text->val[i])) { - dprintf(fd, "%c", t->text->val[i]); + PSI_DUMP(dump, "%c", t->text->val[i]); } else { - dprintf(fd, "\\x%02hhX", t->text->val[i]); + PSI_DUMP(dump, "\\x%02hhX", t->text->val[i]); } break; } } - dprintf(fd, "\""); + PSI_DUMP(dump, "\""); } - dprintf(fd, " at col %u in %s on line %u\n", t->col, t->file->val, t->line); + PSI_DUMP(dump, " at col %u in %s on line %u\n", t->col, t->file->val, t->line); } diff --git a/src/token.h b/src/token.h index 368fba9..e87a16d 100644 --- a/src/token.h +++ b/src/token.h @@ -174,6 +174,8 @@ static inline const char *psi_t_indirection(unsigned pointer_level) { return &indir[32 - MIN(32, pointer_level)]; } +struct psi_dump; + struct psi_token { token_t type; unsigned line; @@ -193,7 +195,7 @@ struct psi_token *psi_token_cat(const char *sep, unsigned argc, ...); struct psi_token *psi_token_append(const char *sep, 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); -void psi_token_dump(int fd, struct psi_token *t); +void psi_token_dump(struct psi_dump *dump, struct psi_token *t); void psi_token_free(struct psi_token **token); #endif diff --git a/src/types/assert_stmt.c b/src/types/assert_stmt.c index e65efae..6909191 100644 --- a/src/types/assert_stmt.c +++ b/src/types/assert_stmt.c @@ -28,6 +28,10 @@ #include "data.h" #include "calc.h" +#include "zend_smart_str.h" +#include "zend_exceptions.h" +#include "ext/spl/spl_exceptions.h" + struct psi_assert_stmt *psi_assert_stmt_init(enum psi_assert_kind kind, struct psi_num_exp *exp) { struct psi_assert_stmt *stmt = pecalloc(1, sizeof(*stmt), 1); @@ -50,11 +54,11 @@ void psi_assert_stmt_free(struct psi_assert_stmt **stmt_ptr) } } -void psi_assert_stmt_dump(int fd, struct psi_assert_stmt *stmt) +void psi_assert_stmt_dump(struct psi_dump *dump, struct psi_assert_stmt *stmt) { - dprintf(fd, "\t%s_assert ", stmt->kind == PSI_ASSERT_PRE ? "pre" : "post"); - psi_num_exp_dump(fd, stmt->exp); - dprintf(fd, ";\n"); + PSI_DUMP(dump, "\t%s_assert ", stmt->kind == PSI_ASSERT_PRE ? "pre" : "post"); + psi_num_exp_dump(dump, stmt->exp); + PSI_DUMP(dump, ";\n"); } bool psi_assert_stmt_exec(struct psi_assert_stmt *stmt, struct psi_call_frame *frame) @@ -81,20 +85,20 @@ bool psi_assert_stmts_validate(struct psi_data *data, struct psi_validate_scope return true; } -char *psi_assert_stmt_message(struct psi_assert_stmt *stmt) +void psi_assert_stmt_throw(struct psi_assert_stmt *stmt) { - /* FIXME */ - struct stat sb; - char *message, template[] = "psi.assert.XXXXXX"; - int fd = mkstemp(template); - - dprintf(fd, "Failed asserting that "); - psi_num_exp_dump(fd, stmt->exp); - fstat(fd, &sb); - message = pemalloc(sb.st_size + 1, 1); - lseek(fd, 0, SEEK_SET); - read(fd, message, sb.st_size); - close(fd); - message[sb.st_size] = '\0'; - return message; + struct psi_dump dump; + smart_str str = {0}; + zend_string *message; + + dump.ctx.hn = &str; + dump.fun = (psi_dump_cb) smart_str_append_printf; + + PSI_DUMP(&dump, "Failed asserting that "); + psi_num_exp_dump(&dump, stmt->exp); + smart_str_0(&str); + zend_throw_exception(stmt->kind == PSI_ASSERT_PRE + ? spl_ce_InvalidArgumentException + : spl_ce_UnexpectedValueException, str.s->val, 0); + smart_str_free(&str); } diff --git a/src/types/assert_stmt.h b/src/types/assert_stmt.h index 7bfa74a..e8a7b19 100644 --- a/src/types/assert_stmt.h +++ b/src/types/assert_stmt.h @@ -46,11 +46,11 @@ struct psi_assert_stmt { struct psi_assert_stmt *psi_assert_stmt_init(enum psi_assert_kind kind, struct psi_num_exp *exp); bool psi_assert_stmt_exec(struct psi_assert_stmt *stmt, struct psi_call_frame *frame); -void psi_assert_stmt_dump(int fd, struct psi_assert_stmt *stmt); +void psi_assert_stmt_dump(struct psi_dump *dump, struct psi_assert_stmt *stmt); void psi_assert_stmt_free(struct psi_assert_stmt **stmt); bool psi_assert_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope); -char *psi_assert_stmt_message(struct psi_assert_stmt *stmt); +void psi_assert_stmt_throw(struct psi_assert_stmt *stmt); #endif diff --git a/src/types/const.c b/src/types/const.c index b839d5f..fd1a165 100644 --- a/src/types/const.c +++ b/src/types/const.c @@ -55,20 +55,36 @@ void psi_const_free(struct psi_const **constant_ptr) } } -void psi_const_dump(int fd, struct psi_const *cnst) +void psi_const_dump(struct psi_dump *dump, struct psi_const *cnst) { - dprintf(fd, "const "); + PSI_DUMP(dump, "const "); if (cnst->type) { - psi_impl_type_dump(fd, cnst->type); + psi_impl_type_dump(dump, cnst->type); } - dprintf(fd, " %s = ", cnst->name->val); - psi_impl_def_val_dump(fd, cnst->val); - dprintf(fd, ";"); + PSI_DUMP(dump, " %s = ", cnst->name->val); + psi_impl_def_val_dump(dump, cnst->val); + PSI_DUMP(dump, ";"); } bool psi_const_validate(struct psi_data *data, struct psi_const *c, struct psi_validate_scope *scope) { + if (c->type) { + switch (c->type->type) { + case PSI_T_BOOL: + case PSI_T_INT: + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + case PSI_T_STRING: + break; + default: + data->error(data, val->token, PSI_WARNING, + "Invalid default value type '%s', " + "expected one of bool, int, float/double or string.", + type->name->val); + return false; + } + } if (!psi_impl_def_val_validate(data, c->val, c->type, scope)) { return false; } diff --git a/src/types/const.h b/src/types/const.h index 4dbb171..da06071 100644 --- a/src/types/const.h +++ b/src/types/const.h @@ -41,7 +41,7 @@ struct psi_const { struct psi_const *psi_const_init(struct psi_impl_type *type, zend_string *name, struct psi_impl_def_val *val); void psi_const_free(struct psi_const **constant_ptr); -void psi_const_dump(int fd, struct psi_const *cnst); +void psi_const_dump(struct psi_dump *dump, struct psi_const *cnst); bool psi_const_validate(struct psi_data *data, struct psi_const *c, struct psi_validate_scope *scope); diff --git a/src/types/cpp_exp.c b/src/types/cpp_exp.c index bfff0d1..aa70c63 100644 --- a/src/types/cpp_exp.c +++ b/src/types/cpp_exp.c @@ -101,9 +101,9 @@ void psi_cpp_exp_free(struct psi_cpp_exp **exp_ptr) } } -void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp) +void psi_cpp_exp_dump(struct psi_dump *dump, struct psi_cpp_exp *exp) { - dprintf(fd, "#%s ", exp->token->text->val); + PSI_DUMP(dump, "#%s ", exp->token->text->val); switch (exp->type) { case PSI_T_WARNING: case PSI_T_ERROR: @@ -114,23 +114,23 @@ void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp) case PSI_T_UNDEF: case PSI_T_IFDEF: case PSI_T_IFNDEF: - dprintf(fd, "%s", exp->data.tok->text->val); + PSI_DUMP(dump, "%s", exp->data.tok->text->val); break; case PSI_T_IMPORT: case PSI_T_INCLUDE: case PSI_T_INCLUDE_NEXT: if (exp->data.tok->type == PSI_T_CPP_HEADER) { - dprintf(fd, "<%s>", exp->data.tok->text->val); + PSI_DUMP(dump, "<%s>", exp->data.tok->text->val); } else { - dprintf(fd, "\"%s\"", exp->data.tok->text->val); + PSI_DUMP(dump, "\"%s\"", exp->data.tok->text->val); } break; case PSI_T_DEFINE: - psi_cpp_macro_decl_dump(fd, exp->data.decl); + psi_cpp_macro_decl_dump(dump, exp->data.decl); break; case PSI_T_IF: case PSI_T_ELIF: - psi_num_exp_dump(fd, exp->data.num); + psi_num_exp_dump(dump, exp->data.num); break; case PSI_T_ENDIF: case PSI_T_ELSE: @@ -140,7 +140,7 @@ void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp) assert(0); break; } - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); } diff --git a/src/types/cpp_exp.h b/src/types/cpp_exp.h index f2706bb..d9b3a39 100644 --- a/src/types/cpp_exp.h +++ b/src/types/cpp_exp.h @@ -45,7 +45,7 @@ struct psi_cpp_exp { struct psi_cpp_exp *psi_cpp_exp_init(token_t type, void *data); void psi_cpp_exp_free(struct psi_cpp_exp **exp_ptr); -void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp); +void psi_cpp_exp_dump(struct psi_dump *dump, struct psi_cpp_exp *exp); void psi_cpp_exp_exec(struct psi_cpp_exp *exp, struct psi_cpp *cpp, struct psi_data *D); #endif diff --git a/src/types/cpp_macro_call.c b/src/types/cpp_macro_call.c index e1277ca..04e0ea4 100644 --- a/src/types/cpp_macro_call.c +++ b/src/types/cpp_macro_call.c @@ -68,17 +68,17 @@ void psi_cpp_macro_call_free(struct psi_cpp_macro_call **call_ptr) } } -void psi_cpp_macro_call_dump(int fd, struct psi_cpp_macro_call *call) +void psi_cpp_macro_call_dump(struct psi_dump *dump, struct psi_cpp_macro_call *call) { size_t i = 0; struct psi_num_exp *num; - dprintf(fd, "%s(", call->name->val); + PSI_DUMP(dump, "%s(", call->name->val); while (psi_plist_get(call->args, i++, &num)) { if (i > 1) { - dprintf(fd, ", "); + PSI_DUMP(dump, ", "); } - psi_num_exp_dump(fd, num); + psi_num_exp_dump(dump, num); } - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); } diff --git a/src/types/cpp_macro_call.h b/src/types/cpp_macro_call.h index 11e2be9..ecb0ea6 100644 --- a/src/types/cpp_macro_call.h +++ b/src/types/cpp_macro_call.h @@ -43,6 +43,6 @@ struct psi_cpp_macro_call *psi_cpp_macro_call_init(zend_string *name, struct psi_cpp_macro_call *psi_cpp_macro_call_copy( struct psi_cpp_macro_call *call); void psi_cpp_macro_call_free(struct psi_cpp_macro_call **call_ptr); -void psi_cpp_macro_call_dump(int fd, struct psi_cpp_macro_call *call); +void psi_cpp_macro_call_dump(struct psi_dump *dump, struct psi_cpp_macro_call *call); #endif diff --git a/src/types/cpp_macro_decl.c b/src/types/cpp_macro_decl.c index 4f21d60..25bafd8 100644 --- a/src/types/cpp_macro_decl.c +++ b/src/types/cpp_macro_decl.c @@ -58,24 +58,24 @@ void psi_cpp_macro_decl_free(struct psi_cpp_macro_decl **macro_ptr) } } -void psi_cpp_macro_decl_dump(int fd, struct psi_cpp_macro_decl *macro) +void psi_cpp_macro_decl_dump(struct psi_dump *dump, struct psi_cpp_macro_decl *macro) { - dprintf(fd, "%s", macro->token->text->val); + PSI_DUMP(dump, "%s", macro->token->text->val); if (macro->sig) { size_t i = 0; struct psi_token *tok; - dprintf(fd, "("); + PSI_DUMP(dump, "("); while (psi_plist_get(macro->sig, i++, &tok)) { - dprintf(fd, "%s%s", i>1?",":"", tok->text->val); + PSI_DUMP(dump, "%s%s", i>1?",":"", tok->text->val); } - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); } if (macro->exp) { - dprintf(fd, " "); - psi_num_exp_dump(fd, macro->exp); + PSI_DUMP(dump, " "); + psi_num_exp_dump(dump, macro->exp); assert(macro->tokens); @@ -86,13 +86,13 @@ void psi_cpp_macro_decl_dump(int fd, struct psi_cpp_macro_decl *macro) while (psi_plist_get(macro->tokens, i++, &tok)) { switch (tok->type) { case PSI_T_QUOTED_STRING: - dprintf(fd, " \"%s\"", tok->text->val); + PSI_DUMP(dump, " \"%s\"", tok->text->val); break; case PSI_T_QUOTED_CHAR: - dprintf(fd, " '%s'", tok->text->val); + PSI_DUMP(dump, " '%s'", tok->text->val); break; default: - dprintf(fd, " %s", tok->text->val); + PSI_DUMP(dump, " %s", tok->text->val); } } } diff --git a/src/types/cpp_macro_decl.h b/src/types/cpp_macro_decl.h index e8ab300..f7cac26 100644 --- a/src/types/cpp_macro_decl.h +++ b/src/types/cpp_macro_decl.h @@ -40,7 +40,7 @@ struct psi_cpp_macro_decl { struct psi_cpp_macro_decl *psi_cpp_macro_decl_init(struct psi_plist *sig, struct psi_plist *tokens, struct psi_num_exp *exp); void psi_cpp_macro_decl_free(struct psi_cpp_macro_decl **macro_ptr); -void psi_cpp_macro_decl_dump(int fd, struct psi_cpp_macro_decl *decl); +void psi_cpp_macro_decl_dump(struct psi_dump *dump, struct psi_cpp_macro_decl *decl); bool psi_cpp_macro_decl_equal(struct psi_cpp_macro_decl *d1, struct psi_cpp_macro_decl *d2); #endif diff --git a/src/types/decl.c b/src/types/decl.c index 780b924..42eeb43 100644 --- a/src/types/decl.c +++ b/src/types/decl.c @@ -65,36 +65,36 @@ void psi_decl_free(struct psi_decl **d_ptr) } } -void psi_decl_dump(int fd, struct psi_decl *decl) +void psi_decl_dump(struct psi_dump *dump, struct psi_decl *decl) { if (decl->abi) { - psi_decl_abi_dump(fd, decl->abi); + psi_decl_abi_dump(dump, decl->abi); } - dprintf(fd, " "); + PSI_DUMP(dump, " "); /* FIXME: functions returning arrays */ - psi_decl_arg_dump(fd, decl->func, 0); - dprintf(fd, "("); + psi_decl_arg_dump(dump, decl->func, 0); + PSI_DUMP(dump, "("); if (decl->args) { size_t i; struct psi_decl_arg *arg; for (i = 0; psi_plist_get(decl->args, i, &arg); ++i) { if (i) { - dprintf(fd, ", "); + PSI_DUMP(dump, ", "); } - psi_decl_arg_dump(fd, arg, 0); + psi_decl_arg_dump(dump, arg, 0); } if (decl->varargs) { - dprintf(fd, ", ..."); + PSI_DUMP(dump, ", ..."); } } if (decl->func->var->array_size) { - dprintf(fd, ")[%u]", decl->func->var->array_size); + PSI_DUMP(dump, ")[%u]", decl->func->var->array_size); } if (decl->redir) { - dprintf(fd, ") __asm__ (\"%s\");", decl->redir->val); + PSI_DUMP(dump, ") __asm__ (\"%s\");", decl->redir->val); } else { - dprintf(fd, ");"); + PSI_DUMP(dump, ");"); } } diff --git a/src/types/decl.h b/src/types/decl.h index 11e72a8..08380b1 100644 --- a/src/types/decl.h +++ b/src/types/decl.h @@ -44,7 +44,7 @@ struct psi_decl { struct psi_decl *psi_decl_init(struct psi_decl_arg *func, struct psi_plist *args); void psi_decl_free(struct psi_decl **d_ptr); -void psi_decl_dump(int fd, struct psi_decl *decl); +void psi_decl_dump(struct psi_dump *dump, struct psi_decl *decl); bool psi_decl_validate(struct psi_data *data, struct psi_decl *decl, struct psi_validate_scope *scope); bool psi_decl_validate_nodl(struct psi_data *data, struct psi_decl *decl, struct psi_validate_scope *scope); diff --git a/src/types/decl_abi.c b/src/types/decl_abi.c index 7efa2ef..a92c8ad 100644 --- a/src/types/decl_abi.c +++ b/src/types/decl_abi.c @@ -47,9 +47,9 @@ void psi_decl_abi_free(struct psi_decl_abi **abi_ptr) } } -void psi_decl_abi_dump(int fd, struct psi_decl_abi *abi) +void psi_decl_abi_dump(struct psi_dump *dump, struct psi_decl_abi *abi) { - dprintf(fd, "%s", abi->convention->val); + PSI_DUMP(dump, "%s", abi->convention->val); } static const char * const abi_ccs[] = { diff --git a/src/types/decl_abi.h b/src/types/decl_abi.h index 331ee92..fe2d16c 100644 --- a/src/types/decl_abi.h +++ b/src/types/decl_abi.h @@ -36,7 +36,7 @@ struct psi_decl_abi { struct psi_decl_abi *psi_decl_abi_init(zend_string *convention); void psi_decl_abi_free(struct psi_decl_abi **abi_ptr); -void psi_decl_abi_dump(int fd, struct psi_decl_abi *abi); +void psi_decl_abi_dump(struct psi_dump *dump, struct psi_decl_abi *abi); bool psi_decl_abi_validate(struct psi_data *data, struct psi_decl_abi *abi); #endif diff --git a/src/types/decl_arg.h b/src/types/decl_arg.h index 325d7c7..b48125b 100644 --- a/src/types/decl_arg.h +++ b/src/types/decl_arg.h @@ -43,7 +43,7 @@ struct psi_decl_arg { struct psi_decl_arg *psi_decl_arg_init(struct psi_decl_type *type, struct psi_decl_var *var); void psi_decl_arg_free(struct psi_decl_arg **arg_ptr); -void psi_decl_arg_dump(int fd, struct psi_decl_arg *arg, unsigned level); +void psi_decl_arg_dump(struct psi_dump *dump, struct psi_decl_arg *arg, unsigned level); bool psi_decl_arg_validate(struct psi_data *data, struct psi_decl_arg *arg, struct psi_validate_scope *scope); bool psi_decl_arg_validate_typedef(struct psi_data *data, struct psi_decl_arg *def, struct psi_validate_scope *scope); diff --git a/src/types/decl_enum.c b/src/types/decl_enum.c index 310b7e3..68d644a 100644 --- a/src/types/decl_enum.c +++ b/src/types/decl_enum.c @@ -49,22 +49,22 @@ void psi_decl_enum_free(struct psi_decl_enum **e_ptr) } } -void psi_decl_enum_dump(int fd, struct psi_decl_enum *e, unsigned level) +void psi_decl_enum_dump(struct psi_dump *dump, struct psi_decl_enum *e, unsigned level) { - dprintf(fd, "enum %s {\n", e->name->val); + PSI_DUMP(dump, "enum %s {\n", e->name->val); if (e->items) { size_t i = 0; struct psi_decl_enum_item *item; while (psi_plist_get(e->items, i++, &item)) { if (i > 1) { - dprintf(fd, ",\n"); + PSI_DUMP(dump, ",\n"); } - dprintf(fd, "%s", psi_t_indent(level + 1)); - psi_decl_enum_item_dump(fd, item); + PSI_DUMP(dump, "%s", psi_t_indent(level + 1)); + psi_decl_enum_item_dump(dump, item); } } - dprintf(fd, "\n}"); + PSI_DUMP(dump, "\n}"); } bool psi_decl_enum_validate(struct psi_data *data, struct psi_decl_enum *e) diff --git a/src/types/decl_enum.h b/src/types/decl_enum.h index fd51d71..037f21d 100644 --- a/src/types/decl_enum.h +++ b/src/types/decl_enum.h @@ -38,7 +38,7 @@ struct psi_decl_enum { struct psi_decl_enum *psi_decl_enum_init(zend_string *name, struct psi_plist *l); void psi_decl_enum_free(struct psi_decl_enum **e_ptr); -void psi_decl_enum_dump(int fd, struct psi_decl_enum *e, unsigned level); +void psi_decl_enum_dump(struct psi_dump *dump, struct psi_decl_enum *e, unsigned level); bool psi_decl_enum_validate(struct psi_data *data, struct psi_decl_enum *e); #endif diff --git a/src/types/decl_enum_item.c b/src/types/decl_enum_item.c index f20eaa6..4992000 100644 --- a/src/types/decl_enum_item.c +++ b/src/types/decl_enum_item.c @@ -64,12 +64,12 @@ void psi_decl_enum_item_free(struct psi_decl_enum_item **i_ptr) } } -void psi_decl_enum_item_dump(int fd, struct psi_decl_enum_item *item) +void psi_decl_enum_item_dump(struct psi_dump *dump, struct psi_decl_enum_item *item) { - dprintf(fd, "%s", item->name->val); + PSI_DUMP(dump, "%s", item->name->val); if (item->num && item->num != &item->inc) { - dprintf(fd, " = "); - psi_num_exp_dump(fd, item->num); + PSI_DUMP(dump, " = "); + psi_num_exp_dump(dump, item->num); } } diff --git a/src/types/decl_enum_item.h b/src/types/decl_enum_item.h index c465ed1..86e4dc8 100644 --- a/src/types/decl_enum_item.h +++ b/src/types/decl_enum_item.h @@ -42,7 +42,7 @@ struct psi_decl_enum_item { struct psi_decl_enum_item *psi_decl_enum_item_init(zend_string *name, struct psi_num_exp *num); void psi_decl_enum_item_free(struct psi_decl_enum_item **i_ptr); -void psi_decl_enum_item_dump(int fd, struct psi_decl_enum_item *item); +void psi_decl_enum_item_dump(struct psi_dump *dump, struct psi_decl_enum_item *item); bool psi_decl_enum_item_validate(struct psi_data *data, struct psi_decl_enum *enm, struct psi_decl_enum_item *item, size_t seq); #endif diff --git a/src/types/decl_extvar.c b/src/types/decl_extvar.c index 2430454..446a28e 100644 --- a/src/types/decl_extvar.c +++ b/src/types/decl_extvar.c @@ -91,11 +91,11 @@ bool psi_decl_extvar_validate(struct psi_data *data, return true; } -void psi_decl_extvar_dump(int fd, struct psi_decl_extvar *evar) +void psi_decl_extvar_dump(struct psi_dump *dump, struct psi_decl_extvar *evar) { - dprintf(fd, "extern "); - psi_decl_arg_dump(fd, evar->arg, 0); - dprintf(fd, ";\n"); + PSI_DUMP(dump, "extern "); + psi_decl_arg_dump(dump, evar->arg, 0); + PSI_DUMP(dump, ";\n"); } struct psi_decl *psi_decl_extvar_setter(struct psi_decl_extvar *evar) diff --git a/src/types/decl_extvar.h b/src/types/decl_extvar.h index 696567e..9d3b9d9 100644 --- a/src/types/decl_extvar.h +++ b/src/types/decl_extvar.h @@ -46,7 +46,7 @@ struct psi_decl_extvar *psi_decl_extvar_init(struct psi_decl_arg *arg); void psi_decl_extvar_free(struct psi_decl_extvar **evar); bool psi_decl_extvar_validate(struct psi_data *data, struct psi_decl_extvar *evar, struct psi_validate_scope *scope); -void psi_decl_extvar_dump(int fd, struct psi_decl_extvar *evar); +void psi_decl_extvar_dump(struct psi_dump *dump, struct psi_decl_extvar *evar); bool psi_decl_extvar_is_blacklisted(const char *name); diff --git a/src/types/decl_struct.c b/src/types/decl_struct.c index 14076c6..44f8b4c 100644 --- a/src/types/decl_struct.c +++ b/src/types/decl_struct.c @@ -55,14 +55,14 @@ void psi_decl_struct_free(struct psi_decl_struct **s_ptr) } } -void psi_decl_struct_dump(int fd, struct psi_decl_struct *strct) +void psi_decl_struct_dump(struct psi_dump *dump, struct psi_decl_struct *strct) { - dprintf(fd, "struct %s::(%zu, %zu)", strct->name->val, strct->align, + PSI_DUMP(dump, "struct %s::(%zu, %zu)", strct->name->val, strct->align, strct->size); if (psi_plist_count(strct->args)) { psi_decl_type_dump_args_with_layout(fd, strct->args, 0); } else { - dprintf(fd, ";"); + PSI_DUMP(dump, ";"); } } diff --git a/src/types/decl_struct.h b/src/types/decl_struct.h index 51cdbe2..01f6595 100644 --- a/src/types/decl_struct.h +++ b/src/types/decl_struct.h @@ -46,7 +46,7 @@ struct psi_decl_struct { struct psi_decl_struct *psi_decl_struct_init(zend_string *name, struct psi_plist *args); void psi_decl_struct_free(struct psi_decl_struct **s_ptr); -void psi_decl_struct_dump(int fd, struct psi_decl_struct *strct); +void psi_decl_struct_dump(struct psi_dump *dump, struct psi_decl_struct *strct); bool psi_decl_struct_validate(struct psi_data *data, struct psi_decl_struct *s, struct psi_validate_scope *scope); diff --git a/src/types/decl_type.c b/src/types/decl_type.c index 51795b0..164f33f 100644 --- a/src/types/decl_type.c +++ b/src/types/decl_type.c @@ -294,60 +294,60 @@ void psi_decl_type_dump_args_with_layout(int fd, struct psi_plist *args, { size_t i = 0; - dprintf(fd, " {\n"); + PSI_DUMP(dump, " {\n"); if (args) { struct psi_decl_arg *sarg; ++level; while (psi_plist_get(args, i++, &sarg)) { - dprintf(fd, "%s", psi_t_indent(level)); - psi_decl_arg_dump(fd, sarg, level); + PSI_DUMP(dump, "%s", psi_t_indent(level)); + psi_decl_arg_dump(dump, sarg, level); if (sarg->layout) { if (sarg->layout->bfw) { - dprintf(fd, ":%zu", sarg->layout->bfw->len); + PSI_DUMP(dump, ":%zu", sarg->layout->bfw->len); } - dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos, + PSI_DUMP(dump, "::(%zu, %zu);\n", sarg->layout->pos, sarg->layout->len); } else { - dprintf(fd, ";\n"); + PSI_DUMP(dump, ";\n"); } } --level; } - dprintf(fd, "%s", psi_t_indent(level)); - dprintf(fd, "}"); + PSI_DUMP(dump, "%s", psi_t_indent(level)); + PSI_DUMP(dump, "}"); } -void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level) +void psi_decl_type_dump(struct psi_dump *dump, struct psi_decl_type *t, unsigned level) { switch (t->type) { case PSI_T_POINTER: - dprintf(fd, "%s *", t->name->val); + PSI_DUMP(dump, "%s *", t->name->val); return; case PSI_T_ENUM: - dprintf(fd, "enum "); + PSI_DUMP(dump, "enum "); if (psi_decl_type_is_anon(t->name, "enum")) { size_t i = 0, c = psi_plist_count(t->real.enm->items); struct psi_decl_enum_item *item; - dprintf(fd, "{\n"); + PSI_DUMP(dump, "{\n"); ++level; while (psi_plist_get(t->real.enm->items, i++, &item)) { - dprintf(fd, "%s", psi_t_indent(level)); - psi_decl_enum_item_dump(fd, item); + PSI_DUMP(dump, "%s", psi_t_indent(level)); + psi_decl_enum_item_dump(dump, item); if (i < c) { - dprintf(fd, "%s\n", i < c ? "," : ""); + PSI_DUMP(dump, "%s\n", i < c ? "," : ""); } } --level; - dprintf(fd, "%s\n} ", psi_t_indent(level)); + PSI_DUMP(dump, "%s\n} ", psi_t_indent(level)); return; } break; case PSI_T_STRUCT: - dprintf(fd, "struct "); + PSI_DUMP(dump, "struct "); if (psi_decl_type_is_anon(t->name, "struct")) { psi_decl_type_dump_args_with_layout(fd, t->real.strct->args, level); return; @@ -355,7 +355,7 @@ void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level) break; case PSI_T_UNION: - dprintf(fd, "union "); + PSI_DUMP(dump, "union "); if (psi_decl_type_is_anon(t->name, "union")) { psi_decl_type_dump_args_with_layout(fd, t->real.unn->args, level); return; @@ -363,14 +363,14 @@ void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level) break; case PSI_T_FUNCTION: - psi_decl_type_dump(fd, t->real.func->func->type, level); + psi_decl_type_dump(dump, t->real.func->func->type, level); return; default: break; } - dprintf(fd, "%s", t->name->val); + PSI_DUMP(dump, "%s", t->name->val); } int psi_decl_type_is_weak(struct psi_decl_type *type) diff --git a/src/types/decl_type.h b/src/types/decl_type.h index da95e64..d51220d 100644 --- a/src/types/decl_type.h +++ b/src/types/decl_type.h @@ -57,7 +57,7 @@ struct psi_decl_type { struct psi_decl_type *psi_decl_type_init(token_t type, zend_string *name); struct psi_decl_type *psi_decl_type_copy(struct psi_decl_type *src); void psi_decl_type_free(struct psi_decl_type **type_ptr); -void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level); +void psi_decl_type_dump(struct psi_dump *dump, struct psi_decl_type *t, unsigned level); bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type, struct psi_decl_arg *def, struct psi_validate_scope *scope); diff --git a/src/types/decl_union.c b/src/types/decl_union.c index 3ab8f69..a2daf2c 100644 --- a/src/types/decl_union.c +++ b/src/types/decl_union.c @@ -52,13 +52,13 @@ void psi_decl_union_free(struct psi_decl_union **u_ptr) } } -void psi_decl_union_dump(int fd, struct psi_decl_union *unn) +void psi_decl_union_dump(struct psi_dump *dump, struct psi_decl_union *unn) { - dprintf(fd, "union %s::(%zu, %zu)", unn->name->val, unn->align, unn->size); + PSI_DUMP(dump, "union %s::(%zu, %zu)", unn->name->val, unn->align, unn->size); if (psi_plist_count(unn->args)) { psi_decl_type_dump_args_with_layout(fd, unn->args, 0); } else { - dprintf(fd, ";"); + PSI_DUMP(dump, ";"); } } diff --git a/src/types/decl_union.h b/src/types/decl_union.h index 1227ed1..9d7fcc5 100644 --- a/src/types/decl_union.h +++ b/src/types/decl_union.h @@ -41,7 +41,7 @@ struct psi_decl_union { struct psi_decl_union *psi_decl_union_init(zend_string *name, struct psi_plist *args); void psi_decl_union_free(struct psi_decl_union **u_ptr); -void psi_decl_union_dump(int fd, struct psi_decl_union *unn); +void psi_decl_union_dump(struct psi_dump *dump, struct psi_decl_union *unn); bool psi_decl_union_validate(struct psi_data *data, struct psi_decl_union *u, struct psi_validate_scope *scope); diff --git a/src/types/decl_var.c b/src/types/decl_var.c index 49bc58f..376bb13 100644 --- a/src/types/decl_var.c +++ b/src/types/decl_var.c @@ -75,13 +75,13 @@ void psi_decl_var_free(struct psi_decl_var **var_ptr) } } -void psi_decl_var_dump(int fd, struct psi_decl_var *var) +void psi_decl_var_dump(struct psi_dump *dump, struct psi_decl_var *var) { - dprintf(fd, "%s%s", + PSI_DUMP(dump, "%s%s", psi_t_indirection(var->pointer_level - !!var->array_size), var->name ? var->name->val : "/**/"); if (var->array_size && var->arg->type->type != PSI_T_FUNCTION) { - dprintf(fd, "[%u]", var->array_size); + PSI_DUMP(dump, "[%u]", var->array_size); } } diff --git a/src/types/decl_var.h b/src/types/decl_var.h index ca9a5fd..08f4b14 100644 --- a/src/types/decl_var.h +++ b/src/types/decl_var.h @@ -44,7 +44,7 @@ struct psi_decl_var { struct psi_decl_var *psi_decl_var_init(zend_string *name, unsigned pl, unsigned as); struct psi_decl_var *psi_decl_var_copy(struct psi_decl_var *src); void psi_decl_var_free(struct psi_decl_var **var_ptr); -void psi_decl_var_dump(int fd, struct psi_decl_var *var); +void psi_decl_var_dump(struct psi_dump *dump, struct psi_decl_var *var); bool psi_decl_var_validate(struct psi_data *data, struct psi_decl_var *dvar, struct psi_validate_scope *scope); diff --git a/src/types/free_exp.c b/src/types/free_exp.c index 7d17756..1a29cd2 100644 --- a/src/types/free_exp.c +++ b/src/types/free_exp.c @@ -51,19 +51,19 @@ void psi_free_exp_free(struct psi_free_exp **f_ptr) } } -void psi_free_exp_dump(int fd, struct psi_free_exp *call) +void psi_free_exp_dump(struct psi_dump *dump, struct psi_free_exp *call) { size_t l = 0, c = psi_plist_count(call->vars); struct psi_decl_var *fvar; - dprintf(fd, "%s(", call->func->val); + PSI_DUMP(dump, "%s(", call->func->val); while (psi_plist_get(call->vars, l++, &fvar)) { - psi_decl_var_dump(fd, fvar); + psi_decl_var_dump(dump, fvar); if (l < c) { - dprintf(fd, ", "); + PSI_DUMP(dump, ", "); } } - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); } static inline struct psi_decl *locate_free_decl(struct psi_plist *decls, diff --git a/src/types/free_exp.h b/src/types/free_exp.h index a615868..01bbf28 100644 --- a/src/types/free_exp.h +++ b/src/types/free_exp.h @@ -44,7 +44,7 @@ struct psi_free_exp { struct psi_free_exp *psi_free_exp_init(zend_string *func, struct psi_plist *vars); void psi_free_exp_free(struct psi_free_exp **f_ptr); -void psi_free_exp_dump(int fd, struct psi_free_exp *call); +void psi_free_exp_dump(struct psi_dump *dump, struct psi_free_exp *call); bool psi_free_exp_validate(struct psi_data *data, struct psi_free_exp *fc, struct psi_validate_scope *scope); diff --git a/src/types/free_stmt.c b/src/types/free_stmt.c index 526f22d..b6254b3 100644 --- a/src/types/free_stmt.c +++ b/src/types/free_stmt.c @@ -45,19 +45,19 @@ void psi_free_stmt_free(struct psi_free_stmt **f_ptr) } } -void psi_free_stmt_dump(int fd, struct psi_free_stmt *fre) +void psi_free_stmt_dump(struct psi_dump *dump, struct psi_free_stmt *fre) { size_t i; struct psi_free_exp *exp; - dprintf(fd, "\tfree "); + PSI_DUMP(dump, "\tfree "); for (i = 0; psi_plist_get(fre->exps, i, &exp); ++i) { if (i) { - dprintf(fd, ", "); + PSI_DUMP(dump, ", "); } - psi_free_exp_dump(fd, exp); + psi_free_exp_dump(dump, exp); } - dprintf(fd, ";\n"); + PSI_DUMP(dump, ";\n"); } bool psi_free_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope) diff --git a/src/types/free_stmt.h b/src/types/free_stmt.h index f490f01..542fe6e 100644 --- a/src/types/free_stmt.h +++ b/src/types/free_stmt.h @@ -38,7 +38,7 @@ struct psi_free_stmt { struct psi_free_stmt *psi_free_stmt_init(struct psi_plist *calls); void psi_free_stmt_free(struct psi_free_stmt **f_ptr); -void psi_free_stmt_dump(int fd, struct psi_free_stmt *fre); +void psi_free_stmt_dump(struct psi_dump *dump, struct psi_free_stmt *fre); bool psi_free_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope); void psi_free_stmt_exec(struct psi_free_stmt *fre, struct psi_call_frame *frame); diff --git a/src/types/impl.c b/src/types/impl.c index 84bff97..c1b9b9a 100644 --- a/src/types/impl.c +++ b/src/types/impl.c @@ -87,7 +87,7 @@ void psi_impl_free(struct psi_impl **impl_ptr) } } -void psi_impl_dump(int fd, struct psi_impl *impl) +void psi_impl_dump(struct psi_dump *dump, struct psi_impl *impl) { size_t i; struct psi_return_stmt *ret; @@ -96,24 +96,24 @@ void psi_impl_dump(int fd, struct psi_impl *impl) struct psi_free_stmt *fre; struct psi_assert_stmt *ass; - psi_impl_func_dump(fd, impl->func); - dprintf(fd, " {\n"); + psi_impl_func_dump(dump, impl->func); + PSI_DUMP(dump, " {\n"); for (i = 0; psi_plist_get(impl->stmts.let, i, &let); ++i) { - psi_let_stmt_dump(fd, let); + psi_let_stmt_dump(dump, let); } for (i = 0; psi_plist_get(impl->stmts.ass, i, &ass); ++i) { - psi_assert_stmt_dump(fd, ass); + psi_assert_stmt_dump(dump, ass); } for (i = 0; psi_plist_get(impl->stmts.ret, i, &ret); ++i) { - psi_return_stmt_dump(fd, ret); + psi_return_stmt_dump(dump, ret); } for (i = 0; psi_plist_get(impl->stmts.set, i, &set); ++i) { - psi_set_stmt_dump(fd, set); + psi_set_stmt_dump(dump, set); } for (i = 0; psi_plist_get(impl->stmts.fre, i, &fre); ++i) { - psi_free_stmt_dump(fd, fre); + psi_free_stmt_dump(dump, fre); } - dprintf(fd, "}\n"); + PSI_DUMP(dump, "}\n"); } bool psi_impl_validate(struct psi_data *data, struct psi_impl *impl, diff --git a/src/types/impl.h b/src/types/impl.h index fd1c9d0..7123922 100644 --- a/src/types/impl.h +++ b/src/types/impl.h @@ -49,7 +49,7 @@ struct psi_impl { struct psi_impl *psi_impl_init(struct psi_impl_func *func, struct psi_plist *stmts); void psi_impl_free(struct psi_impl **impl_ptr); -void psi_impl_dump(int fd, struct psi_impl *impl); +void psi_impl_dump(struct psi_dump *dump, struct psi_impl *impl); bool psi_impl_validate(struct psi_data *data, struct psi_impl *impl, struct psi_validate_scope *scope); diff --git a/src/types/impl_arg.c b/src/types/impl_arg.c index 5de6161..12e09b6 100644 --- a/src/types/impl_arg.c +++ b/src/types/impl_arg.c @@ -52,14 +52,14 @@ void psi_impl_arg_free(struct psi_impl_arg **arg_ptr) } } -void psi_impl_arg_dump(int fd, struct psi_impl_arg *iarg, bool vararg) +void psi_impl_arg_dump(struct psi_dump *dump, struct psi_impl_arg *iarg, bool vararg) { - psi_impl_type_dump(fd, iarg->type); - dprintf(fd, " "); - psi_impl_var_dump(fd, iarg->var, vararg); + psi_impl_type_dump(dump, iarg->type); + PSI_DUMP(dump, " "); + psi_impl_var_dump(dump, iarg->var, vararg); if (iarg->def) { - dprintf(fd, " = "); - psi_impl_def_val_dump(fd, iarg->def); + PSI_DUMP(dump, " = "); + psi_impl_def_val_dump(dump, iarg->def); } } diff --git a/src/types/impl_arg.h b/src/types/impl_arg.h index d3e470a..4aea333 100644 --- a/src/types/impl_arg.h +++ b/src/types/impl_arg.h @@ -40,6 +40,6 @@ struct psi_impl_arg { struct psi_impl_arg *psi_impl_arg_init(struct psi_impl_type *type, struct psi_impl_var *var, struct psi_impl_def_val *def); void psi_impl_arg_free(struct psi_impl_arg **arg_ptr); -void psi_impl_arg_dump(int fd, struct psi_impl_arg *iarg, bool vararg); +void psi_impl_arg_dump(struct psi_dump *dump, struct psi_impl_arg *iarg, bool vararg); #endif diff --git a/src/types/impl_def_val.c b/src/types/impl_def_val.c index eec90e6..8b2d37b 100644 --- a/src/types/impl_def_val.c +++ b/src/types/impl_def_val.c @@ -26,6 +26,8 @@ #include "php_psi_stdinc.h" #include "data.h" +#include "zend_smart_str.h" + #include #include @@ -37,7 +39,11 @@ struct psi_impl_def_val *psi_impl_def_val_init(token_t t, void *data) switch ((def->type = t)) { case PSI_T_TRUE: + def->ival.zend.bval = 1; + /* no break */ case PSI_T_FALSE: + def->ityp = PSI_T_UINT8; + /* no break */ case PSI_T_NULL: break; case PSI_T_QUOTED_STRING: @@ -85,25 +91,271 @@ void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr) } } +void psi_impl_def_val_get_zval(struct psi_impl_def_val *val, token_t typ, zval *zv) +{ + impl_val tmp = val->ival; + + /* c->val has already been forced to the type of the containing constant or impl_arg */ + switch (typ) { + case PSI_T_BOOL: + ZVAL_BOOL(zv, tmp.zend.bval); + break; + case PSI_T_INT: + ZVAL_LONG(zv, tmp.zend.lval); + break; + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + is_double: ; + ZVAL_DOUBLE(zv, tmp.dval); + break; + case PSI_T_STRING: + is_string: ; + ZVAL_NEW_STR(zv, zend_string_copy(tmp.zend.str)); + if (ZSTR_IS_INTERNED(Z_STR_P(zv))) { + Z_TYPE_FLAGS_P(zv) = 0; + } + break; + case PSI_T_MIXED: + switch (val->type) { + case PSI_T_NULL: + ZVAL_NULL(zv); + break; + case PSI_T_TRUE: + ZVAL_TRUE(zv); + break; + case PSI_T_FALSE: + ZVAL_FALSE(zv); + break; + case PSI_T_STRING: + goto is_string; + break; + case PSI_T_NUMBER: + switch (val->ityp) { + case PSI_T_INT8: + case PSI_T_UINT8: + case PSI_T_INT16: + case PSI_T_UINT16: + case PSI_T_INT32: + case PSI_T_UINT32: + psi_calc_cast(val->ityp, &tmp, PSI_T_INT64, &tmp); + /* no break */ + case PSI_T_INT64: + ZVAL_LONG(zv, tmp.i64); + break; + case PSI_T_UINT64: + ZVAL_LONG_DOUBLE_STR(zv, tmp.u64, is_signed=false;persistent=true); + break; +#if HAVE_INT128 + case PSI_T_INT128: + ZVAL_LONG_DOUBLE_STR(zv, tmp.i128, is_signed=true;persistent=true); + break; + case PSI_T_UINT128: + ZVAL_LONG_DOUBLE_STR(zv, tmp.u128, is_signed=false;persistent=true); +#endif + break; + case PSI_T_FLOAT: + ZVAL_DOUBLE(zv, tmp.fval); + break; + case PSI_T_DOUBLE: + goto is_double; + break; +#if HAVE_LONG_DOUBLE + case PSI_T_LONG_DOUBLE: + ZVAL_DOUBLE(zv, tmp.ldval); + break; +#endif + default: + assert(0); + } + break; + default: + assert(0); + break; + } + break; + default: + assert(0); + break; + } + +} +/* +token_t psi_impl_def_val_get_zend(struct psi_impl_def_val *val, impl_val *res) +{ + switch (val->type) { + case PSI_T_NULL: + return PSI_T_NULL; + case PSI_T_TRUE: + case PSI_T_FALSE: + res->zend.bval = val->ival.zend.bval; + return PSI_T_BOOL; + case PSI_T_STRING: + res->zend.str = val->ival.zend.str + ? zend_string_copy(val->ival.zend.str) + : zend_empty_string; + return PSI_T_STRING; + case PSI_T_NUMBER: + switch (val->ityp) { + case PSI_T_FLOAT: + res->dval = val->ival.fval; + return PSI_T_DOUBLE; + case PSI_T_DOUBLE: + res->dval = val->ival.dval; + return PSI_T_DOUBLE; +#if HAVE_LONG_DOUBLE + case PSI_T_LONG_DOUBLE: + res->dval = val->ival.ldval; + return PSI_T_DOUBLE; +#endif + default: + psi_calc_cast(val->ityp, &val->ival, PSI_T_INT64, res); + return PSI_T_INT; + } + break; + default: + assert(0); + return 0; + } +} +*/ + +static inline bool psi_impl_def_val_validate_impl_type(struct psi_data *data, + struct psi_impl_def_val *val, struct psi_impl_type *type, + struct psi_validate_scope *scope) +{ + switch (type->type) { + case PSI_T_BOOL: + switch (val->type) { + case PSI_T_TRUE: + case PSI_T_FALSE: + return true; + case PSI_T_STRING: + if (val->ival.zend.str + && *val->ival.zend.str->val + && *val->ival.zend.str->val != '0') { + zend_string_release(val->ival.zend.str); + val->ival.zend.bval = 1; + } else { + if (val->ival.zend.str) { + zend_string_release(val->ival.zend.str); + } + val->ival.zend.bval = 0; + } + val->ityp = PSI_T_UINT8; + return true; + default: + assert(0); + break; + } + break; + case PSI_T_INT: + if (val->type == PSI_T_STRING) { + zend_string *str = val->ival.zend.str; + switch (is_numeric_str_function(str, &val->ival.zend.lval, &val->ival.dval)) { + case IS_DOUBLE: + val->ival.zend.lval = zend_dval_to_lval_cap(val->ival.dval); + /* no break */ + case IS_LONG: + break; + default: + val->ival.zend.lval = 0; + } + zend_string_release(str); + val->ityp = PSI_T_INT64; + return true; + } + psi_calc_cast(val->ityp, &val->ival, PSI_T_INT64, &val->ival); + val->type = val->ityp = PSI_T_INT64; + return true; + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + if (val->type == PSI_T_STRING) { + zend_string *str = val->ival.zend.str; + switch (is_numeric_str_function(str, &val->ival.zend.lval, &val->ival.dval)) { + case IS_LONG: + val->ival.dval = val->ival.zend.lval; + /* no break */ + case IS_DOUBLE: + break; + default: + val->ival.dval = 0; + } + zend_string_release(str); + val->type = val->ityp = PSI_T_DOUBLE; + return true; + } + psi_calc_cast(val->ityp, &val->ival, PSI_T_DOUBLE, &val->ival); + val->ityp = PSI_T_DOUBLE; + return true; + case PSI_T_STRING: + if (val->type == PSI_T_STRING) { + return true; + } else { + smart_str str = {0}; + + switch (val->ityp) { + CASE_IMPLVAL_NUM_PRINTF(smart_str_append_printf, &str, val->ival, false); + default: + assert(0); + } + val->ival.zend.str = smart_str_extract(&str); + val->type = PSI_T_STRING; + return true; + } + break; + default: + data->error(data, val->token, PSI_WARNING, + "Invalid default value type '%s', " + "expected one of bool, int, float/double or string.", + type->name->val); + + } + return false; +} + bool psi_impl_def_val_validate(struct psi_data *data, struct psi_impl_def_val *val, struct psi_impl_type *type, struct psi_validate_scope *scope) { + /* NULL can be anything */ if (val->type == PSI_T_NULL) { return true; - } else if (val->type == PSI_T_NUMBER) { + } + + /* a number can be anything */ + if (val->type == PSI_T_NUMBER) { if (!psi_num_exp_validate(data, val->data.num, scope)) { return false; } + val->ityp = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp); + } + + /* forced type, like `const foo`, or function param ` $xyz` */ + if (type) { + return psi_impl_def_val_validate_impl_type(data, val, type, scope); + } + + switch (val->type) { + case PSI_T_NUMBER: + case PSI_T_NULL: + case PSI_T_TRUE: + case PSI_T_FALSE: + case PSI_T_STRING: + return true; + default: + assert(0); + break; } + return false; +/* switch (type ? type->type : PSI_T_MIXED) { case PSI_T_BOOL: val->ival.zend.bval = val->type == PSI_T_TRUE ? 1 : 0; return true; break; - /* macros */ + // macros case PSI_T_NUMBER: if (val->type == PSI_T_NUMBER) { token_t typ = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp); @@ -111,7 +363,7 @@ bool psi_impl_def_val_validate(struct psi_data *data, switch (typ) { case PSI_T_FLOAT: val->ival.dval = val->ival.fval; - /* no break */ + // no break case PSI_T_DOUBLE: val->type = PSI_T_FLOAT; type->type = PSI_T_FLOAT; @@ -125,7 +377,7 @@ bool psi_impl_def_val_validate(struct psi_data *data, val->ival.u64); } default: - /* FIXME big integers */ + // FIXME big integers val->type = PSI_T_INT; type->type = PSI_T_INT; zend_string_release(type->name); @@ -172,105 +424,58 @@ bool psi_impl_def_val_validate(struct psi_data *data, case PSI_T_STRING: if (val->type == PSI_T_STRING) { - return true; + return true; data->error(data, val->token, PSI_WARNING, + "Invalid default value type '%s', " + "expected one of bool, int, float, string.", + type ? type->name->val : "mixed"); + } break; case PSI_T_MIXED: - switch (val->type) { - case PSI_T_TRUE: - case PSI_T_FALSE: - case PSI_T_NULL: - case PSI_T_STRING: - case PSI_T_FLOAT: - case PSI_T_DOUBLE: - case PSI_T_INT: - return true; - default: - break; - } - if (val->type == PSI_T_NUMBER) { - token_t typ = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp); - switch (typ) { - case PSI_T_FLOAT: -#if HAVE_LONG_DOUBLE - case PSI_T_LONG_DOUBLE: -#endif - promote_double: ; - psi_calc_cast(typ, &val->ival, PSI_T_DOUBLE, &val->ival); - /* no break */ - case PSI_T_DOUBLE: - val->type = PSI_T_DOUBLE; - return true; - case PSI_T_UINT64: - if (val->ival.u64 > (uint64_t) ZEND_LONG_MAX) { - if (val->ival.u64 > (1LU<<53)) { - char buf[0x20]; - - /* convert to string */ - char *res = zend_print_ulong_to_buf(buf + sizeof(buf) - 1, val->ival.u64); - val->type = PSI_T_STRING; - val->ival.zend.str = zend_string_init(res, buf + sizeof(buf) - 1 - res, 1); - - return true; - } - goto promote_double; - } - /* no break */ - default: - psi_calc_cast(typ, &val->ival, PSI_T_INT64, &val->ival); - /* no break */ - case PSI_T_INT64: - val->type = PSI_T_INT; - return true; - } } - /* no break */ + // no break default: - data->error(data, val->token, PSI_WARNING, - "Invalid default value type '%s', " - "expected one of bool, int, float, string.", - type ? type->name->val : "mixed"); } - - return false; +*/ } -void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val) { +void psi_impl_def_val_dump(struct psi_dump *dump, struct psi_impl_def_val *val) { switch (val->type) { case PSI_T_NULL: - dprintf(fd, "NULL"); + PSI_DUMP(dump, "NULL"); break; case PSI_T_TRUE: - dprintf(fd, "true"); + PSI_DUMP(dump, "true"); break; case PSI_T_FALSE: - dprintf(fd, "false"); + PSI_DUMP(dump, "false"); break; case PSI_T_BOOL: - dprintf(fd, "%s", val->ival.zend.bval ? "true" : "false"); + PSI_DUMP(dump, "%s", val->ival.zend.bval ? "true" : "false"); break; case PSI_T_INT: - dprintf(fd, ZEND_LONG_FMT, val->ival.zend.lval); + PSI_DUMP(dump, ZEND_LONG_FMT, val->ival.zend.lval); break; case PSI_T_FLOAT: case PSI_T_DOUBLE: if (isinf(val->ival.dval)) { - dprintf(fd, "\\INF"); + PSI_DUMP(dump, "\\INF"); } else if (isnan(val->ival.dval)) { - dprintf(fd, "\\NAN"); + PSI_DUMP(dump, "\\NAN"); } else { - dprintf(fd, "%" PRIdval, val->ival.dval); + PSI_DUMP(dump, "%" PRIdval, val->ival.dval); } break; case PSI_T_STRING: - dprintf(fd, "\"%s\"", val->ival.zend.str->val); + PSI_DUMP(dump, "\"%s\"", val->ival.zend.str->val); break; case PSI_T_NUMBER: - psi_num_exp_dump(fd, val->data.num); + psi_num_exp_dump(dump, val->data.num); break; default: assert(0); } + PSI_DUMP(dump, "\t/* t=%d */ ", val->type); } diff --git a/src/types/impl_def_val.h b/src/types/impl_def_val.h index e597745..1345005 100644 --- a/src/types/impl_def_val.h +++ b/src/types/impl_def_val.h @@ -31,6 +31,7 @@ struct psi_data; struct psi_impl_type; +struct psi_dump; struct psi_impl_def_val { struct psi_token *token; @@ -38,13 +39,14 @@ struct psi_impl_def_val { union { struct psi_num_exp *num; } data; + token_t ityp; impl_val ival; }; struct psi_impl_def_val *psi_impl_def_val_init(token_t t, void *data); void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr); -void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val); +void psi_impl_def_val_dump(struct psi_dump *dump, struct psi_impl_def_val *val); bool psi_impl_def_val_validate(struct psi_data *data, struct psi_impl_def_val *def, struct psi_impl_type *cmp, struct psi_validate_scope *scope); - +token_t psi_impl_def_val_get_zend(struct psi_impl_def_val *val, impl_val *res); #endif diff --git a/src/types/impl_func.c b/src/types/impl_func.c index a6f45e6..56c61d8 100644 --- a/src/types/impl_func.c +++ b/src/types/impl_func.c @@ -85,25 +85,25 @@ bool psi_impl_func_validate(struct psi_data *data, struct psi_impl_func *func, return true; } -void psi_impl_func_dump(int fd, struct psi_impl_func *func) +void psi_impl_func_dump(struct psi_dump *dump, struct psi_impl_func *func) { - dprintf(fd, "function %s(", func->name->val); + PSI_DUMP(dump, "function %s(", func->name->val); if (func->args) { size_t i = 0; struct psi_impl_arg *iarg; while (psi_plist_get(func->args, i++, &iarg)) { if (i > 1) { - dprintf(fd, ", "); + PSI_DUMP(dump, ", "); } - psi_impl_arg_dump(fd, iarg, false); + psi_impl_arg_dump(dump, iarg, false); } if (func->vararg) { - dprintf(fd, ", "); - psi_impl_arg_dump(fd, func->vararg, true); + PSI_DUMP(dump, ", "); + psi_impl_arg_dump(dump, func->vararg, true); } } - dprintf(fd, ") : %s%s", func->return_reference ? "&" : "", + PSI_DUMP(dump, ") : %s%s", func->return_reference ? "&" : "", func->return_type->name->val); } diff --git a/src/types/impl_func.h b/src/types/impl_func.h index 38ebf68..f55f10c 100644 --- a/src/types/impl_func.h +++ b/src/types/impl_func.h @@ -46,7 +46,7 @@ struct psi_impl_func { struct psi_impl_func *psi_impl_func_init(zend_string *name, struct psi_plist *args, struct psi_impl_type *return_type); void psi_impl_func_free(struct psi_impl_func **f_ptr); -void psi_impl_func_dump(int fd, struct psi_impl_func *func); +void psi_impl_func_dump(struct psi_dump *dump, struct psi_impl_func *func); bool psi_impl_func_validate(struct psi_data *data, struct psi_impl_func *func, struct psi_validate_scope *scope); diff --git a/src/types/impl_type.c b/src/types/impl_type.c index be173aa..41baf1c 100644 --- a/src/types/impl_type.c +++ b/src/types/impl_type.c @@ -36,9 +36,9 @@ struct psi_impl_type *psi_impl_type_init(token_t type, zend_string *name) return t; } -void psi_impl_type_dump(int fd, struct psi_impl_type *type) +void psi_impl_type_dump(struct psi_dump *dump, struct psi_impl_type *type) { - dprintf(fd, "%s", type->name->val); + PSI_DUMP(dump, "%s", type->name->val); } void psi_impl_type_free(struct psi_impl_type **type_ptr) diff --git a/src/types/impl_type.h b/src/types/impl_type.h index 7c5a6fe..4a60e02 100644 --- a/src/types/impl_type.h +++ b/src/types/impl_type.h @@ -36,6 +36,6 @@ struct psi_impl_type { struct psi_impl_type *psi_impl_type_init(token_t type, zend_string *name); void psi_impl_type_free(struct psi_impl_type **type_ptr); -void psi_impl_type_dump(int fd, struct psi_impl_type *type); +void psi_impl_type_dump(struct psi_dump *dump, struct psi_impl_type *type); #endif diff --git a/src/types/impl_val.h b/src/types/impl_val.h index 9b28a7d..186a080 100644 --- a/src/types/impl_val.h +++ b/src/types/impl_val.h @@ -69,21 +69,42 @@ typedef union impl_val { # define isnanl isnan #endif #if HAVE_LONG_DOUBLE -# define CASE_IMPLVAL_LD_PRINTF(fun, to, ival) \ +# define CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix) \ case PSI_T_LONG_DOUBLE: \ if (isinfl(ival.ldval)) { \ fun(to, "\\INF"); \ } else if (isnanl(ival.ldval)) { \ fun(to, "\\NAN"); \ } else { \ - fun(to, "%" PRIldval "L", ival.ldval); \ + fun(to, "%" PRIldval "%s", ival.ldval, (with_suffix) ? "L" : ""); \ } \ break; #else # define CASE_IMPLVAL_LD_PRINTF(fun, to, ival) #endif -#define CASE_IMPLVAL_NUM_PRINTF(fun, to, ival) \ +#define CASE_IMPLVAL_FLOAT_PRINTF(fun, to, ival, with_suffix) \ + CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix); \ + case PSI_T_FLOAT: \ + if (isinf(ival.dval)) { \ + fun(to, "\\INF"); \ + } else if (isnan(ival.dval)) { \ + fun(to, "\\NAN"); \ + } else { \ + fun(to, "%" PRIfval "%s", ival.dval, (with_suffix) ? "F" : ""); \ + } \ + break; \ + case PSI_T_DOUBLE: \ + if (isinf(ival.dval)) { \ + fun(to, "\\INF"); \ + } else if (isnan(ival.dval)) { \ + fun(to, "\\NAN"); \ + } else { \ + fun(to, "%" PRIdval, ival.dval); \ + } \ + break + +#define CASE_IMPLVAL_INT_PRINTF(fun, to, ival, with_suffix) \ case PSI_T_INT8: \ fun(to, "%" PRId8, ival.i8); \ break; \ @@ -100,32 +121,17 @@ typedef union impl_val { fun(to, "%" PRId32, ival.i32); \ break; \ case PSI_T_UINT32: \ - fun(to, "%" PRIu32 "U", ival.u32); \ + fun(to, "%" PRIu32 "%s", ival.u32, (with_suffix) ? "U" : ""); \ break; \ case PSI_T_INT64: \ - fun(to, "%" PRId64 "L", ival.i64); \ + fun(to, "%" PRId64 "%s", ival.i64, (with_suffix) ? "L" : ""); \ break; \ case PSI_T_UINT64: \ - fun(to, "%" PRIu64 "UL", ival.u64); \ - break; \ - case PSI_T_FLOAT: \ - if (isinf(ival.dval)) { \ - fun(to, "\\INF"); \ - } else if (isnan(ival.dval)) { \ - fun(to, "\\NAN"); \ - } else { \ - fun(to, "%" PRIfval "F", ival.dval); \ - } \ - break; \ - case PSI_T_DOUBLE: \ - if (isinf(ival.dval)) { \ - fun(to, "\\INF"); \ - } else if (isnan(ival.dval)) { \ - fun(to, "\\NAN"); \ - } else { \ - fun(to, "%" PRIdval, ival.dval); \ - } \ - break; \ - CASE_IMPLVAL_LD_PRINTF(fun, to, ival) + fun(to, "%" PRIu64 "%s", ival.u64, (with_suffix) ? "UL" : ""); \ + break + +#define CASE_IMPLVAL_NUM_PRINTF(fun, to, ival, with_suffix) \ + CASE_IMPLVAL_INT_PRINTF(fun, to, ival, with_suffix); \ + CASE_IMPLVAL_FLOAT_PRINTF(fun, to, ival, with_suffix) #endif diff --git a/src/types/impl_var.c b/src/types/impl_var.c index d3ab4f8..7d727af 100644 --- a/src/types/impl_var.c +++ b/src/types/impl_var.c @@ -67,9 +67,9 @@ void psi_impl_var_free(struct psi_impl_var **var_ptr) } } -void psi_impl_var_dump(int fd, struct psi_impl_var *var, bool vararg) +void psi_impl_var_dump(struct psi_dump *dump, struct psi_impl_var *var, bool vararg) { - dprintf(fd, "%s%s%s", + PSI_DUMP(dump, "%s%s%s", var->reference ? "&" : "", vararg ? "..." : "", var->name->val); diff --git a/src/types/impl_var.h b/src/types/impl_var.h index 2a179ad..aaab32d 100644 --- a/src/types/impl_var.h +++ b/src/types/impl_var.h @@ -41,7 +41,7 @@ struct psi_impl_var { struct psi_impl_var *psi_impl_var_init(zend_string *name, bool is_reference); struct psi_impl_var *psi_impl_var_copy(struct psi_impl_var *var); void psi_impl_var_free(struct psi_impl_var **var_ptr); -void psi_impl_var_dump(int fd, struct psi_impl_var *var, bool vararg); +void psi_impl_var_dump(struct psi_dump *dump, struct psi_impl_var *var, bool vararg); bool psi_impl_var_validate(struct psi_data *data, struct psi_impl_var *ivar, struct psi_validate_scope *scope); diff --git a/src/types/let_callback.c b/src/types/let_callback.c index 4d65df4..abe2141 100644 --- a/src/types/let_callback.c +++ b/src/types/let_callback.c @@ -125,22 +125,22 @@ bool psi_let_callback_validate(struct psi_data *data, struct psi_let_callback *c return true; } -void psi_let_callback_dump(int fd, struct psi_let_callback *callback, +void psi_let_callback_dump(struct psi_dump *dump, struct psi_let_callback *callback, unsigned level) { - dprintf(fd, "callback("); + PSI_DUMP(dump, "callback("); if (callback->cb_args) { size_t i = 0; struct psi_decl_var *cb_arg; while (psi_plist_get(callback->cb_args, i++, &cb_arg)) { if (i > 1) { - dprintf(fd, ", "); + PSI_DUMP(dump, ", "); } - psi_decl_var_dump(fd, cb_arg); + psi_decl_var_dump(dump, cb_arg); } } - dprintf(fd, ") as %s(%s(", + PSI_DUMP(dump, ") as %s(%s(", callback->func->name->val, callback->func->var->name->val); @@ -148,14 +148,14 @@ void psi_let_callback_dump(int fd, struct psi_let_callback *callback, size_t i = 0, last = psi_plist_count(callback->args); struct psi_set_exp *set; - dprintf(fd, "\n"); + PSI_DUMP(dump, "\n"); ++level; while (psi_plist_get(callback->args, i++, &set)) { - psi_set_exp_dump(fd, set, level, i == last); - dprintf(fd, "\n"); + psi_set_exp_dump(dump, set, level, i == last); + PSI_DUMP(dump, "\n"); } --level; - dprintf(fd, "%s", psi_t_indent(level)); + PSI_DUMP(dump, "%s", psi_t_indent(level)); } - dprintf(fd, "))"); + PSI_DUMP(dump, "))"); } diff --git a/src/types/let_callback.h b/src/types/let_callback.h index e10b32a..d545359 100644 --- a/src/types/let_callback.h +++ b/src/types/let_callback.h @@ -44,7 +44,7 @@ struct psi_let_callback { struct psi_let_callback *psi_let_callback_init(struct psi_let_func *func, struct psi_plist *args, struct psi_plist *cb_args); void psi_let_callback_free(struct psi_let_callback **cb_ptr); -void psi_let_callback_dump(int fd, struct psi_let_callback *cb, unsigned level); +void psi_let_callback_dump(struct psi_dump *dump, struct psi_let_callback *cb, unsigned level); bool psi_let_callback_validate(struct psi_data *data, struct psi_let_callback *cb, struct psi_validate_scope *scope); #endif diff --git a/src/types/let_calloc.c b/src/types/let_calloc.c index 152e5c8..46badc0 100644 --- a/src/types/let_calloc.c +++ b/src/types/let_calloc.c @@ -50,11 +50,11 @@ void psi_let_calloc_free(struct psi_let_calloc **alloc_ptr) } } -void psi_let_calloc_dump(int fd, struct psi_let_calloc *alloc) +void psi_let_calloc_dump(struct psi_dump *dump, struct psi_let_calloc *alloc) { - dprintf(fd, "calloc("); - psi_num_exp_dump(fd, alloc->nmemb); - dprintf(fd, ", "); - psi_num_exp_dump(fd, alloc->size); - dprintf(fd, ")"); + PSI_DUMP(dump, "calloc("); + psi_num_exp_dump(dump, alloc->nmemb); + PSI_DUMP(dump, ", "); + psi_num_exp_dump(dump, alloc->size); + PSI_DUMP(dump, ")"); } diff --git a/src/types/let_calloc.h b/src/types/let_calloc.h index 6caeb8d..04bfa41 100644 --- a/src/types/let_calloc.h +++ b/src/types/let_calloc.h @@ -38,6 +38,6 @@ struct psi_let_calloc { struct psi_let_calloc *psi_let_calloc_init(struct psi_num_exp *nmemb, struct psi_num_exp *size); void psi_let_calloc_free(struct psi_let_calloc **alloc_ptr); -void psi_let_calloc_dump(int fd, struct psi_let_calloc *alloc); +void psi_let_calloc_dump(struct psi_dump *dump, struct psi_let_calloc *alloc); #endif diff --git a/src/types/let_exp.c b/src/types/let_exp.c index 97eec8f..55bf576 100644 --- a/src/types/let_exp.c +++ b/src/types/let_exp.c @@ -102,42 +102,42 @@ void psi_let_exp_free(struct psi_let_exp **let_ptr) } } -void psi_let_exp_dump(int fd, struct psi_let_exp *val, unsigned level, int last) +void psi_let_exp_dump(struct psi_dump *dump, struct psi_let_exp *val, unsigned level, int last) { if (level > 1) { /* only if not directly after `set ...` */ - dprintf(fd, "%s", psi_t_indent(level)); + PSI_DUMP(dump, "%s", psi_t_indent(level)); } if (val->var) { if (val->var->token) { - psi_decl_var_dump(fd, val->var); - dprintf(fd, " = "); + psi_decl_var_dump(dump, val->var); + PSI_DUMP(dump, " = "); } } if (val->is_reference) { - dprintf(fd, "&"); + PSI_DUMP(dump, "&"); } switch (val->kind) { case PSI_LET_NULL: - dprintf(fd, "NULL"); + PSI_DUMP(dump, "NULL"); break; case PSI_LET_TMP: - psi_decl_var_dump(fd, val->data.var); - dprintf(fd, "\t/* fqn=%s */", val->data.var->fqn->val); + psi_decl_var_dump(dump, val->data.var); + PSI_DUMP(dump, "\t/* fqn=%s */", val->data.var->fqn->val); break; case PSI_LET_CALLOC: - psi_let_calloc_dump(fd, val->data.alloc); + psi_let_calloc_dump(dump, val->data.alloc); break; case PSI_LET_CALLBACK: - psi_let_callback_dump(fd, val->data.callback, level); + psi_let_callback_dump(dump, val->data.callback, level); break; case PSI_LET_FUNC: - psi_let_func_dump(fd, val->data.func, level); + psi_let_func_dump(dump, val->data.func, level); break; case PSI_LET_NUMEXP: - psi_num_exp_dump(fd, val->data.num); + psi_num_exp_dump(dump, val->data.num); break; default: @@ -145,15 +145,15 @@ void psi_let_exp_dump(int fd, struct psi_let_exp *val, unsigned level, int last) } if (val->var) { - dprintf(fd, "\t/* fqn=%s */", val->var->fqn->val); + PSI_DUMP(dump, "\t/* fqn=%s */", val->var->fqn->val); } if (level > 1) { if (!last) { - dprintf(fd, ","); + PSI_DUMP(dump, ","); } } else { - dprintf(fd, ";"); + PSI_DUMP(dump, ";"); } } diff --git a/src/types/let_exp.h b/src/types/let_exp.h index 91cb1ef..caa6cff 100644 --- a/src/types/let_exp.h +++ b/src/types/let_exp.h @@ -62,7 +62,7 @@ struct psi_let_exp { struct psi_let_exp *psi_let_exp_init(enum psi_let_exp_kind kind, void *data); struct psi_let_exp *psi_let_exp_init_ex(struct psi_decl_var *var, enum psi_let_exp_kind kind, void *data); void psi_let_exp_free(struct psi_let_exp **let_ptr); -void psi_let_exp_dump(int fd, struct psi_let_exp *exp, unsigned level, int last); +void psi_let_exp_dump(struct psi_dump *dump, struct psi_let_exp *exp, unsigned level, int last); void *psi_let_exp_exec(struct psi_let_exp *exp, struct psi_decl_arg *darg, void *actual_location, size_t actual_size, struct psi_call_frame *frame); bool psi_let_exp_validate(struct psi_data *data, struct psi_let_exp *exp, struct psi_validate_scope *scope); diff --git a/src/types/let_func.c b/src/types/let_func.c index fd8b49f..4a61632 100644 --- a/src/types/let_func.c +++ b/src/types/let_func.c @@ -58,26 +58,26 @@ void psi_let_func_free(struct psi_let_func **func_ptr) } } -void psi_let_func_dump(int fd, struct psi_let_func *func, unsigned level) +void psi_let_func_dump(struct psi_dump *dump, struct psi_let_func *func, unsigned level) { - dprintf(fd, "%s(%s\t/* fqn=%s */", func->name->val, func->var->name->val, + PSI_DUMP(dump, "%s(%s\t/* fqn=%s */", func->name->val, func->var->name->val, func->var->fqn->val); if (func->inner) { size_t i = 0, count = psi_plist_count(func->inner); struct psi_let_exp *inner; - dprintf(fd, ","); + PSI_DUMP(dump, ","); ++level; while (psi_plist_get(func->inner, i++, &inner)) { - dprintf(fd, "\n"); - psi_let_exp_dump(fd, inner, level, i == count); + PSI_DUMP(dump, "\n"); + psi_let_exp_dump(dump, inner, level, i == count); } --level; - dprintf(fd, "\n"); - dprintf(fd, "%s", psi_t_indent(level)); + PSI_DUMP(dump, "\n"); + PSI_DUMP(dump, "%s", psi_t_indent(level)); } - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); } static inline int validate_let_func_type(struct psi_data *data, diff --git a/src/types/let_func.h b/src/types/let_func.h index 5313a93..957bd97 100644 --- a/src/types/let_func.h +++ b/src/types/let_func.h @@ -45,7 +45,7 @@ struct psi_let_func { struct psi_let_func *psi_let_func_init(token_t type, zend_string *name, struct psi_impl_var *var); void psi_let_func_free(struct psi_let_func **func_ptr); -void psi_let_func_dump(int fd, struct psi_let_func *func, unsigned level); +void psi_let_func_dump(struct psi_dump *dump, struct psi_let_func *func, unsigned level); void *psi_let_func_exec(struct psi_let_exp *func_val, struct psi_let_func *func, struct psi_decl_arg *darg, struct psi_call_frame *frame); bool psi_let_func_validate(struct psi_data *data, struct psi_let_func *func, struct psi_validate_scope *scope); diff --git a/src/types/let_stmt.c b/src/types/let_stmt.c index c64856b..776d206 100644 --- a/src/types/let_stmt.c +++ b/src/types/let_stmt.c @@ -48,11 +48,11 @@ void psi_let_stmt_free(struct psi_let_stmt **stmt_ptr) } } -void psi_let_stmt_dump(int fd, struct psi_let_stmt *let) +void psi_let_stmt_dump(struct psi_dump *dump, struct psi_let_stmt *let) { - dprintf(fd, "\t%s ", let->exp->kind == PSI_LET_TMP ? "temp" : "let"); - psi_let_exp_dump(fd, let->exp, 1, 1); - dprintf(fd, "\n"); + PSI_DUMP(dump, "\t%s ", let->exp->kind == PSI_LET_TMP ? "temp" : "let"); + psi_let_exp_dump(dump, let->exp, 1, 1); + PSI_DUMP(dump, "\n"); } bool psi_let_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope) diff --git a/src/types/let_stmt.h b/src/types/let_stmt.h index 37ef118..ab657bc 100644 --- a/src/types/let_stmt.h +++ b/src/types/let_stmt.h @@ -39,7 +39,7 @@ struct psi_let_stmt { struct psi_let_stmt *psi_let_stmt_init(struct psi_let_exp *exp); void psi_let_stmt_free(struct psi_let_stmt **stmt_ptr); -void psi_let_stmt_dump(int fd, struct psi_let_stmt *stmt); +void psi_let_stmt_dump(struct psi_dump *dump, struct psi_let_stmt *stmt); void *psi_let_stmt_exec(struct psi_let_stmt *stmt, struct psi_call_frame *frame); bool psi_let_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope); diff --git a/src/types/num_exp.c b/src/types/num_exp.c index ab99dd9..ce89de5 100644 --- a/src/types/num_exp.c +++ b/src/types/num_exp.c @@ -380,30 +380,30 @@ struct psi_plist *psi_num_exp_tokens(struct psi_num_exp *exp, return list; } -void psi_num_exp_dump(int fd, struct psi_num_exp *exp) +void psi_num_exp_dump(struct psi_dump *dump, struct psi_num_exp *exp) { switch (exp->op) { case PSI_T_NUMBER: - psi_number_dump(fd, exp->data.n); + psi_number_dump(dump, exp->data.n); break; case PSI_T_CAST: - dprintf(fd, "("); + PSI_DUMP(dump, "("); psi_decl_type_dump(1, exp->data.c.typ, 0); - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); break; case PSI_T_NOT: case PSI_T_TILDE: unary: - dprintf(fd, "%s", psi_num_exp_op_tok(exp->op)); - psi_num_exp_dump(fd, exp->data.u); + PSI_DUMP(dump, "%s", psi_num_exp_op_tok(exp->op)); + psi_num_exp_dump(dump, exp->data.u); break; case PSI_T_LPAREN: - dprintf(fd, "("); - psi_num_exp_dump(fd, exp->data.u); - dprintf(fd, ")"); + PSI_DUMP(dump, "("); + psi_num_exp_dump(dump, exp->data.u); + PSI_DUMP(dump, ")"); break; case PSI_T_PLUS: @@ -429,17 +429,17 @@ void psi_num_exp_dump(int fd, struct psi_num_exp *exp) case PSI_T_CMP_GE: case PSI_T_RCHEVR: case PSI_T_LCHEVR: - psi_num_exp_dump(fd, exp->data.b.lhs); - dprintf(fd, " %s ", psi_num_exp_op_tok(exp->op)); - psi_num_exp_dump(fd, exp->data.b.rhs); + psi_num_exp_dump(dump, exp->data.b.lhs); + PSI_DUMP(dump, " %s ", psi_num_exp_op_tok(exp->op)); + psi_num_exp_dump(dump, exp->data.b.rhs); break; case PSI_T_IIF: - psi_num_exp_dump(fd, exp->data.t.cond); - dprintf(fd, " ? "); - psi_num_exp_dump(fd, exp->data.t.truthy); - dprintf(fd, " : "); - psi_num_exp_dump(fd, exp->data.t.falsy); + psi_num_exp_dump(dump, exp->data.t.cond); + PSI_DUMP(dump, " ? "); + psi_num_exp_dump(dump, exp->data.t.truthy); + PSI_DUMP(dump, " : "); + psi_num_exp_dump(dump, exp->data.t.falsy); break; default: diff --git a/src/types/num_exp.h b/src/types/num_exp.h index df7c6f5..db3aaf0 100644 --- a/src/types/num_exp.h +++ b/src/types/num_exp.h @@ -77,7 +77,7 @@ void psi_num_exp_free(struct psi_num_exp **c_ptr); struct psi_num_exp *psi_num_exp_copy(struct psi_num_exp *exp); void psi_num_exp_copy_ctor(struct psi_num_exp **exp_ptr); -void psi_num_exp_dump(int fd, struct psi_num_exp *exp); +void psi_num_exp_dump(struct psi_dump *dump, struct psi_num_exp *exp); bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp, struct psi_validate_scope *scope); diff --git a/src/types/number.c b/src/types/number.c index 840eb03..7c05c85 100644 --- a/src/types/number.c +++ b/src/types/number.c @@ -292,37 +292,37 @@ struct psi_plist *psi_number_tokens(struct psi_number *exp, return list; } -void psi_number_dump(int fd, struct psi_number *exp) +void psi_number_dump(struct psi_dump *dump, struct psi_number *exp) { switch (exp->type) { case PSI_T_DEFINED: - CASE_IMPLVAL_NUM_PRINTF(dprintf, fd, exp->data.ival) + CASE_IMPLVAL_NUM_PRINTF(dump->fun, dump->ctx, exp->data.ival, 1); case PSI_T_NULL: - dprintf(fd, "NULL"); + PSI_DUMP(dump, "NULL"); break; case PSI_T_NUMBER: case PSI_T_NSNAME: case PSI_T_DEFINE: case PSI_T_QUOTED_CHAR: case PSI_T_CPP_HEADER: - dprintf(fd, "%s", exp->data.numb->val); + PSI_DUMP(dump, "%s", exp->data.numb->val); break; case PSI_T_FUNCTION: - psi_cpp_macro_call_dump(fd, exp->data.call); + psi_cpp_macro_call_dump(dump, exp->data.call); break; case PSI_T_CONST: - dprintf(fd, "%s", exp->data.cnst->name->val); + PSI_DUMP(dump, "%s", exp->data.cnst->name->val); break; case PSI_T_ENUM: - dprintf(fd, "%s", exp->data.enm->name->val); + PSI_DUMP(dump, "%s", exp->data.enm->name->val); break; case PSI_T_NAME: - psi_decl_var_dump(fd, exp->data.dvar); + psi_decl_var_dump(dump, exp->data.dvar); break; case PSI_T_SIZEOF: - dprintf(fd, "sizeof("); - psi_decl_type_dump(fd, exp->data.dtyp, 0); - dprintf(fd, ")"); + PSI_DUMP(dump, "sizeof("); + psi_decl_type_dump(dump, exp->data.dtyp, 0); + PSI_DUMP(dump, ")"); break; default: assert(0); @@ -493,7 +493,6 @@ static inline bool psi_number_validate_number(struct psi_data *data, struct psi_ case PSI_NUMBER_FLT: switch (exp->flags & 0x0ff00) { case PSI_NUMBER_F: - case PSI_NUMBER_DF: tmp.fval = strtof(exp->data.numb->val, NULL); zend_string_release(exp->data.numb); exp->type = PSI_T_FLOAT; @@ -510,6 +509,7 @@ static inline bool psi_number_validate_number(struct psi_data *data, struct psi_ #endif case PSI_NUMBER_DD: default: + case PSI_NUMBER_DF: tmp.dval = strtod(exp->data.numb->val, NULL); zend_string_release(exp->data.numb); exp->type = PSI_T_DOUBLE; @@ -606,6 +606,10 @@ bool psi_number_validate(struct psi_data *data, struct psi_number *exp, case PSI_T_UINT32: case PSI_T_INT64: case PSI_T_UINT64: +#if HAVE_INT128 + case PSI_T_INT128: + case PSI_T_UINT128: +#endif case PSI_T_FLOAT: case PSI_T_DOUBLE: #if HAVE_LONG_DOUBLE @@ -873,7 +877,16 @@ token_t psi_number_eval(struct psi_number *exp, impl_val *res, *res = exp->data.ival; if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu64, res->u64); return PSI_T_UINT64; - +#if HAVE_INT128 + case PSI_T_INT128: + *res = exp->data.ival; + //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIi128, res->i128); + return PSI_T_INT128; + case PSI_T_UINT128: + *res = exp->data.ival; + //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu128, res->u128); + return PSI_T_UINT128; +#endif case PSI_T_FLOAT: *res = exp->data.ival; if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIfval, res->fval); diff --git a/src/types/number.h b/src/types/number.h index b2a61cc..5d73b5e 100644 --- a/src/types/number.h +++ b/src/types/number.h @@ -76,7 +76,7 @@ struct psi_number { struct psi_number *psi_number_init(token_t t, void *num, unsigned flags); struct psi_number *psi_number_copy(struct psi_number *exp); void psi_number_free(struct psi_number **exp_ptr); -void psi_number_dump(int fd, struct psi_number *exp); +void psi_number_dump(struct psi_dump *dump, struct psi_number *exp); bool psi_number_validate(struct psi_data *data, struct psi_number *exp, struct psi_validate_scope *scope); diff --git a/src/types/return_exp.c b/src/types/return_exp.c index d66c55c..5d2795a 100644 --- a/src/types/return_exp.c +++ b/src/types/return_exp.c @@ -60,30 +60,30 @@ void psi_return_exp_free(struct psi_return_exp **exp_ptr) } } -void psi_return_exp_dump(int fd, struct psi_return_exp *exp) +void psi_return_exp_dump(struct psi_dump *dump, struct psi_return_exp *exp) { if (exp->func) { - psi_decl_var_dump(fd, exp->func); - dprintf(fd, "("); + psi_decl_var_dump(dump, exp->func); + PSI_DUMP(dump, "("); if (exp->args) { size_t i = 0; struct psi_decl_var *arg; while (psi_plist_get(exp->args, i++, &arg)) { if (i > 1) { - dprintf(fd, ", "); + PSI_DUMP(dump, ", "); } - psi_decl_var_dump(fd, arg); + psi_decl_var_dump(dump, arg); } } - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); } if (exp->set) { if (exp->func) { - dprintf(fd, " as "); + PSI_DUMP(dump, " as "); } - psi_set_exp_dump(fd, exp->set, 1, 1); + psi_set_exp_dump(dump, exp->set, 1, 1); } } diff --git a/src/types/return_exp.h b/src/types/return_exp.h index b76313a..ead554a 100644 --- a/src/types/return_exp.h +++ b/src/types/return_exp.h @@ -36,7 +36,7 @@ struct psi_return_exp { struct psi_return_exp *psi_return_exp_init(struct psi_decl_var *func, struct psi_plist *args, struct psi_set_exp *set); void psi_return_exp_free(struct psi_return_exp **exp_ptr); -void psi_return_exp_dump(int fd, struct psi_return_exp *exp); +void psi_return_exp_dump(struct psi_dump *dump, struct psi_return_exp *exp); void psi_return_exp_exec(struct psi_return_exp *exp, zval *return_value, struct psi_call_frame *frame); bool psi_return_exp_validate(struct psi_data *data, struct psi_return_exp *exp, diff --git a/src/types/return_stmt.c b/src/types/return_stmt.c index 0c4df36..41a17ee 100644 --- a/src/types/return_stmt.c +++ b/src/types/return_stmt.c @@ -52,11 +52,11 @@ void psi_return_stmt_free(struct psi_return_stmt **ret_ptr) } } -void psi_return_stmt_dump(int fd, struct psi_return_stmt *ret) +void psi_return_stmt_dump(struct psi_dump *dump, struct psi_return_stmt *ret) { - dprintf(fd, "\treturn "); - psi_return_exp_dump(fd, ret->exp); - dprintf(fd, ";\n"); + PSI_DUMP(dump, "\treturn "); + psi_return_exp_dump(dump, ret->exp); + PSI_DUMP(dump, ";\n"); } bool psi_return_stmt_validate(struct psi_data *data, diff --git a/src/types/return_stmt.h b/src/types/return_stmt.h index 7d088a6..c030427 100644 --- a/src/types/return_stmt.h +++ b/src/types/return_stmt.h @@ -41,7 +41,7 @@ struct psi_return_stmt { struct psi_return_stmt *psi_return_stmt_init(struct psi_return_exp *exp); void psi_return_stmt_free(struct psi_return_stmt **ret_ptr); -void psi_return_stmt_dump(int fd, struct psi_return_stmt *ret); +void psi_return_stmt_dump(struct psi_dump *dump, struct psi_return_stmt *ret); void psi_return_stmt_exec(struct psi_return_stmt *ret, zval *return_value, struct psi_call_frame *frame); bool psi_return_stmt_validate(struct psi_data *data, struct psi_validate_scope *impl); diff --git a/src/types/set_exp.c b/src/types/set_exp.c index aea0747..80c166c 100644 --- a/src/types/set_exp.c +++ b/src/types/set_exp.c @@ -123,37 +123,37 @@ void psi_set_exp_free(struct psi_set_exp **exp_ptr) } } -void psi_set_exp_dump(int fd, struct psi_set_exp *set, unsigned level, int last) +void psi_set_exp_dump(struct psi_dump *dump, struct psi_set_exp *set, unsigned level, int last) { if (level > 1) { /* only if not directly after `set ...` */ - dprintf(fd, "%s", psi_t_indent(level)); + PSI_DUMP(dump, "%s", psi_t_indent(level)); } if (set->var) { /* parsed, or generated */ if (set->var->token) { - dprintf(fd, "%s = ", set->var->name->val); + PSI_DUMP(dump, "%s = ", set->var->name->val); } } switch (set->kind) { case PSI_SET_FUNC: - psi_set_func_dump(fd, set->data.func, level); + psi_set_func_dump(dump, set->data.func, level); break; case PSI_SET_NUMEXP: - psi_num_exp_dump(fd, set->data.num); + psi_num_exp_dump(dump, set->data.num); break; default: assert(0); } if (!last) { - dprintf(fd, ","); + PSI_DUMP(dump, ","); } if (set->var) { - dprintf(fd, "\t/* fqn=%s */", set->var->fqn->val); + PSI_DUMP(dump, "\t/* fqn=%s */", set->var->fqn->val); } } diff --git a/src/types/set_exp.h b/src/types/set_exp.h index cf19ff9..151736e 100644 --- a/src/types/set_exp.h +++ b/src/types/set_exp.h @@ -54,7 +54,7 @@ struct psi_set_exp { struct psi_set_exp *psi_set_exp_init(enum psi_set_exp_kind kind, void *data); void psi_set_exp_free(struct psi_set_exp **exp_ptr); -void psi_set_exp_dump(int fd, struct psi_set_exp *set, unsigned level, int last); +void psi_set_exp_dump(struct psi_dump *dump, struct psi_set_exp *set, unsigned level, int last); void psi_set_exp_exec(struct psi_set_exp *val, struct psi_call_frame *frame); void psi_set_exp_exec_ex(struct psi_set_exp *val, zval *zv, impl_val *iv, struct psi_call_frame *frame); bool psi_set_exp_validate(struct psi_data *data, struct psi_set_exp *set, struct psi_validate_scope *scope); diff --git a/src/types/set_func.c b/src/types/set_func.c index caf32ff..96ab6a1 100644 --- a/src/types/set_func.c +++ b/src/types/set_func.c @@ -51,30 +51,30 @@ void psi_set_func_free(struct psi_set_func **func_ptr) } } -void psi_set_func_dump(int fd, struct psi_set_func *func, unsigned level) +void psi_set_func_dump(struct psi_dump *dump, struct psi_set_func *func, unsigned level) { - dprintf(fd, "%s(", func->name->val); - psi_decl_var_dump(fd, func->var); - dprintf(fd, "\t/* fqn=%s */", func->var->fqn->val); + PSI_DUMP(dump, "%s(", func->name->val); + psi_decl_var_dump(dump, func->var); + PSI_DUMP(dump, "\t/* fqn=%s */", func->var->fqn->val); if (func->inner && !func->recursive) { size_t i = 0, count = psi_plist_count(func->inner); struct psi_set_exp *inner; - dprintf(fd, ","); + PSI_DUMP(dump, ","); ++level; while (psi_plist_get(func->inner, i++, &inner)) { - dprintf(fd, "\n"); - psi_set_exp_dump(fd, inner, level, i == count); + PSI_DUMP(dump, "\n"); + psi_set_exp_dump(dump, inner, level, i == count); } --level; } if (func->recursive) { - dprintf(fd, ", ..."); + PSI_DUMP(dump, ", ..."); } if (func->inner && !func->recursive) { - dprintf(fd, "\n%s", psi_t_indent(level)); + PSI_DUMP(dump, "\n%s", psi_t_indent(level)); } - dprintf(fd, ")"); + PSI_DUMP(dump, ")"); } static inline bool psi_set_func_validate_to_string(struct psi_data *data, diff --git a/src/types/set_func.h b/src/types/set_func.h index 3f6ef25..8b3b2d4 100644 --- a/src/types/set_func.h +++ b/src/types/set_func.h @@ -45,7 +45,7 @@ struct psi_set_func { struct psi_set_func *psi_set_func_init(token_t type, zend_string *name, struct psi_decl_var *var); void psi_set_func_free(struct psi_set_func **func_ptr); -void psi_set_func_dump(int fd, struct psi_set_func *func, unsigned level); +void psi_set_func_dump(struct psi_dump *dump, struct psi_set_func *func, unsigned level); bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, struct psi_validate_scope *scope); diff --git a/src/types/set_stmt.c b/src/types/set_stmt.c index 1917571..fca2519 100644 --- a/src/types/set_stmt.c +++ b/src/types/set_stmt.c @@ -51,11 +51,11 @@ void psi_set_stmt_free(struct psi_set_stmt **set_ptr) } } -void psi_set_stmt_dump(int fd, struct psi_set_stmt *set) +void psi_set_stmt_dump(struct psi_dump *dump, struct psi_set_stmt *set) { - dprintf(fd, "\tset "); - psi_set_exp_dump(fd, set->exp, 1, 1); - dprintf(fd, ";\n"); + PSI_DUMP(dump, "\tset "); + psi_set_exp_dump(dump, set->exp, 1, 1); + PSI_DUMP(dump, ";\n"); } diff --git a/src/types/set_stmt.h b/src/types/set_stmt.h index a4e40fa..1ca7f93 100644 --- a/src/types/set_stmt.h +++ b/src/types/set_stmt.h @@ -39,7 +39,7 @@ struct psi_set_stmt { struct psi_set_stmt *psi_set_stmt_init(struct psi_set_exp *val); void psi_set_stmt_free(struct psi_set_stmt **set_ptr); -void psi_set_stmt_dump(int fd, struct psi_set_stmt *set); +void psi_set_stmt_dump(struct psi_dump *dump, struct psi_set_stmt *set); void psi_set_stmt_exec(struct psi_set_stmt *set, struct psi_call_frame *frame); bool psi_set_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope); -- 2.30.2