From 98d971f89db2431ef24dac508cf9797ef93646c6 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 15 Feb 2016 14:44:06 +0100 Subject: [PATCH] fix varargs support --- src/engine.c | 15 +++++++++------ src/marshal.c | 5 +++-- src/parser.h | 4 +++- tests/stdio/printf001.phpt | 20 ++++++++++++++++++++ 4 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 tests/stdio/printf001.phpt diff --git a/src/engine.c b/src/engine.c index 447e0d7..aa4feeb 100644 --- a/src/engine.c +++ b/src/engine.c @@ -449,7 +449,8 @@ static inline impl_vararg *psi_do_varargs(impl *impl) { for (i = 0, j = 0; i < vacount; ++i) { impl_arg *vaarg = va->args->args[i]; void *to_free = NULL; - token_t let_fn, vatype = va->name->type->type; + token_t vatype = va->name->type->type; + let_func_handler let_fn; if (vatype == PSI_T_MIXED) { switch (Z_TYPE_P(vaarg->_zv)) { @@ -463,17 +464,19 @@ static inline impl_vararg *psi_do_varargs(impl *impl) { switch (vatype) { - case PSI_T_BOOL: let_fn = PSI_T_BOOLVAL; break; - case PSI_T_INT: let_fn = PSI_T_INTVAL; break; + case PSI_T_BOOL: let_fn = psi_let_boolval; break; + case PSI_T_INT: let_fn = psi_let_intval; break; case PSI_T_FLOAT: - case PSI_T_DOUBLE: let_fn = PSI_T_FLOATVAL;break; - case PSI_T_STRING: let_fn = PSI_T_STRVAL; break; + case PSI_T_DOUBLE: let_fn = psi_let_floatval; break; + case PSI_T_STRING: let_fn = psi_let_strval; break; EMPTY_SWITCH_DEFAULT_CASE(); } va->types[i] = vatype; + /* FIXME: varargs with struct-by-value :) */ - if (!psi_let_val(let_fn, vaarg, &va->values[i], NULL, &to_free)) { + //if (!psi_let_val(let_fn, vaarg, &va->values[i], NULL, &to_free)) { + if (!let_fn(&va->values[i], NULL, vaarg, &to_free)) { return NULL; } diff --git a/src/marshal.c b/src/marshal.c index f204753..2ec3329 100644 --- a/src/marshal.c +++ b/src/marshal.c @@ -106,9 +106,10 @@ static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_lo case PSI_T_UINT16: tmp->u16 = intval; break; case PSI_T_INT32: tmp->i32 = intval; break; case PSI_T_UINT32: tmp->u32 = intval; break; - case PSI_T_INT: tmp->ival = intval; break; case PSI_T_INT64: tmp->i64 = intval; break; case PSI_T_UINT64: tmp->u64 = intval; break; + case PSI_T_INT: tmp->ival = intval; break; + case PSI_T_LONG: tmp->lval = intval; break; case PSI_T_FLOAT: tmp->fval = intval; break; case PSI_T_DOUBLE: tmp->dval = intval; break; #ifdef HAVE_LONG_DOUBLE @@ -123,7 +124,7 @@ static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_lo impl_val *psi_let_intval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free) { zend_long intval; - token_t real_type = type ? real_decl_type(type)->type : PSI_T_INT; + token_t real_type = type ? real_decl_type(type)->type : PSI_T_LONG; if (iarg->type->type == PSI_T_INT) { intval = iarg->val.zend.lval; diff --git a/src/parser.h b/src/parser.h index 34e849e..c9e9f75 100644 --- a/src/parser.h +++ b/src/parser.h @@ -919,11 +919,13 @@ static inline void free_let_callback(let_callback *cb) { free(cb); } +typedef impl_val *(*let_func_handler)(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free); + typedef struct let_func { token_t type; char *name; impl_var *var; - impl_val *(*handler)(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free); + let_func_handler handler; } let_func; static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) { diff --git a/tests/stdio/printf001.phpt b/tests/stdio/printf001.phpt new file mode 100644 index 0000000..cd1527d --- /dev/null +++ b/tests/stdio/printf001.phpt @@ -0,0 +1,20 @@ +--TEST-- +printf +--SKIPIF-- + +--ENV-- +LC_ALL=C +--INI-- +psi.directory={PWD}/../../psi.d:{PWD} +--FILE-- +===TEST=== + +===DONE=== +--EXPECT-- +===TEST=== +hello 123456789 0.987654 +===DONE=== -- 2.30.2