From bcd9e150292290ce2951fdca61fad526c478e787 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 2 Nov 2015 08:08:58 +0100 Subject: [PATCH] working asctime --- src/module.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- src/parser.h | 11 +++++++ src/parser.re | 2 ++ src/parser_proc.h | 23 +++++++------- src/parser_proc.y | 4 +++ 5 files changed, 104 insertions(+), 12 deletions(-) diff --git a/src/module.c b/src/module.c index 6674272..ac08a95 100644 --- a/src/module.c +++ b/src/module.c @@ -281,6 +281,58 @@ static impl_val *iterate(impl_val *val, token_t t, unsigned i, impl_val *tmp) return tmp; } +void psi_from_zval(impl_val *mem, decl_arg *spec, zval *zv, void **tmp) +{ + decl_type *type = real_decl_type(spec->type); + + switch (type->type) { + case PSI_T_FLOAT: + mem->fval = (float) zval_get_double(zv); + break; + case PSI_T_DOUBLE: + mem->dval = zval_get_double(zv); + break; + case PSI_T_CHAR: + case PSI_T_SINT8: + case PSI_T_UINT8: + if (spec->var->pointer_level) { + zend_string *zs = zval_get_string(zv); + *tmp = mem->ptr = estrndup(zs->val, zs->len); + zend_string_release(zs); + break; + } + default: + mem->lval = zval_get_long(zv); + break; + } +} + +void *psi_array_to_struct(decl_struct *s, HashTable *arr) +{ + size_t i, j = 0, size = decl_struct_size(s); + char *mem = ecalloc(1, size + s->args->count * sizeof(void *)); + + for (i = 0; i < s->args->count; ++i) { + decl_struct_layout *layout = &s->layout[i]; + decl_arg *darg = s->args->args[i]; + decl_type *type = real_decl_type(darg->type); + zval *entry = zend_hash_str_find_ind(arr, darg->var->name, strlen(darg->var->name)); + + if (entry) { + impl_val val; + void *tmp = NULL; + + memset(&tmp, 0, sizeof(tmp)); + psi_from_zval(&val, darg, entry, &tmp); + memcpy(mem + layout->pos, &val, layout->len); + if (tmp) { + ((void **)(mem + size))[j++] = tmp; + } + } + } + return mem; +} + void psi_to_array(impl_val *ret_val, decl_arg *func, zval *return_value) { zval ele; @@ -288,7 +340,6 @@ void psi_to_array(impl_val *ret_val, decl_arg *func, zval *return_value) impl_val tmp; decl_type *type = real_decl_type(func->type); token_t t = type->type; - printf("%d:%s real=%p,strct=%p\n", t, type->name, type->real, type->strct); array_init(return_value); @@ -296,6 +347,7 @@ void psi_to_array(impl_val *ret_val, decl_arg *func, zval *return_value) decl_struct *s = type->strct; ret_val = deref_impl_val(func->var->pointer_level, ret_val, func); + ZEND_ASSERT(s); for (i = 0; i < s->args->count; ++i) { decl_arg *darg = s->args->args[i]; decl_struct_layout layout = s->layout[i]; @@ -454,6 +506,18 @@ impl_val *psi_do_let(decl_arg *darg) arg_val->ptr = calloc(1, darg->let->val->func->size); darg->let->mem = arg_val->ptr; break; + case PSI_T_ARRVAL: + if (iarg->type->type == PSI_T_ARRAY) { + decl_type *type = real_decl_type(darg->type); + + switch (type->type) { + case PSI_T_STRUCT: + arg_val->ptr = psi_array_to_struct(type->strct, HASH_OF(iarg->_zv)); + darg->let->mem = arg_val->ptr; + break; + } + } + break; EMPTY_SWITCH_DEFAULT_CASE(); } @@ -528,6 +592,16 @@ void psi_do_clean(impl *impl) decl_arg *darg = impl->decl->args->args[i]; if (darg->let && darg->let->mem) { + decl_type *type = real_decl_type(darg->type); + + if (type->type == PSI_T_STRUCT) { + size_t eos = decl_struct_size(type->strct); + void **ptr = (void **) ((char *) darg->let->mem + eos); + + while (*ptr) { + efree(*ptr++); + } + } efree(darg->let->mem); darg->let->mem = NULL; } diff --git a/src/parser.h b/src/parser.h index 62f5e31..f56f278 100644 --- a/src/parser.h +++ b/src/parser.h @@ -14,6 +14,10 @@ typedef int token_t; +/* in php_psi.h */ +size_t psi_t_alignment(token_t); +size_t psi_t_size(token_t); + typedef struct PSI_Token { token_t type; unsigned line; @@ -276,6 +280,12 @@ static inline void free_decl_struct(decl_struct *s) { free(s); } +static inline size_t decl_struct_size(decl_struct *s) { + size_t c = s->args->count - 1; + decl_type *type = real_decl_type(s->args->args[c]->type); + return s->layout[c].pos + psi_t_alignment(type->type); +} + typedef struct decl_structs { size_t count; decl_struct **list; @@ -305,6 +315,7 @@ typedef union impl_val { char cval; short sval; int ival; + float fval; double dval; zend_long lval; zend_string *str; diff --git a/src/parser.re b/src/parser.re index 0bca5b0..13d6484 100644 --- a/src/parser.re +++ b/src/parser.re @@ -214,6 +214,7 @@ token_t PSI_ParserScan(PSI_Parser *P) INTVAL = 'intval'; FLOATVAL = 'floatval'; BOOLVAL = 'boolval'; + ARRVAL = 'arrval'; CALLOC = 'calloc'; TO_ARRAY = 'to_array'; TO_STRING = 'to_string'; @@ -275,6 +276,7 @@ token_t PSI_ParserScan(PSI_Parser *P) INTVAL {RETURN(PSI_T_INTVAL);} FLOATVAL {RETURN(PSI_T_FLOATVAL);} BOOLVAL {RETURN(PSI_T_BOOLVAL);} + ARRVAL {RETURN(PSI_T_ARRVAL);} CALLOC {RETURN(PSI_T_CALLOC);} TO_ARRAY {RETURN(PSI_T_TO_ARRAY);} TO_STRING {RETURN(PSI_T_TO_STRING);} diff --git a/src/parser_proc.h b/src/parser_proc.h index a427b08..3d86e2b 100644 --- a/src/parser_proc.h +++ b/src/parser_proc.h @@ -48,14 +48,15 @@ #define PSI_T_INTVAL 48 #define PSI_T_FLOATVAL 49 #define PSI_T_BOOLVAL 50 -#define PSI_T_SET 51 -#define PSI_T_TO_ARRAY 52 -#define PSI_T_TO_STRING 53 -#define PSI_T_TO_INT 54 -#define PSI_T_TO_FLOAT 55 -#define PSI_T_TO_BOOL 56 -#define PSI_T_RETURN 57 -#define PSI_T_FREE 58 -#define PSI_T_MIXED 59 -#define PSI_T_ARRAY 60 -#define PSI_T_POINTER 61 +#define PSI_T_ARRVAL 51 +#define PSI_T_SET 52 +#define PSI_T_TO_ARRAY 53 +#define PSI_T_TO_STRING 54 +#define PSI_T_TO_INT 55 +#define PSI_T_TO_FLOAT 56 +#define PSI_T_TO_BOOL 57 +#define PSI_T_RETURN 58 +#define PSI_T_FREE 59 +#define PSI_T_MIXED 60 +#define PSI_T_ARRAY 61 +#define PSI_T_POINTER 62 diff --git a/src/parser_proc.y b/src/parser_proc.y index 59477ba..43ae161 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -376,6 +376,10 @@ let_func(func) ::= BOOLVAL(T). { func = init_let_func(T->type, T->text, 0); free(T); } +let_func(func) ::= ARRVAL(T). { + func = init_let_func(T->type, T->text, 0); + free(T); +} %type set_stmt {set_stmt*} set_stmt(set) ::= SET impl_var(var) EQUALS set_value(val) EOS. { -- 2.30.2