OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
-#include "php_psi_stdinc.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
#include "data.h"
#include "calc.h"
zend_internal_function_info *fi;
struct psi_impl_arg *iarg;
- aip = calloc(argc + 1 + !!impl->func->vararg, sizeof(*aip));
+ aip = pecalloc(argc + 1 + !!impl->func->vararg, sizeof(*aip), 1);
fi = (zend_internal_function_info *) &aip[0];
#ifdef ZEND_TYPE_ENCODE
struct psi_impl_arg *vararg = impl->func->vararg;
zend_internal_arg_info *ai = &aip[argc];
- ai->name = vararg->var->name;
+ ai->name = vararg->var->name->val;
#ifdef ZEND_TYPE_ENCODE
ai->type = ZEND_TYPE_ENCODE(psi_internal_type(vararg->type), 1);
#else
while (psi_plist_get(impl->func->args, i++, &iarg)) {
zend_internal_arg_info *ai = &aip[i];
- ai->name = iarg->var->name;
+ ai->name = iarg->var->name->val;
#ifdef ZEND_TYPE_ENCODE
ai->type = ZEND_TYPE_ENCODE(psi_internal_type(iarg->type), 1);
#else
/*
* ?
*/
-impl_val *psi_let_void(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_void(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
return tmp;
}
/*
* let dvar = zval($ivar)
*/
-impl_val *psi_let_zval(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_zval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
*to_free = tmp->ptr = emalloc(sizeof(zval));
ZVAL_COPY_VALUE(tmp->ptr, zvalue);
case PSI_T_UINT32: tmp->u32 = boolval; break;
case PSI_T_INT64: tmp->i64 = boolval; break;
case PSI_T_UINT64: tmp->u64 = boolval; break;
+#ifdef HAVE_INT128
+ case PSI_T_INT128: tmp->i128 = boolval; break;
+ case PSI_T_UINT128: tmp->u128 = boolval; break;
+#endif
case PSI_T_FLOAT: tmp->fval = boolval; break;
case PSI_T_DOUBLE: tmp->dval = boolval; break;
#ifdef HAVE_LONG_DOUBLE
/*
* let dvar = boolval($ivar)
*/
-impl_val *psi_let_boolval(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_boolval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
zend_bool boolval;
- token_t real_type = spec ? psi_decl_type_get_real(spec)->type : PSI_T_UINT8;
+ token_t real_type = spec ? psi_decl_type_get_real(spec->type)->type : PSI_T_UINT8;
if (ival && impl_type == PSI_T_BOOL) {
boolval = ival->zend.bval;
return psi_val_boolval(tmp, real_type, boolval);
}
-# define RETVAL_LONG_U64(V) \
- if (V > ZEND_LONG_MAX) { \
- char d[24] = {0}; \
- RETVAL_STRING(zend_print_ulong_to_buf(&d[22], V)); \
- } else { \
- RETVAL_LONG(V); \
- }
-
/*
* set $ivar = to_int(*dvar)
*/
case PSI_T_UINT8: RETVAL_LONG(v->u8); break;
case PSI_T_INT16: RETVAL_LONG(v->i16); break;
case PSI_T_UINT16: RETVAL_LONG(v->u16); break;
+ case PSI_T_ENUM:
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_U64(v->u64); break;
- case PSI_T_FLOAT: RETVAL_DOUBLE((double) v->fval); break;
- case PSI_T_DOUBLE: RETVAL_DOUBLE(v->dval); break;
+ case PSI_T_UINT64: RETVAL_LONG_DOUBLE_STR(v->u64,); break;
+#ifdef HAVE_INT128
+ 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);
+ convert_to_long(return_value);
+ break;
+ case PSI_T_DOUBLE:
+ RETVAL_DOUBLE(v->dval);
+ convert_to_long(return_value);
+ break;
#ifdef HAVE_LONG_DOUBLE
- case PSI_T_LONG_DOUBLE: RETVAL_DOUBLE((double) v->ldval); break;
+ case PSI_T_LONG_DOUBLE:
+ RETVAL_DOUBLE((double) v->ldval);
+ convert_to_long(return_value);
+ break;
#endif
EMPTY_SWITCH_DEFAULT_CASE();
}
-
- convert_to_long(return_value);
}
static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_long intval) {
case PSI_T_UINT8: tmp->u8 = intval; break;
case PSI_T_INT16: tmp->i16 = intval; break;
case PSI_T_UINT16: tmp->u16 = intval; break;
+ case PSI_T_ENUM:
case PSI_T_INT32: tmp->i32 = intval; break;
case PSI_T_UINT32: tmp->u32 = 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;
+#if HAVE_INT128
+ case PSI_T_INT128: tmp->i128 = intval; break;
+ case PSI_T_UINT128: tmp->u128 = intval; break;
+#endif
case PSI_T_FLOAT: tmp->fval = intval; break;
case PSI_T_DOUBLE: tmp->dval = intval; break;
#ifdef HAVE_LONG_DOUBLE
return tmp;
}
+#if HAVE_INT128
+static void psi_strto_i128(char *ptr, char *end, token_t real_type, impl_val *val) {
+ unsigned __int128 i = 0;
+ bool oct = false, hex = false, sign = false;
+
+ if (*ptr == '+') {
+ ++ptr;
+ } else if (*ptr == '-') {
+ sign = true;
+ ++ptr;
+ } else if (*ptr == '\\') {
+ switch (*++ptr) {
+ case 'x':
+ hex = true;
+ ++ptr;
+ break;
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':
+ oct = true;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ while (ptr < end) {
+ switch (*ptr) {
+ case '8':case '9':
+ if (oct) {
+ goto fail;
+ }
+ /* no break */
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':
+ if (oct) {
+ i <<= 3;
+ } else if (hex) {
+ i <<= 4;
+ } else {
+ i *= 10;
+ }
+ i += *ptr - '0';
+ break;
+ case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
+ if (!hex) {
+ goto fail;
+ }
+ i <<= 4;
+ i += 10 + (*ptr - 'a');
+ break;
+ case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
+ if (!hex) {
+ goto fail;
+ }
+ i <<= 4;
+ i += 10 + (*ptr - 'A');
+ break;
+ default:
+ fail:
+ zend_error(E_WARNING, "A non well formed numeric value encountered");
+ goto stop;
+ }
+ ++ptr;
+ }
+
+stop:
+ if (real_type == PSI_T_UINT128) {
+ if (sign) {
+ val->u128 = -i;
+ } else {
+ val->u128 = i;
+ }
+ } else {
+ if (sign) {
+ val->i128 = -i;
+ } else {
+ val->i128 = i;
+ }
+ }
+}
+#endif
+
/*
* let dvar = intval($ivar)
*/
-impl_val *psi_let_intval(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_intval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
- zend_long intval;
- token_t real_type = spec ? psi_decl_type_get_real(spec)->type : PSI_T_LONG;
+ int64_t intval;
+ token_t real_type = spec ? psi_decl_type_get_real(spec->type)->type : PSI_T_INT64;
+
if (ival && impl_type == PSI_T_INT) {
intval = ival->zend.lval;
+#if HAVE_INT128
+ } else if ((real_type == PSI_T_UINT128 || real_type == PSI_T_INT128) &&
+ !((Z_TYPE_P(zvalue) == IS_TRUE || Z_TYPE_P(zvalue) == IS_FALSE || Z_TYPE_P(zvalue) == IS_LONG || Z_TYPE_P(zvalue) == IS_DOUBLE || Z_TYPE_P(zvalue) == IS_NULL))) {
+ zend_string *str = zval_get_string(zvalue);
+ psi_strto_i128(str->val, str->val + str->len, real_type, tmp);
+ zend_string_release(str);
+ return tmp;
+#endif
} else {
intval = zval_get_long(zvalue);
}
case PSI_T_UINT32: RETVAL_DOUBLE((double) v->u32); break;
case PSI_T_INT64: RETVAL_DOUBLE((double) v->i64); break;
case PSI_T_UINT64: RETVAL_DOUBLE((double) v->u64); break;
+#if HAVE_INT128
+ case PSI_T_INT128: RETVAL_DOUBLE((double) v->i128); break;
+ case PSI_T_UINT128: RETVAL_DOUBLE((double) v->u128); break;
+#endif
EMPTY_SWITCH_DEFAULT_CASE();
}
}
case PSI_T_UINT32: tmp->u32 = floatval; break;
case PSI_T_INT64: tmp->i64 = floatval; break;
case PSI_T_UINT64: tmp->u64 = floatval; break;
+#if HAVE_INT128
+ case PSI_T_INT128: tmp->i128 = floatval; break;
+ case PSI_T_UINT128: tmp->u128 = floatval; break;
+#endif
case PSI_T_FLOAT: tmp->fval = floatval; break;
case PSI_T_DOUBLE: tmp->dval = floatval; break;
#ifdef HAVE_LONG_DOUBLE
/*
* let dvar = floatval($ivar)
*/
-impl_val *psi_let_floatval(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_floatval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
double floatval;
- token_t real_type = spec ? psi_decl_type_get_real(spec)->type : PSI_T_DOUBLE;
+ token_t real_type = spec ? psi_decl_type_get_real(spec->type)->type : PSI_T_DOUBLE;
if (ival && (impl_type == PSI_T_FLOAT || impl_type == PSI_T_DOUBLE)) {
floatval = ival->dval;
impl_val *ptr = deref_impl_val(ret_val, var);
char *str;
- if (var->arg->var->array_size) {
+ if (var->arg->var->array_size && var->arg->var->pointer_level == 1) {
str = (char *) ptr;
} else {
str = ptr->ptr;
struct psi_set_exp *sub_exp;
psi_plist_get(set->inner, 0, &sub_exp);
- RETVAL_STRINGL(str, psi_long_num_exp(sub_exp->data.num, frame));
+ RETVAL_STRINGL(str, psi_num_exp_get_long(sub_exp->data.num, frame, NULL));
} else {
RETVAL_EMPTY_STRING();
}
/*
* let dvar = strval($ivar)
*/
-impl_val *psi_let_strval(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_strval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
if (ival && impl_type == PSI_T_STRING) {
if (ival->zend.str) {
/*
* let dvar = pathval($ivar)
*/
-impl_val *psi_let_pathval(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_pathval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
tmp = psi_let_strval(tmp, spec, impl_type, ival, zvalue, to_free);
if (SUCCESS != php_check_open_basedir(tmp->ptr)) {
/*
* let dvar = strlen($ivar)
*/
-impl_val *psi_let_strlen(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_strlen(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
if (ival && impl_type == PSI_T_STRING) {
if (ival->zend.str) {
- tmp->lval = ival->zend.str->len;
+ tmp->u64 = ival->zend.str->len;
} else {
- tmp->lval = 0;
+ tmp->u64 = 0;
}
} else {
zend_string *zs = zval_get_string(zvalue);
- tmp->lval = zs->len;
+ tmp->u64 = zs->len;
zend_string_release(zs);
}
+ if (spec) {
+ psi_calc_cast(PSI_T_UINT64, tmp, psi_decl_type_get_real(spec->type)->type, tmp);
+ }
return tmp;
}
+#if 0
static impl_val *iterate(impl_val *val, size_t size, unsigned i, impl_val *tmp)
{
memset(tmp, 0, sizeof(*tmp));
memcpy(tmp, ((char *) val) + size * i, size);
return tmp;
}
+#endif
/*
* set $ivar = to_array(dvar,
}
psi_plist_get(set->inner, 0, &sub_exp);
- count = psi_long_num_exp(sub_exp->data.num, frame);
+ count = psi_num_exp_get_long(sub_exp->data.num, frame, NULL);
psi_plist_get(set->inner, 1, &sub_exp);
- for (ptr = (char *) ret_val; 0 < count--; ptr += size) {
size = psi_decl_var_get_size(psi_set_exp_get_decl_var(sub_exp));
+ for (ptr = (char *) ret_val; 0 < count--; ptr += size) {
zval ele;
ZVAL_NULL(&ele);
ZVAL_NULL(&ele);
psi_set_exp_exec_ex(sub_exp, &ele, sym->ptr, frame);
- add_assoc_zval(return_value, ivar->name + 1, &ele);
+ add_assoc_zval_ex(return_value, ivar->name->val + 1, ivar->name->len - 1, &ele);
}
}
-//impl_val *psi_let_arrval(impl_val *tmp, decl_type *spec, decl_var *spec_var, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
-//{
-// decl_type *real = real_decl_type(spec);
-// HashTable *arr;
-// zval *zv;
-// size_t i, sz;
-// decl_arg tmp_arg = {0};
-//
-// if (impl_type != PSI_T_ARRAY) {
-// SEPARATE_ARG_IF_REF(zvalue);
-// convert_to_array(zvalue);
-// }
-// arr = HASH_OF(zvalue);
-//
-// switch (real->type) {
-// case PSI_T_STRUCT:
-// *to_free = tmp = psi_array_to_struct(real->real.strct, arr);
-// break;
-// case PSI_T_UNION:
-// *to_free = tmp = psi_array_to_union(real->real.unn, arr);
-// break;
-// default:
-// sz = psi_t_size(real->type);
-// tmp = *to_free = ecalloc(zend_hash_num_elements(arr), sz);
-// tmp_arg.type = spec;
-// tmp_arg.var = spec_var;
-// ZEND_HASH_FOREACH_VAL_IND(arr, zv)
-// {
-// void *ptr = ((char *) tmp) + (i++ * sz);
-// psi_from_zval_ex(NULL, (impl_val **) &ptr, &tmp_arg, 0, zv, NULL);
-// }
-// ZEND_HASH_FOREACH_END();
-// }
-//
-// return tmp;
-//}
-
/*
* let dvar = count($ivar)
*/
-impl_val *psi_let_count(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_count(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
- return psi_val_intval(tmp, psi_decl_type_get_real(spec)->type, psi_zval_count(zvalue));
+ return psi_val_intval(tmp, psi_decl_type_get_real(spec->type)->type, psi_zval_count(zvalue));
}
/*
/*
* let dvar = objval($ivar)
*/
-impl_val *psi_let_objval(impl_val *tmp, struct psi_decl_type *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
+impl_val *psi_let_objval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl_type, impl_val *ival, zval *zvalue, void **to_free)
{
psi_object *obj;