From: Sterling Hughes Date: Tue, 27 May 2003 18:52:25 +0000 (+0000) Subject: Assume lazy consensus regarding the cast_object() patch. *Only* implemented X-Git-Tag: RELEASE_1_0_2~565 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae2bfb78808099609f516b4be0d4282c528d192a;p=php Assume lazy consensus regarding the cast_object() patch. *Only* implemented from a internals perspective. This callback has been very useful for both ext/mono and ext/simplexml --- diff --git a/Zend/zend.c b/Zend/zend.c index 47416cd520..2fdd7d00ad 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -208,8 +208,13 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop expr_copy->value.str.val = estrndup("Array", expr_copy->value.str.len); break; case IS_OBJECT: - expr_copy->value.str.val = (char *) emalloc(sizeof("Object id #")-1 + MAX_LENGTH_OF_LONG); - expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Object id #%ld", (long)expr->value.obj.handle); + if (expr->value.obj.handlers->cast_object) { + TSRMLS_FETCH(); + expr->value.obj.handlers->cast_object(expr, expr_copy, IS_STRING, 0 TSRMLS_CC); + } else { + expr_copy->value.str.val = (char *) emalloc(sizeof("Object id #")-1 + MAX_LENGTH_OF_LONG); + expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Object id #%ld", (long)expr->value.obj.handle); + } #if 0 /* FIXME: This might break BC for some people */ expr_copy->value.str.len = sizeof("Object")-1; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 1932d8c8d3..4147f9e786 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -830,7 +830,8 @@ zend_object_handlers std_object_handlers = { zend_std_get_constructor, /* get_constructor */ zend_std_object_get_class, /* get_class_entry */ zend_std_object_get_class_name, /* get_class_name */ - zend_std_compare_objects /* compare_objects */ + zend_std_compare_objects, /* compare_objects */ + NULL, /* cast_object */ }; /* diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 78c9e4fee3..2676d1e8ce 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -67,6 +67,8 @@ typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC); typedef zend_class_entry *(*zend_object_get_class_entry_t)(zval *object TSRMLS_DC); typedef int (*zend_object_get_class_name_t)(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC); typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC); +typedef void (*zend_object_cast_t)(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC); + typedef struct _zend_object_handlers { /* general object functions */ @@ -90,6 +92,7 @@ typedef struct _zend_object_handlers { zend_object_get_class_entry_t get_class_entry; zend_object_get_class_name_t get_class_name; zend_object_compare_t compare_objects; + zend_object_cast_t cast_object; } zend_object_handlers; extern zend_object_handlers std_object_handlers; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 18408fed72..20a967197d 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -328,8 +328,13 @@ ZEND_API void convert_to_long_base(zval *op, int base) op->value.lval = tmp; break; case IS_OBJECT: - zval_dtor(op); - op->value.lval = 1; /* TBI!! */ + if (op->value.obj.handlers->cast_object) { + TSRMLS_FETCH(); + op->value.obj.handlers->cast_object(op, op, IS_LONG, 1 TSRMLS_CC); + } else { + zval_dtor(op); + op->value.lval = 1; + } break; default: zend_error(E_WARNING, "Cannot convert to ordinal value"); @@ -375,8 +380,13 @@ ZEND_API void convert_to_double(zval *op) op->value.dval = tmp; break; case IS_OBJECT: - zval_dtor(op); - op->value.dval = 1; /* TBI!! */ + if (op->value.obj.handlers->cast_object) { + TSRMLS_FETCH(); + op->value.obj.handlers->cast_object(op, op, IS_DOUBLE, 1 TSRMLS_CC); + } else { + zval_dtor(op); + op->value.dval = 1; /* TBI!! */ + } break; default: zend_error(E_WARNING, "Cannot convert to real value (type=%d)", op->type); @@ -390,6 +400,14 @@ ZEND_API void convert_to_double(zval *op) ZEND_API void convert_to_null(zval *op) { + if (op->type == IS_OBJECT) { + if (op->value.obj.handlers->cast_object) { + TSRMLS_FETCH(); + op->value.obj.handlers->cast_object(op, op, IS_NULL, 1 TSRMLS_CC); + return; + } + } + zval_dtor(op); op->type = IS_NULL; } @@ -435,8 +453,13 @@ ZEND_API void convert_to_boolean(zval *op) op->value.lval = tmp; break; case IS_OBJECT: - zval_dtor(op); - op->value.lval = 1; /* TBI!! */ + if (op->value.obj.handlers->cast_object) { + TSRMLS_FETCH(); + op->value.obj.handlers->cast_object(op, op, IS_BOOL, 1 TSRMLS_CC); + } else { + zval_dtor(op); + op->value.lval = 1; /* TBI!! */ + } break; default: zval_dtor(op); @@ -497,10 +520,15 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) zend_error(E_NOTICE, "Array to string conversion"); break; case IS_OBJECT: - zval_dtor(op); - op->value.str.val = estrndup_rel("Object", sizeof("Object")-1); - op->value.str.len = sizeof("Object")-1; - zend_error(E_NOTICE, "Object to string conversion"); + if (op->value.obj.handlers->cast_object) { + TSRMLS_FETCH(); + op->value.obj.handlers->cast_object(op, op, IS_STRING, 1 TSRMLS_CC); + } else { + zval_dtor(op); + op->value.str.val = estrndup_rel("Object", sizeof("Object")-1); + op->value.str.len = sizeof("Object")-1; + zend_error(E_NOTICE, "Object to string conversion"); + } break; default: zval_dtor(op);