@@ -136,6 +136,26 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {
136136}
137137/* }}} */
138138
139+ /* {{{ convert_object_to_type: dst will be either ctype or UNDEF */
140+ #define convert_object_to_type (op , dst , ctype , conv_func ) \
141+ ZVAL_UNDEF(dst); \
142+ if (Z_OBJ_HT_P(op)->cast_object) { \
143+ if (Z_OBJ_HT_P(op)->cast_object(op, dst, ctype) == FAILURE) { \
144+ zend_error(E_RECOVERABLE_ERROR, \
145+ "Object of class %s could not be converted to %s", ZSTR_VAL(Z_OBJCE_P(op)->name),\
146+ zend_get_type_by_const(ctype)); \
147+ } \
148+ } else if (Z_OBJ_HT_P(op)->get) { \
149+ zval *newop = Z_OBJ_HT_P(op)->get(op, dst); \
150+ if (Z_TYPE_P(newop) != IS_OBJECT) { \
151+ /* for safety - avoid loop */ \
152+ ZVAL_COPY_VALUE (dst , newop ); \
153+ conv_func (dst ); \
154+ } \
155+ }
156+
157+ /* }}} */
158+
139159void ZEND_FASTCALL _convert_scalar_to_number (zval * op , zend_bool silent ) /* {{{ */
140160{
141161try_again :
@@ -172,7 +192,18 @@ void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{
172192 }
173193 break ;
174194 case IS_OBJECT :
175- convert_to_long_base (op , 10 );
195+ {
196+ zval dst ;
197+
198+ convert_object_to_type (op , & dst , _IS_NUMBER , convert_scalar_to_number );
199+ zval_dtor (op );
200+
201+ if (Z_TYPE (dst ) == IS_LONG || Z_TYPE (dst ) == IS_DOUBLE ) {
202+ ZVAL_COPY_VALUE (op , & dst );
203+ } else {
204+ ZVAL_LONG (op , 1 );
205+ }
206+ }
176207 break ;
177208 }
178209}
@@ -215,17 +246,17 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
215246 break; \
216247 case IS_OBJECT: \
217248 ZVAL_COPY(&(holder), op); \
218- convert_to_long_base (&(holder), 10); \
249+ _convert_scalar_to_number (&(holder), silent); \
219250 if (UNEXPECTED(EG(exception))) { \
220251 if (result != op1) { \
221252 ZVAL_UNDEF(result); \
222253 } \
223254 return FAILURE; \
224255 } \
225- if (Z_TYPE(holder) == IS_LONG) { \
256+ if (Z_TYPE(holder) == IS_LONG || Z_TYPE(holder) == IS_DOUBLE) { \
226257 if (op == result) { \
227258 zval_ptr_dtor(op); \
228- ZVAL_LONG (op, Z_LVAL (holder)); \
259+ ZVAL_COPY (op, & (holder)); \
229260 } else { \
230261 (op) = &(holder); \
231262 } \
@@ -237,26 +268,6 @@ ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
237268
238269/* }}} */
239270
240- /* {{{ convert_object_to_type: dst will be either ctype or UNDEF */
241- #define convert_object_to_type (op , dst , ctype , conv_func ) \
242- ZVAL_UNDEF(dst); \
243- if (Z_OBJ_HT_P(op)->cast_object) { \
244- if (Z_OBJ_HT_P(op)->cast_object(op, dst, ctype) == FAILURE) { \
245- zend_error(E_RECOVERABLE_ERROR, \
246- "Object of class %s could not be converted to %s", ZSTR_VAL(Z_OBJCE_P(op)->name),\
247- zend_get_type_by_const(ctype)); \
248- } \
249- } else if (Z_OBJ_HT_P(op)->get) { \
250- zval *newop = Z_OBJ_HT_P(op)->get(op, dst); \
251- if (Z_TYPE_P(newop) != IS_OBJECT) { \
252- /* for safety - avoid loop */ \
253- ZVAL_COPY_VALUE (dst , newop ); \
254- conv_func (dst ); \
255- } \
256- }
257-
258- /* }}} */
259-
260271#define convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , op , op_func ) \
261272 do { \
262273 if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { \
0 commit comments