diff options
author | Stanislav Malyshev <stas@php.net> | 2004-03-28 12:08:26 +0000 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2004-03-28 12:08:26 +0000 |
commit | 9091bf8e5fdcf54393ea2e06bc518dd65eb2989c (patch) | |
tree | 1debaa205f7e236b7c4e5aeab4e6c092a083fea7 /Zend/zend_operators.c | |
parent | 3b8b43a947931469116e992d50499d2b6fa9b690 (diff) | |
download | php-git-9091bf8e5fdcf54393ea2e06bc518dd65eb2989c.tar.gz |
centralize object-to-scalar conversion, make it work with get handler
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r-- | Zend/zend_operators.c | 129 |
1 files changed, 71 insertions, 58 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index bbf382edbf..66ffa1fce2 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -138,6 +138,9 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) zend_list_delete(op->value.lval); op->type = IS_LONG; break; + case IS_OBJECT: + convert_to_long_base(op, 10); + break; case IS_NULL: op->type = IS_LONG; op->value.lval = 0; @@ -180,6 +183,11 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) (holder).type = IS_LONG; \ (op) = &(holder); \ break; \ + case IS_OBJECT: \ + (holder) = (*(op)); \ + zval_copy_ctor(&(holder)); \ + convert_to_long_base(&(holder), 10); \ + break; \ } \ } @@ -206,7 +214,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) case IS_OBJECT: \ (holder) = (*(op)); \ zval_copy_ctor(&(holder)); \ - convert_to_long(&(holder)); \ + convert_to_long_base(&(holder), 10); \ break; \ case IS_BOOL: \ case IS_RESOURCE: \ @@ -262,6 +270,27 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) } +#define convert_object_to_type(op, ctype, conv_func) \ + if (Z_OBJ_HT_P(op)->cast_object) { \ + if (Z_OBJ_HT_P(op)->cast_object(op, op, ctype, 1 TSRMLS_CC) == SUCCESS) { \ + op->type = ctype; \ + return; \ + } \ + } else { \ + if(Z_OBJ_HT_P(op)->get) { \ + zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC); \ + if(Z_TYPE_P(newop) != IS_OBJECT) { \ + /* for safety - avoid loop */ \ + zval_dtor(op); \ + *op = *newop; \ + FREE_ZVAL(newop); \ + conv_func(op); \ + return; \ + } \ + } \ + } + + ZEND_API void convert_to_long(zval *op) { convert_to_long_base(op, 10); @@ -301,27 +330,22 @@ ZEND_API void convert_to_long_base(zval *op, int base) break; case IS_OBJECT: { + int retval = 1; TSRMLS_FETCH(); - if (Z_OBJ_HT_P(op)->cast_object) { - if (Z_OBJ_HT_P(op)->cast_object(op, op, IS_LONG, 1 TSRMLS_CC) == SUCCESS) { - break; - } - } else { - int retval = 1; + convert_object_to_type(op, IS_LONG, convert_to_long); - if (EG(ze1_compatibility_mode)) { - HashTable *ht = Z_OBJPROP_P(op); - if (ht) { - retval = (zend_hash_num_elements(ht)?1:0); - } - } else { - zend_error(E_NOTICE, "Object of class %s could not be converted to integer", Z_OBJCE_P(op)->name); + if (EG(ze1_compatibility_mode)) { + HashTable *ht = Z_OBJPROP_P(op); + if (ht) { + retval = (zend_hash_num_elements(ht)?1:0); } - - zval_dtor(op); - ZVAL_LONG(op, retval); + } else { + zend_error(E_NOTICE, "Object of class %s could not be converted to integer", Z_OBJCE_P(op)->name); } + + zval_dtor(op); + ZVAL_LONG(op, retval); break; } default: @@ -369,28 +393,22 @@ ZEND_API void convert_to_double(zval *op) break; case IS_OBJECT: { + double retval = 1.0; TSRMLS_FETCH(); + + convert_object_to_type(op, IS_DOUBLE, convert_to_double); - if (Z_OBJ_HT_P(op)->cast_object) { - TSRMLS_FETCH(); - if (Z_OBJ_HT_P(op)->cast_object(op, op, IS_DOUBLE, 1 TSRMLS_CC) == SUCCESS) { - break; + if (EG(ze1_compatibility_mode)) { + HashTable *ht = Z_OBJPROP_P(op); + if (ht) { + retval = (zend_hash_num_elements(ht)?1.0:0.0); } } else { - double retval = 1.0; - - if (EG(ze1_compatibility_mode)) { - HashTable *ht = Z_OBJPROP_P(op); - if (ht) { - retval = (zend_hash_num_elements(ht)?1.0:0.0); - } - } else { - zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name); - } - - zval_dtor(op); - ZVAL_DOUBLE(op, retval); + zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name); } + + zval_dtor(op); + ZVAL_DOUBLE(op, retval); break; } default: @@ -460,25 +478,20 @@ ZEND_API void convert_to_boolean(zval *op) break; case IS_OBJECT: { + zend_bool retval = 1; TSRMLS_FETCH(); - if (Z_OBJ_HT_P(op)->cast_object) { - if (Z_OBJ_HT_P(op)->cast_object(op, op, IS_BOOL, 1 TSRMLS_CC) == SUCCESS) { - break; - } - } else { - zend_bool retval = 1; + convert_object_to_type(op, IS_BOOL, convert_to_double); - if (EG(ze1_compatibility_mode)) { - HashTable *ht = Z_OBJPROP_P(op); - if (ht) { - retval = (zend_hash_num_elements(ht)?1:0); - } + if (EG(ze1_compatibility_mode)) { + HashTable *ht = Z_OBJPROP_P(op); + if (ht) { + retval = (zend_hash_num_elements(ht)?1:0); } - - zval_dtor(op); - ZVAL_BOOL(op, retval); } + + zval_dtor(op); + ZVAL_BOOL(op, retval); break; } default: @@ -489,7 +502,6 @@ ZEND_API void convert_to_boolean(zval *op) op->type = IS_BOOL; } - ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) { long lval; @@ -542,14 +554,10 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) break; case IS_OBJECT: { TSRMLS_FETCH(); - if (Z_OBJ_HT_P(op)->cast_object) { - if (Z_OBJ_HT_P(op)->cast_object(op, op, IS_STRING, 1 TSRMLS_CC) == SUCCESS) { - break; - } - zend_error(E_NOTICE, "Object of class %s could not be converted to string", Z_OBJCE_P(op)->name); - } else { - zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name); - } + + convert_object_to_type(op, IS_STRING, convert_to_string); + + zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name); zval_dtor(op); op->value.str.val = estrndup_rel("Object", sizeof("Object")-1); op->value.str.len = sizeof("Object")-1; @@ -609,7 +617,12 @@ ZEND_API void convert_to_array(zval *op) ALLOC_HASHTABLE(ht); zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0); if (Z_OBJ_HT_P(op)->get_properties) { - zend_hash_copy(ht, Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC); + if(obj_ht) { + zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + } + } else { + convert_object_to_type(op, IS_ARRAY, convert_to_array); } zval_dtor(op); op->type = IS_ARRAY; |