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"
case IS_OBJECT:
count = 1;
if (Z_OBJ_HT_P(zvalue)->count_elements) {
- if (SUCCESS == Z_OBJ_HT_P(zvalue)->count_elements(zvalue, &count)) {
+ if (SUCCESS == Z_OBJ_HT_P(zvalue)->count_elements(Z_OBJ_P(zvalue), &count)) {
break;
}
}
if (instanceof_function(Z_OBJCE_P(zvalue), spl_ce_Countable)) {
- zend_call_method_with_0_params(zvalue, NULL, NULL, "count", &retval);
+ zend_call_method_with_0_params(Z_OBJ_P(zvalue), NULL, NULL, "count", &retval);
if (Z_TYPE(retval) != IS_UNDEF) {
count = zval_get_long(&retval);
zval_ptr_dtor(&retval);
zend_internal_arg_info *aip;
zend_internal_function_info *fi;
struct psi_impl_arg *iarg;
+ zend_type rtyp = ZEND_TYPE_INIT_CODE(psi_internal_type(impl->func->return_type), 1, _ZEND_ARG_INFO_FLAGS(impl->func->return_reference, impl->func->vararg));
- 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
- fi->type = ZEND_TYPE_ENCODE(psi_internal_type(impl->func->return_type), 1);
-#else
- fi->allow_null = 1;
- fi->type_hint = psi_internal_type(impl->func->return_type);
-#endif
fi->required_num_args = psi_impl_num_min_args(impl);
- fi->return_reference = impl->func->return_reference;
+ fi->type = rtyp;
if (impl->func->vararg) {
struct psi_impl_arg *vararg = impl->func->vararg;
zend_internal_arg_info *ai = &aip[argc];
+ zend_type atyp = ZEND_TYPE_INIT_CODE(psi_internal_type(vararg->type), 1, _ZEND_ARG_INFO_FLAGS(vararg->var->reference, 1));
- ai->name = vararg->var->name;
-#ifdef ZEND_TYPE_ENCODE
- ai->type = ZEND_TYPE_ENCODE(psi_internal_type(vararg->type), 1);
-#else
- ai->allow_null = 1;
- ai->type_hint = psi_internal_type(vararg->type);
-#endif
- if (vararg->var->reference) {
- ai->pass_by_reference = 1;
- }
- ai->is_variadic = 1;
+ ai->name = &vararg->var->name->val[1];
+ ai->type = atyp;
}
while (psi_plist_get(impl->func->args, i++, &iarg)) {
zend_internal_arg_info *ai = &aip[i];
+ zend_type atyp = ZEND_TYPE_INIT_CODE(psi_internal_type(iarg->type), 1, _ZEND_ARG_INFO_FLAGS(iarg->var->reference, 0));
- ai->name = iarg->var->name;
-#ifdef ZEND_TYPE_ENCODE
- ai->type = ZEND_TYPE_ENCODE(psi_internal_type(iarg->type), 1);
-#else
- ai->allow_null = 1;
- ai->type_hint = psi_internal_type(iarg->type);
-#endif
- if (iarg->var->reference) {
- ai->pass_by_reference = 1;
- }
+ ai->name = &iarg->var->name->val[1];
+ ai->type = atyp;
}
return aip;
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
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_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_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);
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_ENUM:
- 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_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)->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
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, NULL));
+ RETVAL_STRINGL(str, psi_num_exp_get_long(sub_exp->data.num, frame, NULL));
} else {
RETVAL_EMPTY_STRING();
}
{
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;
}
}
psi_plist_get(set->inner, 0, &sub_exp);
- count = psi_long_num_exp(sub_exp->data.num, frame, NULL);
+ 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);
}
}