From cfebc76ed7426836f21296cca9a14b422bfa04cf Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 12 Jan 2016 13:15:48 +0100 Subject: [PATCH] flush --- m4/sys_socket.m4 | 1 + psi.d/glob.psi | 2 +- psi.d/netdb.psi | 32 ++++++++++++++++-- psi.d/stdio.psi | 2 +- psi.d/time.psi | 2 +- psi.d/uname.psi | 2 +- src/context.c | 52 ++++++++++++++++++----------- src/module.c | 70 +++++++++++++++++++++++++++------------ src/parser.h | 39 ++++++++++++++++------ tests/iconv/iconv001.phpt | 6 ++-- 10 files changed, 145 insertions(+), 63 deletions(-) diff --git a/m4/sys_socket.m4 b/m4/sys_socket.m4 index 331bd16..3d403cd 100644 --- a/m4/sys_socket.m4 +++ b/m4/sys_socket.m4 @@ -31,6 +31,7 @@ AC_DEFUN(PSI_CHECK_SYS_SOCKET, [ ) PSI_CONST(AF_INET, int) + PSI_CONST(AF_INET6, int) PSI_CONST(AF_UNIX, int) PSI_CONST(AF_UNSPEC, int) PSI_CONST(MSG_CTRUNC, int) diff --git a/psi.d/glob.psi b/psi.d/glob.psi index 02d1c3d..ce6f5a7 100644 --- a/psi.d/glob.psi +++ b/psi.d/glob.psi @@ -9,7 +9,7 @@ function psi\glob(string $pattern, int $flags, array &$glob = NULL) : int { to_int(gl_pathc), to_int(gl_offs), to_int(gl_flags), - to_array(**gl_pathv, gl_pathc + gl_offs, to_string(*gl_pathv)) + to_array(gl_pathv, gl_pathc + gl_offs, to_string(gl_pathv)) ); free globfree(buf); } diff --git a/psi.d/netdb.psi b/psi.d/netdb.psi index 0820c20..dd81ed8 100644 --- a/psi.d/netdb.psi +++ b/psi.d/netdb.psi @@ -11,18 +11,46 @@ function psi\endservent() : void { return void(endservent); } +function psi\sethostent(bool $stayopen) : void { + let stayopen = intval($stayopen); + return void(sethostent); +} +function psi\setnetset(bool $stayopen) : void { + let stayopen = intval($stayopen); + return void(setnetent); +} +function psi\setprotoent(bool $stayopen) : void { + let stayopen = intval($stayopen); + return void(setprotoent); +} +function psi\setservent(bool $stayopen) : void { + let stayopen = intval($stayopen); + return void(setservent); +} + +function psi\gethostent() : array { + return to_array(gethostent, + to_string(h_name), + to_array(h_aliases, to_string(h_aliases)), + to_int(h_addrtype), + to_int(h_length), + to_array(h_addr_list, to_string(h_addr_list, h_length)) + ); +} + function psi\gai_strerror(int $errcode) : string { let errcode = intval($errcode); return to_string(gai_strerror); } +// extern int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); function psi\getaddrinfo(string $node, string $service, array $hints, object &$res = NULL) : int { let node = strval($node); let service = strval($service); let hints = arrval($hints); let res = &NULL; return to_int(getaddrinfo); - set $res = to_array(*res, + set $res = to_array(**res, to_int(ai_flags), to_int(ai_family), to_int(ai_socktype), @@ -30,7 +58,7 @@ function psi\getaddrinfo(string $node, string $service, array $hints, object &$r to_int(ai_addrlen), to_string(ai_addr, ai_addrlen), to_string(ai_canonname), - to_array(ai_next, ...) + to_array(*ai_next, ...) ); free freeaddrinfo(res); } \ No newline at end of file diff --git a/psi.d/stdio.psi b/psi.d/stdio.psi index 43987de..6909354 100644 --- a/psi.d/stdio.psi +++ b/psi.d/stdio.psi @@ -2,7 +2,7 @@ function psi\fopen(string $path, string $mode) : object { let path = pathval($path); let mode = strval($mode); - return to_object(*fopen); + return to_object(fopen); } // extern int fclose(FILE *stream); diff --git a/psi.d/time.psi b/psi.d/time.psi index ae16b0a..ff81e93 100644 --- a/psi.d/time.psi +++ b/psi.d/time.psi @@ -77,7 +77,7 @@ function psi\nanosleep(array $rq = NULL, array &$rm = NULL) : int { function psi\times(array &$tms = NULL) : int { let buf = calloc(1, psi\SIZEOF_STRUCT_TMS); return to_int(times); - set $tms = to_array(*buf, + set $tms = to_array(buf, to_int(tms_utime), to_int(tms_stime), to_int(tms_cutime), diff --git a/psi.d/uname.psi b/psi.d/uname.psi index 6c6a6b0..b7aed96 100644 --- a/psi.d/uname.psi +++ b/psi.d/uname.psi @@ -8,4 +8,4 @@ function psi\uname(array &$u = NULL) : int { to_string(version), to_string(machine), to_string(domainname)); -} \ No newline at end of file +} diff --git a/src/context.c b/src/context.c index ee79c8f..c3f1cb1 100644 --- a/src/context.c +++ b/src/context.c @@ -151,6 +151,12 @@ static struct psi_predef_const { PSI_MACROS +struct utsname *uname2() { + struct utsname *u = calloc(1, sizeof(*u)); + uname(u); + return u; +} + int psi_glob(const char *pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob) { @@ -169,6 +175,7 @@ static struct psi_func_redir { void (*func)(void); } psi_func_redirs[] = { {"glob", (void (*)(void)) psi_glob}, + {"uname2", (void (*)(void)) uname2}, PSI_REDIRS {0} }; @@ -527,6 +534,8 @@ static inline int validate_set_value_handler(set_value *set) { case PSI_T_ELLIPSIS: if (set->outer.set && set->outer.set->func->type == PSI_T_TO_ARRAY) { set->func->handler = psi_to_recursive; + set->inner = set->outer.set->inner; + set->count = set->outer.set->count; break; } /* no break */ @@ -589,13 +598,15 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg if (ref_type->type == PSI_T_STRUCT) { /* to_array(struct, to_...) */ - 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_ex(data, set->inner[i], sub_ref, ref_type->strct->args)) { - return 0; + if (!set->outer.set || set->outer.set->inner != set->inner) { + 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_ex(data, set->inner[i], sub_ref, ref_type->strct->args)) { + return 0; + } } } } @@ -886,25 +897,26 @@ static inline int validate_impl_free_stmts(PSI_Data *data, impl *impl) { free_call->func, impl->func->name); return 0; } - if (!impl->decl->args) { - data->error(free_call->token, PSI_WARNING, - "Declaration '%s' of implementation '%s'" - " does not have any arguments to free", - impl->decl->func->var->name, impl->func->name); - } + + /* now check for known vars */ for (l = 0; l < free_call->vars->count; ++l) { int check = 0; decl_var *free_var = free_call->vars->vars[l]; - for (k = 0; k < impl->decl->args->count; ++k) { - decl_arg *free_arg = impl->decl->args->args[k]; + if (!strcmp(free_var->name, impl->decl->func->var->name)) { + check = 1; + free_var->arg = impl->decl->func; + } else if (impl->decl->args) { + for (k = 0; k < impl->decl->args->count; ++k) { + decl_arg *free_arg = impl->decl->args->args[k]; - if (!strcmp(free_var->name, free_arg->var->name)) { - check = 1; - free_var->arg = free_arg; - break; + if (!strcmp(free_var->name, free_arg->var->name)) { + check = 1; + free_var->arg = free_arg; + break; + } } } @@ -1318,7 +1330,7 @@ static inline void dump_num_exp(int fd, num_exp *exp) { } static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) { - size_t i, j; + size_t i; if (level > 1) { /* only if not directly after `set ...` */ diff --git a/src/module.c b/src/module.c index 607015d..152c949 100644 --- a/src/module.c +++ b/src/module.c @@ -293,6 +293,7 @@ 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) { + char *str; decl_var *var = set->vars->vars[0]; token_t t = real_decl_type(var->arg->type)->type; @@ -304,26 +305,27 @@ void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val) RETVAL_DOUBLE(deref_impl_val(ret_val, var)->dval); break; default: - case PSI_T_VOID: - case PSI_T_INT8: - case PSI_T_UINT8: if (!var->arg->var->pointer_level) { RETVAL_STRINGL(&ret_val->cval, 1); } else { ret_val = deref_impl_val(ret_val, var); - if (ret_val && ret_val->ptr) { + if (var->arg->var->array_size) { + str = (char *) ret_val; + } else { + str = ret_val->ptr; + } + if (str) { if (set->num) { - RETVAL_STRINGL(ret_val->ptr, psi_long_num_exp(set->num, set->outer.val)); + zend_long n = psi_long_num_exp(set->num, set->outer.val); + RETVAL_STRINGL(str, n); } else { - RETVAL_STRING(ret_val->ptr); + RETVAL_STRING(str); } } else { RETVAL_EMPTY_STRING(); } } return; - psi_to_int(return_value, set, ret_val); - break; } convert_to_string(return_value); } @@ -332,7 +334,7 @@ void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val) static impl_val *iterate(impl_val *val, size_t size, unsigned i, impl_val *tmp) { memset(tmp, 0, sizeof(*tmp)); - memcpy(tmp, ((void*) val->ptr) + size * i, size); + memcpy(tmp, ((void*) val) + size * i, size); return tmp; } @@ -388,7 +390,7 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr) void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val) { - set->outer.set->func->handler(return_value, set->outer.set, r_val->ptr); + set->outer.set->func->handler(return_value, set, r_val); } void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) @@ -398,7 +400,7 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) token_t t = real_decl_type(var->arg->type)->type; impl_val tmp, *ret_val = deref_impl_val(r_val, var); - if ((intptr_t) ret_val->ptr <= (intptr_t) 0) { + if ((intptr_t) ret_val <= (intptr_t) 0) { RETURN_NULL(); } @@ -413,13 +415,13 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) set_value *sub_set = set->inner[i]; decl_var *sub_var = sub_set->vars->vars[0]; - sub_set->outer.val = r_val; + sub_set->outer.val = ret_val; if (sub_var->arg) { impl_val *tmp = NULL, *val; zval ztmp; - val = deref_impl_val(struct_member_ref(sub_var->arg, ret_val, &tmp), sub_var); + val = struct_member_ref(sub_var->arg, ret_val, &tmp); sub_set->func->handler(&ztmp, sub_set, val); add_assoc_zval(return_value, sub_var->name, &ztmp); @@ -455,20 +457,32 @@ void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) } return; } else if (set->num) { - /* to_array(arr_var, num_expr, to_int(*arr_var)) - */ + /* to_array(arr_var, num_expr, to_int(*arr_var)) */ zval ele; + char *ptr; zend_long i, n = psi_long_num_exp(set->num, set->outer.val); + size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t); + set_value *sub_set = set->inner[0]; + sub_set->outer.val = set->outer.val; for (i = 0; i < n; ++i) { - size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t); - impl_val *ptr = iterate(ret_val, size, i, &tmp); - - set->inner[0]->func->handler(&ele, set->inner[0], ptr); + ptr = (char *) ret_val->ptr + i * size; + sub_set->func->handler(&ele, sub_set, (void *) ptr); add_next_index_zval(return_value, &ele); } } else { - ZEND_ASSERT(0); + /* to_array(arr_var, to_int(*arr_var)) */ + zval ele; + char *ptr = ret_val->ptr; + size_t size = psi_t_size(var->arg->var->pointer_level ? PSI_T_POINTER : t); + set_value *sub_set = set->inner[0]; + + sub_set->outer.val = set->outer.val; + while (*(void **) ptr) { + sub_set->func->handler(&ele, sub_set, (void *) ptr); + add_next_index_zval(return_value, &ele); + ptr += size; + } } } @@ -588,6 +602,9 @@ static inline void *psi_do_calloc(let_calloc *alloc) zend_long n = psi_long_num_exp(alloc->nmemb, NULL), s = psi_long_num_exp(alloc->size, NULL); void *mem = safe_emalloc(n, s, sizeof(void *)); memset(mem, 0, n * s + sizeof(void *)); +#if 0 + fprintf(stderr, "calloc: %p\n", mem); +#endif return mem; } @@ -681,7 +698,12 @@ static inline void *psi_do_let(let_stmt *let) switch (let->val ? let->val->kind : PSI_LET_NULL) { case PSI_LET_TMP: - arg_val->ptr = deref_impl_val(let->val->data.var->arg->val.ptr, let->var); + memcpy(arg_val, deref_impl_val(let->val->data.var->arg->let->ptr, let->val->data.var), sizeof(*arg_val)); +#if 0 + fprintf(stderr, "LET TMP: %p -> %p\n", + let->val->data.var->arg->let->ptr, + arg_val->ptr); +#endif break; case PSI_LET_NULL: if (darg->var->array_size) { @@ -715,8 +737,10 @@ static inline void *psi_do_let(let_stmt *let) static inline void psi_do_set(zval *return_value, set_value *set) { + decl_arg *set_arg = set->vars->vars[0]->arg; + zval_dtor(return_value); - set->func->handler(return_value, set, set->vars->vars[0]->arg->ptr); + set->func->handler(return_value, set, set_arg->let ? set_arg->let->ptr : set_arg->ptr); } static inline void psi_do_return(zval *return_value, return_stmt *ret) @@ -830,6 +854,8 @@ static inline int psi_calc_num_exp_value(num_exp *exp, impl_val *strct, impl_val case PSI_T_NAME: if (strct) { ref = struct_member_ref(exp->u.dvar->arg, strct, &tmp); + } else if (exp->u.dvar->arg->let) { + ref = exp->u.dvar->arg->let->ptr; } else { ref = exp->u.dvar->arg->ptr; } diff --git a/src/parser.h b/src/parser.h index 2ea0ec8..5129097 100644 --- a/src/parser.h +++ b/src/parser.h @@ -833,7 +833,7 @@ static inline void free_set_value(set_value *val) { if (val->vars) { free_decl_vars(val->vars); } - if (val->inner) { + if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) { size_t i; for (i = 0; i < val->count; ++i) { free_set_value(val->inner[i]); @@ -1145,7 +1145,16 @@ static inline void add_decl_lib(decl_libs *libs, void *dlopened) { static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) { unsigned i; - if (var->arg->var != var) for (i = 1; i < var->pointer_level; ++i) { + ZEND_ASSERT(var->arg->var != var); +#if 0 + fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n", + var->name, var->pointer_level, var->arg->var->pointer_level, + var->array_size, var->arg->var->array_size, ret_val); +#endif + for (i = 0; i < var->pointer_level; ++i) { +#if 0 + fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr); +#endif ret_val = *(void **) ret_val; } return ret_val; @@ -1155,11 +1164,21 @@ static inline impl_val *enref_impl_val(void *ptr, decl_var *var) { impl_val *val, *val_ptr; unsigned i; + ZEND_ASSERT(var->arg->var == var); +#if 0 + fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n", + var->name, var->pointer_level, var->arg->var->pointer_level, + var->array_size, var->arg->var->array_size); +#endif if (!var->pointer_level && real_decl_type(var->arg->type)->type != PSI_T_STRUCT) { return ptr; } + val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *)); - for (i = 1; i < var->pointer_level; ++i) { + for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) { +#if 0 + fprintf(stderr, "++\n"); +#endif val_ptr->ptr = (void **) val_ptr + 1; val_ptr = val_ptr->ptr; } @@ -1168,16 +1187,14 @@ static inline impl_val *enref_impl_val(void *ptr, decl_var *var) { } static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) { - void *ptr = (char *) struct_ptr->ptr + set_arg->layout->pos; - impl_val *val = enref_impl_val(ptr, set_arg->var); - - if (val != ptr) { - *to_free = val; - } - - return val; + void *ptr = (char *) struct_ptr + set_arg->layout->pos; +#if 0 + fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr); +#endif + return ptr; } + #define PSI_ERROR 16 #define PSI_WARNING 32 typedef void (*psi_error_cb)(PSI_Token *token, int type, const char *msg, ...); diff --git a/tests/iconv/iconv001.phpt b/tests/iconv/iconv001.phpt index 6227c2a..779ee60 100644 --- a/tests/iconv/iconv001.phpt +++ b/tests/iconv/iconv001.phpt @@ -14,15 +14,13 @@ psi.directory={PWD}/../../psi.d:{PWD} $cd = psi\iconv_open("latin1", "utf8"); $in = "ß"; $rc = psi\iconv($cd, $in, $tr); -var_dump($tr === "\xdf"); -var_dump($in === ""); +if ($tr !== "\xdf") var_dump($tr); +if ($in !== "") var_dump($in); var_dump(psi\iconv_close($cd)); ?> ===DONE=== --EXPECT-- ===TEST=== -bool(true) -bool(true) int(0) ===DONE=== -- 2.30.2