From: Michael Wallner Date: Thu, 19 Nov 2015 12:36:53 +0000 (+0100) Subject: flush X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=61918592ab618c073b9846783ce79fed9f26c5f7;p=m6w6%2Fext-psi flush --- diff --git a/config.m4 b/config.m4 index 77373a8..0b11787 100644 --- a/config.m4 +++ b/config.m4 @@ -238,7 +238,7 @@ if test "$PHP_PSI" != "no"; then fi ], [], PSI_INCLUDES_DEFAULT($4)) ]) - if test "$1" != "$psi_struct_name" + if test "$1" = "$psi_struct_name" then PSI_TYPES="{PSI_T_STRUCT, \"$psi_struct_name\", \"$psi_struct_name\"}, $PSI_TYPES" fi diff --git a/php_psi.h b/php_psi.h index b4b96e8..066d9d6 100644 --- a/php_psi.h +++ b/php_psi.h @@ -32,11 +32,11 @@ int psi_internal_type(impl_type *type); zend_internal_arg_info *psi_internal_arginfo(impl *impl); size_t psi_num_min_args(impl *impl); -void psi_to_bool(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var); -void psi_to_int(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var); -void psi_to_double(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var); -void psi_to_string(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var); -void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var); +void psi_to_bool(zval *return_value, set_value *set, impl_val *ret_val); +void psi_to_int(zval *return_value, set_value *set, impl_val *ret_val); +void psi_to_double(zval *return_value, set_value *set, impl_val *ret_val); +void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val); +void psi_to_array(zval *return_value, set_value *set, impl_val *ret_val); void psi_call(zend_execute_data *execute_data, zval *return_value, impl *impl); diff --git a/src/context.c b/src/context.c index 987fb9a..d7eabb5 100644 --- a/src/context.c +++ b/src/context.c @@ -14,6 +14,9 @@ #include "context.h" #include "parser.h" +#include "libjit.h" +#include "libffi.h" + #define psi_predef_count(of) ((sizeof(psi_predef ##of## s)/sizeof(psi_predef ##of))-1) typedef struct psi_predef_type { token_t type_tag; @@ -275,14 +278,15 @@ static inline int validate_decl(PSI_Data *data, void *dl, decl *decl) { } static inline decl_arg *locate_struct_member(decl_struct *s, decl_var *var) { - size_t i; + if (s->args) { + size_t i; - ZEND_ASSERT(s); - for (i = 0; i < s->args->count; ++i) { - decl_arg *darg = s->args->args[i]; + for (i = 0; i < s->args->count; ++i) { + decl_arg *darg = s->args->args[i]; - if (!strcmp(var->name, darg->var->name)) { - return var->arg = darg; + if (!strcmp(var->name, darg->var->name)) { + return var->arg = darg; + } } } @@ -315,33 +319,53 @@ static inline int validate_set_value(PSI_Data *data, set_value *set, decl_arg *r if (strcmp(set_var->name, ref->var->name)) { return 0; } + ZEND_ASSERT(!set_var->arg || set_var->arg == ref); + set_var->arg = ref; - if (set->count && (set->func->type != PSI_T_TO_ARRAY || ref_type->type != PSI_T_STRUCT)) { - data->error(E_WARNING, "Inner `set` statement casts only work with to_array() casts on structs"); + if (set->count && (set->func->type != PSI_T_TO_ARRAY || (ref_type->type != PSI_T_STRUCT && !ref->var->arg->var->pointer_level))) { + data->error(E_WARNING, "Inner `set` statement casts only work with to_array() casts on structs or pointers"); return 0; } - for (i = 0; i < set->count; ++i) { - decl_var *sub_var = set->inner[i]->vars->vars[0]; - decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var); + + if (ref_type->type == PSI_T_STRUCT) { + for (i = 0; i < set->count; ++i) { + decl_var *sub_var = set->inner[i]->vars->vars[0]; + decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var); + + if (sub_ref) { + if (!validate_set_value(data, set->inner[i], sub_ref)) { + return 0; + } + } + } + } else if (set->count == 1) { + decl_var *sub_var = set->inner[0]->vars->vars[0]; + decl_arg *sub_ref = sub_var->arg; if (sub_ref) { - if (!validate_set_value(data, set->inner[i], sub_ref)) { + if (!validate_set_value(data, set->inner[0], sub_ref)) { return 0; } } + } else if (set->count > 1) { + data->error(E_WARNING, "Inner `set` statement casts on pointers may only occur once"); + return 0; } return 1; } static inline decl *locate_impl_decl(decls *decls, return_stmt *ret) { - size_t i; + if (decls) { + size_t i; - for (i = 0; i < decls->count; ++i) { - if (!strcmp(decls->list[i]->func->var->name, ret->set->vars->vars[0]->name)) { - ret->decl = decls->list[i]->func; - return decls->list[i]; + for (i = 0; i < decls->count; ++i) { + if (!strcmp(decls->list[i]->func->var->name, ret->set->vars->vars[0]->name)) { + ret->decl = decls->list[i]->func; + return decls->list[i]; + } } } + return NULL; } static inline int validate_impl_ret_stmt(PSI_Data *data, impl *impl) { @@ -486,14 +510,17 @@ static inline int validate_impl_set_stmts(PSI_Data *data, impl *impl) { return 1; } static inline decl *locate_free_decl(decls *decls, free_call *f) { - size_t i; + if (decls) { + size_t i; - for (i = 0; i < decls->count; ++i) { - if (!strcmp(decls->list[i]->func->var->name, f->func)) { - f->decl = decls->list[i]; - return decls->list[i]; + for (i = 0; i < decls->count; ++i) { + if (!strcmp(decls->list[i]->func->var->name, f->func)) { + f->decl = decls->list[i]; + return decls->list[i]; + } } } + return NULL; } static inline int validate_impl_free_stmts(PSI_Data *data, impl *impl) { @@ -739,7 +766,7 @@ static int psi_select_dirent(const struct dirent *entry) void PSI_ContextBuild(PSI_Context *C, const char *paths) { - int i, n; + int i, n, flags = getenv("PSI_DEBUG") ? PSI_PARSER_DEBUG : 0; char *sep = NULL, *cpy = strdup(paths), *ptr = cpy; struct dirent **entries = NULL; @@ -762,7 +789,7 @@ void PSI_ContextBuild(PSI_Context *C, const char *paths) C->error(PSI_WARNING, "Path to PSI file too long: %s/%s", ptr, entries[i]->d_name); } - if (!PSI_ParserInit(&P, psi, C->error, 0)) { + if (!PSI_ParserInit(&P, psi, C->error, flags)) { C->error(PSI_WARNING, "Failed to init PSI parser (%s): %s", psi, strerror(errno)); continue; @@ -836,6 +863,68 @@ void PSI_ContextCall(PSI_Context *C, impl_val *ret_val, decl *decl) C->ops->call(C, ret_val, decl); } +static inline void dump_decl_type(int fd, decl_type *t) { + const char *pre; + + switch (t->type) { + case PSI_T_STRUCT: + pre = "struct "; + break; + default: + pre = ""; + } + dprintf(fd, "%s%s", pre, t->name); +} +static inline void dump_decl_var(int fd, decl_var *v) { + dprintf(fd, "%.*s%s", v->pointer_level-!!v->array_size, "**********", v->name); + if (v->array_size) { + dprintf(fd, "[%u]", v->array_size); + } +} +static inline void dump_decl_arg(int fd, decl_arg *a) { + dump_decl_type(fd, a->type); + dprintf(fd, " "); + dump_decl_var(fd, a->var); +} +void PSI_ContextDump(PSI_Context *C, int fd) +{ + size_t i, j; + +#ifdef HAVE_LIBJIT + if (C->ops == PSI_Libjit()) { + dprintf(fd, "#PSI(libjit)\n"); + } +#endif +#ifdef HAVE_LIBFFI + if (C->ops == PSI_Libffi()) { + dprintf(fd, "#PSI(libffi)\n"); + } +#endif + + if (C->defs) for (i = 0; i < C->defs->count; ++i) { + decl_typedef *tdef = C->defs->list[i]; + + dprintf(fd, "typedef "); + dump_decl_type(fd, tdef->type); + dprintf(fd, " %s;\n", tdef->alias); + } + if (C->structs) for (i = 0; i < C->structs->count; ++i) { + decl_struct *strct = C->structs->list[i]; + decl_arg *sarg = NULL; + + dprintf(fd, "struct %s::(%zu) {\n", strct->name, strct->size); + for (j = 0; j < strct->args->count; ++j) { + sarg = strct->args->args[j]; + dprintf(fd, "\t"); + dump_decl_arg(fd, sarg); + dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos, sarg->layout->len); + } + dprintf(fd, "}\n"); + } + + dprintf(fd, "\n"); +} + void PSI_ContextDtor(PSI_Context *C) { size_t i; @@ -847,15 +936,19 @@ void PSI_ContextDtor(PSI_Context *C) free_decl_libs(&C->psi.libs); - for (i = 0; i < C->count; ++i) { - PSI_DataDtor(&C->data[i]); + if (C->data) { + for (i = 0; i < C->count; ++i) { + PSI_DataDtor(&C->data[i]); + } + free(C->data); } - free(C->data); - for (zfe = C->closures; zfe->fname; ++zfe) { - free((void *) zfe->arg_info); + if (C->closures) { + for (zfe = C->closures; zfe->fname; ++zfe) { + free((void *) zfe->arg_info); + } + free(C->closures); } - free(C->closures); if (C->consts) { if (C->consts->list) { diff --git a/src/context.h b/src/context.h index 4f86444..e68eddf 100644 --- a/src/context.h +++ b/src/context.h @@ -31,6 +31,7 @@ void PSI_ContextBuild(PSI_Context *C, const char *path); int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P); zend_function_entry *PSI_ContextCompile(PSI_Context *C); void PSI_ContextCall(PSI_Context *C, impl_val *ret_val, decl *decl); +void PSI_ContextDump(PSI_Context *C, int fd); void PSI_ContextDtor(PSI_Context *C); void PSI_ContextFree(PSI_Context **C); diff --git a/src/libffi.c b/src/libffi.c index bb1f34f..d515827 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -192,14 +192,17 @@ static void psi_ffi_init(PSI_Context *C) C->context = PSI_LibffiContextInit(NULL); } -static void psi_ffi_dtor(PSI_Context *C) { - size_t i; +static void psi_ffi_dtor(PSI_Context *C) +{ + if (C->decls) { + size_t i; - for (i = 0; i < C->decls->count; ++i) { - decl *decl = C->decls->list[i]; + for (i = 0; i < C->decls->count; ++i) { + decl *decl = C->decls->list[i]; - if (decl->call.info) { - PSI_LibffiCallFree(decl->call.info); + if (decl->call.info) { + PSI_LibffiCallFree(decl->call.info); + } } } free(C->context); diff --git a/src/libjit.c b/src/libjit.c index 6e2760d..45ee8e7 100644 --- a/src/libjit.c +++ b/src/libjit.c @@ -149,12 +149,14 @@ static void psi_jit_init(PSI_Context *C) static void psi_jit_dtor(PSI_Context *C) { - size_t i; + if (C->decls) { + size_t i; - for (i = 0; i < C->decls->count; ++i) { - decl *decl = C->decls->list[i]; + for (i = 0; i < C->decls->count; ++i) { + decl *decl = C->decls->list[i]; - PSI_LibjitCallFree(decl->call.info); + PSI_LibjitCallFree(decl->call.info); + } } PSI_LibjitContextFree((void *) &C->context); } diff --git a/src/module.c b/src/module.c index 20b25ea..8637bab 100644 --- a/src/module.c +++ b/src/module.c @@ -204,8 +204,10 @@ size_t psi_num_min_args(impl *impl) return n; } -void psi_to_bool(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var) +void psi_to_bool(zval *return_value, set_value *set, impl_val *ret_val) { + decl_var *var = set->vars->vars[0]; + token_t t = real_decl_type(var->arg->type)->type; impl_val *v = deref_impl_val(ret_val, var); switch (t) { @@ -222,8 +224,10 @@ void psi_to_bool(zval *return_value, token_t t, impl_val *ret_val, set_value *se convert_to_boolean(return_value); } -void psi_to_int(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var) +void psi_to_int(zval *return_value, set_value *set, impl_val *ret_val) { + decl_var *var = set->vars->vars[0]; + token_t t = real_decl_type(var->arg->type)->type; impl_val *v = deref_impl_val(ret_val, var); switch (t) { @@ -240,8 +244,10 @@ void psi_to_int(zval *return_value, token_t t, impl_val *ret_val, set_value *set convert_to_long(return_value); } -void psi_to_double(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var) +void psi_to_double(zval *return_value, set_value *set, impl_val *ret_val) { + decl_var *var = set->vars->vars[0]; + token_t t = real_decl_type(var->arg->type)->type; impl_val *v = deref_impl_val(ret_val, var); switch (t) { @@ -257,8 +263,11 @@ void psi_to_double(zval *return_value, token_t t, impl_val *ret_val, set_value * } } -void psi_to_string(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var) +void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val) { + decl_var *var = set->vars->vars[0]; + token_t t = real_decl_type(var->arg->type)->type; + switch (t) { case PSI_T_INT8: case PSI_T_UINT8: @@ -346,17 +355,18 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr) return mem; } -void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, set_value *set, decl_var *var) +void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) { zval ele; unsigned i; - impl_val tmp; + decl_var *var = set->vars->vars[0]; + token_t t = real_decl_type(var->arg->type)->type; + impl_val tmp, *ret_val = deref_impl_val(r_val, var); array_init(return_value); if (t == PSI_T_STRUCT) { decl_struct *s = real_decl_type(var->arg->type)->strct; - ret_val = deref_impl_val(ret_val, var); ZEND_ASSERT(s); @@ -370,13 +380,12 @@ void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, set_value *s decl_arg *sub_arg = sub_var->arg; if (sub_arg) { - token_t t = real_decl_type(sub_arg->type)->type; void *ptr = malloc(sub_arg->layout->len); memcpy(ptr, (char *) ret_val->ptr + sub_arg->layout->pos, sub_arg->layout->len); tmp_ptr = enref_impl_val(ptr, sub_arg->var); - sub_set->func->handler(&ztmp, t, tmp_ptr, sub_set, sub_var); + sub_set->func->handler(&ztmp, sub_set, tmp_ptr); add_assoc_zval(return_value, sub_var->name, &ztmp); free(tmp_ptr); if (tmp_ptr != ptr) { @@ -386,7 +395,6 @@ void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, set_value *s } } return; - // for (i = 0; i < s->args->count; ++i) { // decl_arg *darg = s->args->args[i]; // impl_val tmp, tmp_ptr; @@ -425,25 +433,36 @@ void psi_to_array(zval *return_value, token_t t, impl_val *ret_val, set_value *s // } // add_assoc_zval(return_value, darg->var->name, &ztmp); // } - return; } - ret_val = deref_impl_val(ret_val, var); - for (i = 0; i < var->arg->var->array_size; ++i) { - impl_val *ptr = iterate(ret_val, t, i, &tmp); + if (var->arg->var->array_size) { + /* to_array(foo[NUMBER]) */ + for (i = 0; i < var->arg->var->array_size; ++i) { + impl_val *ptr = iterate(ret_val, t, i, &tmp); + + switch (t) { + case PSI_T_FLOAT: + ZVAL_DOUBLE(&ele, (double) ptr->fval); + break; + case PSI_T_DOUBLE: + ZVAL_DOUBLE(&ele, ptr->dval); + break; + default: + ZVAL_LONG(&ele, ptr->lval); + break; + } - switch (t) { - case PSI_T_FLOAT: - ZVAL_DOUBLE(&ele, (double) ptr->fval); - break; - case PSI_T_DOUBLE: - ZVAL_DOUBLE(&ele, ptr->dval); - break; - default: - ZVAL_LONG(&ele, ptr->lval); - break; + add_next_index_zval(return_value, &ele); } + return; + } else { + /* pointer to something */ + impl_val *ptr; - add_next_index_zval(return_value, &ele); + for (i = 0; (ptr = iterate(ret_val, t, i, &tmp)); ++i) { + if (!ptr->ptr) { + break; + } + } } } @@ -606,20 +625,15 @@ static inline void *psi_do_let(decl_arg *darg) static inline void psi_do_set(zval *return_value, set_value *set) { - impl_val *val = (impl_val *) &set->vars->vars[0]->arg->let->ptr; - token_t t = real_decl_type(set->vars->vars[0]->arg->type)->type; - ZVAL_DEREF(return_value); zval_dtor(return_value); - set->func->handler(return_value, t, val, set, set->vars->vars[0]); + set->func->handler(return_value, set, set->vars->vars[0]->arg->let->ptr); } static inline void psi_do_return(zval *return_value, return_stmt *ret, impl_val *ret_val) { - token_t t = real_decl_type(ret->decl->type)->type; - - ret->set->func->handler(return_value, t, ret_val, ret->set, ret->decl->var); + ret->set->func->handler(return_value, ret->set, ret_val); } static inline void psi_do_free(free_stmt *fre) @@ -739,6 +753,10 @@ PHP_MINIT_FUNCTION(psi) PSI_ContextInit(&PSI_G(context), ops, psi_error); PSI_ContextBuild(&PSI_G(context), PSI_G(directory)); + if (getenv("PSI_DUMP")) { + PSI_ContextDump(&PSI_G(context), STDOUT_FILENO); + } + return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(psi) diff --git a/src/parser.h b/src/parser.h index d8955e5..683192b 100644 --- a/src/parser.h +++ b/src/parser.h @@ -351,7 +351,7 @@ typedef union impl_val { static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) { unsigned i; - if (var->arg->var != var) for (i = 0; i < var->pointer_level; ++i) { + if (var->arg->var != var) for (i = 1; i < var->pointer_level; ++i) { ret_val = *(void **) ret_val; } return ret_val; @@ -595,7 +595,7 @@ struct set_value; typedef struct set_func { token_t type; char *name; - void (*handler)(zval *, token_t, impl_val *, struct set_value *set, decl_var *); + void (*handler)(zval *, struct set_value *set, impl_val *ret_val); } set_func; static inline set_func *init_set_func(token_t type, const char *name) { diff --git a/src/parser.re b/src/parser.re index 0eae943..81005f2 100644 --- a/src/parser.re +++ b/src/parser.re @@ -144,21 +144,6 @@ void PSI_ParserFree(PSI_Parser **P) return t; \ } while(1) -/* DIGIT = [0-9] - DIGITS = DIGIT+ - DECIMALS = (+|-)? DIGIT* "." - digits ::= digits DIGIT. - decimals ::= digits DOT digits. - decimals ::= DOT digits. - decimals ::= digits DOT. - number ::= digits. - number ::= PLUS digits. - number ::= MINUS digits. - number ::= decimals. - number ::= MINUS decimals. - number ::= PLUS decimals. - -*/ token_t PSI_ParserScan(PSI_Parser *P) { for (;;) { @@ -179,7 +164,7 @@ token_t PSI_ParserScan(PSI_Parser *P) QUOTED_STRING = "\"" ([^\"])+ "\""; NUMBER = [+-]? [0-9]* "."? [0-9]+ ([eE] [+-]? [0-9]+)?; - "#" .* "\n" { ++P->line; RETURN(PSI_T_COMMENT);} + ("#"|"//") .* "\n" { ++P->line; continue;} "(" {RETURN(PSI_T_LPAREN);} ")" {RETURN(PSI_T_RPAREN);} ";" {RETURN(PSI_T_EOS);} diff --git a/src/parser_proc.h b/src/parser_proc.h index 7f3e440..3c07664 100644 --- a/src/parser_proc.h +++ b/src/parser_proc.h @@ -4,25 +4,25 @@ #define PSI_T_LET 4 #define PSI_T_RETURN 5 #define PSI_T_LIB 6 -#define PSI_T_COMMENT 7 +#define PSI_T_INT 7 #define PSI_T_QUOTED_STRING 8 #define PSI_T_EOS 9 #define PSI_T_STRUCT 10 #define PSI_T_LBRACE 11 #define PSI_T_RBRACE 12 -#define PSI_T_BOOL 13 -#define PSI_T_INT 14 -#define PSI_T_FLOAT 15 -#define PSI_T_STRING 16 -#define PSI_T_CONST 17 -#define PSI_T_NSNAME 18 -#define PSI_T_EQUALS 19 -#define PSI_T_TYPEDEF 20 -#define PSI_T_LPAREN 21 -#define PSI_T_RPAREN 22 -#define PSI_T_VOID 23 -#define PSI_T_LBRACKET 24 -#define PSI_T_NUMBER 25 +#define PSI_T_COLON 13 +#define PSI_T_LPAREN 14 +#define PSI_T_NUMBER 15 +#define PSI_T_RPAREN 16 +#define PSI_T_BOOL 17 +#define PSI_T_FLOAT 18 +#define PSI_T_STRING 19 +#define PSI_T_CONST 20 +#define PSI_T_NSNAME 21 +#define PSI_T_EQUALS 22 +#define PSI_T_TYPEDEF 23 +#define PSI_T_VOID 24 +#define PSI_T_LBRACKET 25 #define PSI_T_RBRACKET 26 #define PSI_T_COMMA 27 #define PSI_T_DOUBLE 28 @@ -35,24 +35,23 @@ #define PSI_T_INT64 35 #define PSI_T_UINT64 36 #define PSI_T_FUNCTION 37 -#define PSI_T_COLON 38 -#define PSI_T_REFERENCE 39 -#define PSI_T_NULL 40 -#define PSI_T_TRUE 41 -#define PSI_T_FALSE 42 -#define PSI_T_DOLLAR 43 -#define PSI_T_CALLOC 44 -#define PSI_T_ARRVAL 45 -#define PSI_T_STRLEN 46 -#define PSI_T_STRVAL 47 -#define PSI_T_FLOATVAL 48 -#define PSI_T_INTVAL 49 -#define PSI_T_BOOLVAL 50 -#define PSI_T_TO_ARRAY 51 -#define PSI_T_TO_STRING 52 -#define PSI_T_TO_INT 53 -#define PSI_T_TO_FLOAT 54 -#define PSI_T_TO_BOOL 55 -#define PSI_T_MIXED 56 -#define PSI_T_ARRAY 57 -#define PSI_T_POINTER 58 +#define PSI_T_REFERENCE 38 +#define PSI_T_NULL 39 +#define PSI_T_TRUE 40 +#define PSI_T_FALSE 41 +#define PSI_T_DOLLAR 42 +#define PSI_T_CALLOC 43 +#define PSI_T_ARRVAL 44 +#define PSI_T_STRLEN 45 +#define PSI_T_STRVAL 46 +#define PSI_T_FLOATVAL 47 +#define PSI_T_INTVAL 48 +#define PSI_T_BOOLVAL 49 +#define PSI_T_TO_ARRAY 50 +#define PSI_T_TO_STRING 51 +#define PSI_T_TO_INT 52 +#define PSI_T_TO_FLOAT 53 +#define PSI_T_TO_BOOL 54 +#define PSI_T_MIXED 55 +#define PSI_T_ARRAY 56 +#define PSI_T_POINTER 57 diff --git a/src/parser_proc.y b/src/parser_proc.y index 69d6955..f3a51f4 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -19,15 +19,13 @@ } %nonassoc NAME. -%fallback NAME FREE SET LET RETURN LIB. +%fallback NAME FREE SET LET RETURN LIB INT. file ::= blocks. blocks ::= block. blocks ::= blocks block. -block ::= COMMENT. - block ::= LIB(T) QUOTED_STRING(libname) EOS. { if (P->psi.file.ln) { PSI_ParserSyntaxError(P, P->psi.file.ln, T->line, "Extra 'lib %s' statement has no effect", libname->text); @@ -59,11 +57,21 @@ block ::= decl_struct(strct). { %type decl_struct {decl_struct*} %destructor decl_struct {free_decl_struct($$);} -decl_struct(strct) ::= STRUCT NAME(N) LBRACE struct_args(args) RBRACE. { +decl_struct(strct) ::= STRUCT NAME(N) struct_size(size_) LBRACE struct_args(args) RBRACE. { strct = init_decl_struct(N->text, args); + strct->size = size_; free(N); } +%type struct_size {size_t} +struct_size(size) ::= . { + size = 0; +} +struct_size(size) ::= COLON COLON LPAREN NUMBER(SIZ) RPAREN. { + size = atol(SIZ->text); + free(SIZ); +} + %token_class const_type_token BOOL INT FLOAT STRING. %type const_type {const_type*} %destructor const_type {free_const_type($$);} @@ -173,12 +181,29 @@ decl_args(args) ::= decl_args(args_) COMMA decl_arg(arg). { } %type struct_args {decl_args*} %destructor struct_args {free_decl_args($$);} -struct_args(args) ::= decl_arg(arg) EOS. { +struct_args(args) ::= struct_arg(arg). { args = init_decl_args(arg); } -struct_args(args) ::= struct_args(args_) decl_arg(arg) EOS. { +struct_args(args) ::= struct_args(args_) struct_arg(arg). { args = add_decl_arg(args_, arg); } +%type struct_arg {decl_arg*} +%destructor struct_arg {free_decl_arg($$);} +struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. { + arg_->layout = layout_; + arg = arg_; +} + +%type struct_layout {decl_struct_layout*} +%destructor struct_layout {free_decl_struct_layout($$);} +struct_layout(layout) ::= . { + layout = NULL; +} +struct_layout(layout) ::= COLON COLON LPAREN NUMBER(POS) COMMA NUMBER(SIZ) RPAREN. { + layout = init_decl_struct_layout(atol(POS->text), atol(SIZ->text)); + free(POS); + free(SIZ); +} %token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME. %type decl_type {decl_type*} diff --git a/tests/time/asc_gmtime001.phpt b/tests/time/asc_gmtime001.phpt new file mode 100644 index 0000000..3ae7850 --- /dev/null +++ b/tests/time/asc_gmtime001.phpt @@ -0,0 +1,30 @@ +--TEST-- +asctime/gmtime +--SKIPIF-- + +--ENV-- +TZ=UTC +--INI-- +psi.directory = {PWD}/../../psi.d:{PWD} +--FILE-- +===TEST=== + +===DONE=== +--EXPECT-- +===TEST=== +string(25) "Sun Jan 0 00:00:00 1900 +" +string(25) "Sun Jan 0 00:00:00 1900 +" +string(25) "Fri Feb 13 23:31:30 2009 +" +string(25) "Fri Feb 13 23:31:30 2009 +" +===DONE=== diff --git a/tests/time/gettimeofday001.phpt b/tests/time/gettimeofday001.phpt new file mode 100644 index 0000000..746dcd9 --- /dev/null +++ b/tests/time/gettimeofday001.phpt @@ -0,0 +1,58 @@ +--TEST-- +gettimeofday +--INI-- +psi.directory = {PWD}/../../psi.d:{PWD} +--SKIPIF-- + +--FILE-- +===TEST=== + +===DONE=== +--EXPECTF-- +===TEST=== +array(4) { + ["sec"]=> + int(1%d) + ["usec"]=> + int(%d) + ["minuteswest"]=> + int(%d) + ["dsttime"]=> + int(%d) +} +int(0) +int(0) +array(2) { + ["tv_sec"]=> + int(1%d) + ["tv_usec"]=> + int(%d) +} +int(0) +array(2) { + ["tv_sec"]=> + int(1%d) + ["tv_usec"]=> + int(%d) +} +array(2) { + ["tz_minuteswest"]=> + int(%d) + ["tz_dsttime"]=> + int(%d) +} +bool(true) +===DONE=== + \ No newline at end of file diff --git a/tests/time/nanosleep001.phpt b/tests/time/nanosleep001.phpt new file mode 100644 index 0000000..f9e0451 --- /dev/null +++ b/tests/time/nanosleep001.phpt @@ -0,0 +1,44 @@ +--TEST-- +nanosleep +--SKIPIF-- + +--ENV-- +TZ=UTC +--INI-- +psi.directory = {PWD}/../../psi.d:{PWD} +--FILE-- +===TEST=== + 10000000], $rm), $rm); +var_dump(psi\gettimeofday($tv2), $tv2); +var_dump($tv2["tv_usec"]-$tv1["tv_usec"]); +?> +===DONE=== +--EXPECTF-- +===TEST=== +int(0) +array(2) { + ["tv_sec"]=> + int(1%d) + ["tv_usec"]=> + int(%d) +} +int(0) +array(2) { + ["tv_sec"]=> + int(0) + ["tv_nsec"]=> + int(0) +} +int(0) +array(2) { + ["tv_sec"]=> + int(%d) + ["tv_usec"]=> + int(%d) +} +int(%r\d\d\d\d\d%r) +===DONE=== diff --git a/tests/time/time001.phpt b/tests/time/time001.phpt deleted file mode 100644 index 746dcd9..0000000 --- a/tests/time/time001.phpt +++ /dev/null @@ -1,58 +0,0 @@ ---TEST-- -gettimeofday ---INI-- -psi.directory = {PWD}/../../psi.d:{PWD} ---SKIPIF-- - ---FILE-- -===TEST=== - -===DONE=== ---EXPECTF-- -===TEST=== -array(4) { - ["sec"]=> - int(1%d) - ["usec"]=> - int(%d) - ["minuteswest"]=> - int(%d) - ["dsttime"]=> - int(%d) -} -int(0) -int(0) -array(2) { - ["tv_sec"]=> - int(1%d) - ["tv_usec"]=> - int(%d) -} -int(0) -array(2) { - ["tv_sec"]=> - int(1%d) - ["tv_usec"]=> - int(%d) -} -array(2) { - ["tz_minuteswest"]=> - int(%d) - ["tz_dsttime"]=> - int(%d) -} -bool(true) -===DONE=== - \ No newline at end of file diff --git a/tests/time/time002.phpt b/tests/time/time002.phpt deleted file mode 100644 index 3ae7850..0000000 --- a/tests/time/time002.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -asctime/gmtime ---SKIPIF-- - ---ENV-- -TZ=UTC ---INI-- -psi.directory = {PWD}/../../psi.d:{PWD} ---FILE-- -===TEST=== - -===DONE=== ---EXPECT-- -===TEST=== -string(25) "Sun Jan 0 00:00:00 1900 -" -string(25) "Sun Jan 0 00:00:00 1900 -" -string(25) "Fri Feb 13 23:31:30 2009 -" -string(25) "Fri Feb 13 23:31:30 2009 -" -===DONE=== diff --git a/tests/time/time003.phpt b/tests/time/time003.phpt deleted file mode 100644 index f9e0451..0000000 --- a/tests/time/time003.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -nanosleep ---SKIPIF-- - ---ENV-- -TZ=UTC ---INI-- -psi.directory = {PWD}/../../psi.d:{PWD} ---FILE-- -===TEST=== - 10000000], $rm), $rm); -var_dump(psi\gettimeofday($tv2), $tv2); -var_dump($tv2["tv_usec"]-$tv1["tv_usec"]); -?> -===DONE=== ---EXPECTF-- -===TEST=== -int(0) -array(2) { - ["tv_sec"]=> - int(1%d) - ["tv_usec"]=> - int(%d) -} -int(0) -array(2) { - ["tv_sec"]=> - int(0) - ["tv_nsec"]=> - int(0) -} -int(0) -array(2) { - ["tv_sec"]=> - int(%d) - ["tv_usec"]=> - int(%d) -} -int(%r\d\d\d\d\d%r) -===DONE=== diff --git a/tests/time/time004.phpt b/tests/time/time004.phpt deleted file mode 100644 index 816b0b5..0000000 --- a/tests/time/time004.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -times ---INI-- -psi.directory={PWD}/../../psi.d:{PWD} ---SKIPIF-- - ---FILE-- -===TEST=== - -===DONE=== ---EXPECTF-- -===TEST=== -int(%d) -array(4) { - ["tms_utime"]=> - int(%d) - ["tms_stime"]=> - int(%d) - ["tms_cutime"]=> - int(%d) - ["tms_cstime"]=> - int(%d) -} -===DONE=== diff --git a/tests/time/times001.phpt b/tests/time/times001.phpt new file mode 100644 index 0000000..816b0b5 --- /dev/null +++ b/tests/time/times001.phpt @@ -0,0 +1,28 @@ +--TEST-- +times +--INI-- +psi.directory={PWD}/../../psi.d:{PWD} +--SKIPIF-- + +--FILE-- +===TEST=== + +===DONE=== +--EXPECTF-- +===TEST=== +int(%d) +array(4) { + ["tms_utime"]=> + int(%d) + ["tms_stime"]=> + int(%d) + ["tms_cutime"]=> + int(%d) + ["tms_cstime"]=> + int(%d) +} +===DONE===