diff options
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r-- | Zend/zend_operators.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 1b155f88f7..daed16e358 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -136,6 +136,26 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* { } /* }}} */ +/* {{{ convert_object_to_type: dst will be either ctype or UNDEF */ +#define convert_object_to_type(op, dst, ctype, conv_func) \ + ZVAL_UNDEF(dst); \ + if (Z_OBJ_HT_P(op)->cast_object) { \ + if (Z_OBJ_HT_P(op)->cast_object(op, dst, ctype) == FAILURE) { \ + zend_error(E_RECOVERABLE_ERROR, \ + "Object of class %s could not be converted to %s", ZSTR_VAL(Z_OBJCE_P(op)->name),\ + zend_get_type_by_const(ctype)); \ + } \ + } else if (Z_OBJ_HT_P(op)->get) { \ + zval *newop = Z_OBJ_HT_P(op)->get(op, dst); \ + if (Z_TYPE_P(newop) != IS_OBJECT) { \ + /* for safety - avoid loop */ \ + ZVAL_COPY_VALUE(dst, newop); \ + conv_func(dst); \ + } \ + } + +/* }}} */ + void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{ */ { try_again: @@ -172,7 +192,18 @@ try_again: } break; case IS_OBJECT: - convert_to_long_base(op, 10); + { + zval dst; + + convert_object_to_type(op, &dst, _IS_NUMBER, convert_scalar_to_number); + zval_dtor(op); + + if (Z_TYPE(dst) == IS_LONG || Z_TYPE(dst) == IS_DOUBLE) { + ZVAL_COPY_VALUE(op, &dst); + } else { + ZVAL_LONG(op, 1); + } + } break; } } @@ -215,17 +246,17 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */ break; \ case IS_OBJECT: \ ZVAL_COPY(&(holder), op); \ - convert_to_long_base(&(holder), 10); \ + _convert_scalar_to_number(&(holder), silent); \ if (UNEXPECTED(EG(exception))) { \ if (result != op1) { \ ZVAL_UNDEF(result); \ } \ return FAILURE; \ } \ - if (Z_TYPE(holder) == IS_LONG) { \ + if (Z_TYPE(holder) == IS_LONG || Z_TYPE(holder) == IS_DOUBLE) { \ if (op == result) { \ zval_ptr_dtor(op); \ - ZVAL_LONG(op, Z_LVAL(holder)); \ + ZVAL_COPY(op, &(holder)); \ } else { \ (op) = &(holder); \ } \ @@ -237,26 +268,6 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */ /* }}} */ -/* {{{ convert_object_to_type: dst will be either ctype or UNDEF */ -#define convert_object_to_type(op, dst, ctype, conv_func) \ - ZVAL_UNDEF(dst); \ - if (Z_OBJ_HT_P(op)->cast_object) { \ - if (Z_OBJ_HT_P(op)->cast_object(op, dst, ctype) == FAILURE) { \ - zend_error(E_RECOVERABLE_ERROR, \ - "Object of class %s could not be converted to %s", ZSTR_VAL(Z_OBJCE_P(op)->name),\ - zend_get_type_by_const(ctype)); \ - } \ - } else if (Z_OBJ_HT_P(op)->get) { \ - zval *newop = Z_OBJ_HT_P(op)->get(op, dst); \ - if (Z_TYPE_P(newop) != IS_OBJECT) { \ - /* for safety - avoid loop */ \ - ZVAL_COPY_VALUE(dst, newop); \ - conv_func(dst); \ - } \ - } - -/* }}} */ - #define convert_op1_op2_long(op1, op1_lval, op2, op2_lval, result, op, op_func) \ do { \ if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { \ |