cvs: ZendEngine2(PHP_5_1) / zend.h zend_object_handlers.c zend_objects.c zend_reflection_api.c php-src NEWS

From: Date: Tue, 15 Nov 2005 13:35:25 +0000
Subject: cvs: ZendEngine2(PHP_5_1) / zend.h zend_object_handlers.c zend_objects.c zend_reflection_api.c php-src NEWS
Groups: php.zend-engine.cvs 
Request: Send a blank email to [email protected] to get a copy of this message
dmitry		Tue Nov 15 08:35:25 2005 EDT

  Modified files:              (Branch: PHP_5_1)
    /php-src	NEWS 
    /ZendEngine2	zend.h zend_object_handlers.c zend_objects.c 
                	zend_reflection_api.c 
  Log:
  Allow recursive calls to __get/__set for different properties
  
  


http://cvs.php.net/diff.php/php-src/NEWS?r1=1.2027.2.189&r2=1.2027.2.190&ty=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.189 php-src/NEWS:1.2027.2.190 --- php-src/NEWS:1.2027.2.189 Tue Nov 15 08:29:15 2005 +++ php-src/NEWS Tue Nov 15 08:35:20 2005 @@ -1,6 +1,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? Nov 2005, PHP 5.1 +- Allow recursive calls to __get/__set for different properties. (Dmitry) - Upgraded PEAR to version 1.4.4. (Greg) - Fixed bug in mysqli extension with unsigned int(11) being represented as signed integer in PHP instead of string in 32bit systems. (Andrey) http://cvs.php.net/diff.php/ZendEngine2/zend.h?r1=1.293.2.3&r2=1.293.2.4&ty=u Index: ZendEngine2/zend.h diff -u ZendEngine2/zend.h:1.293.2.3 ZendEngine2/zend.h:1.293.2.4 --- ZendEngine2/zend.h:1.293.2.3 Thu Sep 1 06:05:30 2005 +++ ZendEngine2/zend.h Tue Nov 15 08:35:22 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend.h,v 1.293.2.3 2005/09/01 10:05:30 dmitry Exp $ */ +/* $Id: zend.h,v 1.293.2.4 2005/11/15 13:35:22 dmitry Exp $ */ #ifndef ZEND_H #define ZEND_H @@ -265,13 +265,18 @@ typedef struct _zval_struct zval; typedef struct _zend_class_entry zend_class_entry; +typedef struct _zend_guard { + zend_bool in_get; + zend_bool in_set; + zend_bool in_unset; + zend_bool in_isset; + zend_bool dummy; /* sizeof(zend_guard) must not be equal to sizeof(void*) */ +} zend_guard; + typedef struct _zend_object { zend_class_entry *ce; HashTable *properties; - unsigned int in_get:1; - unsigned int in_set:1; - unsigned int in_unset:1; - unsigned int in_isset:1; + HashTable *guards; /* protects from __get/__set ... recursion */ } zend_object; typedef unsigned int zend_object_handle; http://cvs.php.net/diff.php/ZendEngine2/zend_object_handlers.c?r1=1.135.2.2&r2=1.135.2.3&ty=u Index: ZendEngine2/zend_object_handlers.c diff -u ZendEngine2/zend_object_handlers.c:1.135.2.2 ZendEngine2/zend_object_handlers.c:1.135.2.3 --- ZendEngine2/zend_object_handlers.c:1.135.2.2 Thu Oct 20 05:47:12 2005 +++ ZendEngine2/zend_object_handlers.c Tue Nov 15 08:35:22 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_object_handlers.c,v 1.135.2.2 2005/10/20 09:47:12 dmitry Exp $ */ +/* $Id: zend_object_handlers.c,v 1.135.2.3 2005/11/15 13:35:22 dmitry Exp $ */ #include "zend.h" #include "zend_globals.h" @@ -237,7 +237,7 @@ EG(std_property_info).flags = ZEND_ACC_PUBLIC; EG(std_property_info).name = Z_STRVAL_P(member); EG(std_property_info).name_length = Z_STRLEN_P(member); - EG(std_property_info).h = zend_get_hash_value(EG(std_property_info).name, EG(std_property_info).name_length+1); + EG(std_property_info).h = h; property_info = &EG(std_property_info); } return property_info; @@ -268,6 +268,30 @@ return zend_verify_property_access(property_info, zobj->ce TSRMLS_CC) ? SUCCESS : FAILURE; } +static int zend_get_property_guard(zend_object *zobj, zend_property_info *property_info, zval *member, zend_guard **pguard) +{ + zend_property_info info; + zend_guard stub; + + if (!property_info) { + property_info = &info; + info.name = Z_STRVAL_P(member); + info.name_length = Z_STRLEN_P(member); + info.h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1); + } + if (!zobj->guards) { + ALLOC_HASHTABLE(zobj->guards); + zend_hash_init(zobj->guards, 0, NULL, NULL, 0); + } else if (zend_hash_quick_find(zobj->guards, property_info->name, property_info->name_length+1, property_info->h, (void **) pguard) == SUCCESS) { + return SUCCESS; + } + stub.in_get = 0; + stub.in_set = 0; + stub.in_unset = 0; + stub.in_isset = 0; + return zend_hash_quick_add(zobj->guards, property_info->name, property_info->name_length+1, property_info->h, (void**)&stub, sizeof(stub), (void**) pguard); +} + zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) { zend_object *zobj; @@ -276,11 +300,9 @@ zval *rv = NULL; zend_property_info *property_info; int silent; - zend_bool use_get; silent = (type == BP_VAR_IS); zobj = Z_OBJ_P(object); - use_get = (zobj->ce->__get && !zobj->in_get); if (member->type != IS_STRING) { ALLOC_ZVAL(tmp_member); @@ -296,14 +318,18 @@ #endif /* make zend_get_property_info silent if we have getter - we may want to use it */ - property_info = zend_get_property_info(zobj->ce, member, use_get TSRMLS_CC); + property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC); if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) { - if (use_get) { + zend_guard *guard; + + if (zobj->ce->__get && + zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS && + !guard->in_get) { /* have getter - try with it! */ - zobj->in_get = 1; /* prevent circular getting */ + guard->in_get = 1; /* prevent circular getting */ rv = zend_std_call_getter(object, member TSRMLS_CC); - zobj->in_get = 0; + guard->in_get = 0; if (rv) { retval = &rv; @@ -333,10 +359,8 @@ zval **variable_ptr; int setter_done = 0; zend_property_info *property_info; - zend_bool use_set; zobj = Z_OBJ_P(object); - use_set = (zobj->ce->__set && !zobj->in_set); if (member->type != IS_STRING) { ALLOC_ZVAL(tmp_member); @@ -347,7 +371,7 @@ member = tmp_member; } - property_info = zend_get_property_info(zobj->ce, member, use_set TSRMLS_CC); + property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__set != NULL) TSRMLS_CC); if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) { if (*variable_ptr == value) { @@ -368,13 +392,17 @@ } } } else { - if (use_set) { - zobj->in_set = 1; /* prevent circular setting */ + zend_guard *guard; + + if (zobj->ce->__set && + zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS && + !guard->in_set) { + guard->in_set = 1; /* prevent circular setting */ if (zend_std_call_setter(object, member, value TSRMLS_CC) != SUCCESS) { /* for now, just ignore it - __set should take care of warnings, etc. */ } setter_done = 1; - zobj->in_set = 0; + guard->in_set = 0; } } @@ -482,10 +510,8 @@ zval tmp_member; zval **retval; zend_property_info *property_info; - zend_bool use_get; zobj = Z_OBJ_P(object); - use_get = (zobj->ce->__get && !zobj->in_get); if (member->type != IS_STRING) { tmp_member = *member; @@ -498,12 +524,15 @@ fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); #endif - property_info = zend_get_property_info(zobj->ce, member, use_get TSRMLS_CC); + property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC); if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) { zval *new_zval; + zend_guard *guard; - if (!use_get) { + if (!zobj->ce->__get || + zend_get_property_guard(zobj, property_info, member, &guard) != SUCCESS || + guard->in_get) { /* we don't have access controls - will just add it */ new_zval = &EG(uninitialized_zval); @@ -527,10 +556,8 @@ zend_object *zobj; zval *tmp_member = NULL; zend_property_info *property_info; - zend_bool use_unset; zobj = Z_OBJ_P(object); - use_unset = (zobj->ce->__unset && !zobj->in_unset); if (member->type != IS_STRING) { ALLOC_ZVAL(tmp_member); @@ -541,14 +568,18 @@ member = tmp_member; } - property_info = zend_get_property_info(zobj->ce, member, 0 TSRMLS_CC); + property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__unset != NULL) TSRMLS_CC); if (!property_info || zend_hash_del(zobj->properties, property_info->name, property_info->name_length+1) == FAILURE) { - if (use_unset) { + zend_guard *guard; + + if (zobj->ce->__unset && + zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS && + !guard->in_unset) { /* have unseter - try with it! */ - zobj->in_unset = 1; /* prevent circular unsetting */ + guard->in_unset = 1; /* prevent circular setting */ zend_std_call_unsetter(object, member TSRMLS_CC); - zobj->in_unset = 0; + guard->in_unset = 0; } } @@ -895,10 +926,8 @@ zval **value; zval *tmp_member = NULL; zend_property_info *property_info; - zend_bool use_isset; zobj = Z_OBJ_P(object); - use_isset = (zobj->ce->__isset && !zobj->in_isset); if (member->type != IS_STRING) { ALLOC_ZVAL(tmp_member); @@ -916,19 +945,25 @@ property_info = zend_get_property_info(zobj->ce, member, 1 TSRMLS_CC); if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &value) == FAILURE) { + zend_guard *guard; + result = 0; - if (use_isset && (has_set_exists != 2)) { + if ((has_set_exists != 2) && + zobj->ce->__isset && + zend_get_property_guard(zobj, property_info, member, &guard) == SUCCESS && + !guard->in_isset) { zval *rv; /* have issetter - try with it! */ - zobj->in_isset = 1; /* prevent circular getting */ + guard->in_isset = 1; /* prevent circular getting */ rv = zend_std_call_issetter(object, member TSRMLS_CC); - zobj->in_isset = 0; if (rv) { result = zend_is_true(rv); zval_ptr_dtor(&rv); - if (has_set_exists && result && !EG(exception) && zobj->ce->__get && !zobj->in_get) { + if (has_set_exists && result && !EG(exception) && zobj->ce->__get && !guard->in_get) { + guard->in_get = 1; rv = zend_std_call_getter(object, member TSRMLS_CC); + guard->in_get = 0; if (rv) { rv->refcount++; result = i_zend_is_true(rv); @@ -936,6 +971,7 @@ } } } + guard->in_isset = 0; } } else { switch (has_set_exists) { http://cvs.php.net/diff.php/ZendEngine2/zend_objects.c?r1=1.56&r2=1.56.2.1&ty=u Index: ZendEngine2/zend_objects.c diff -u ZendEngine2/zend_objects.c:1.56 ZendEngine2/zend_objects.c:1.56.2.1 --- ZendEngine2/zend_objects.c:1.56 Thu Aug 4 04:36:54 2005 +++ ZendEngine2/zend_objects.c Tue Nov 15 08:35:23 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_objects.c,v 1.56 2005/08/04 08:36:54 dmitry Exp $ */ +/* $Id: zend_objects.c,v 1.56.2.1 2005/11/15 13:35:23 dmitry Exp $ */ #include "zend.h" #include "zend_globals.h" @@ -88,6 +88,10 @@ ZEND_API void zend_objects_free_object_storage(zend_object *object TSRMLS_DC) { + if (object->guards) { + zend_hash_destroy(object->guards); + FREE_HASHTABLE(object->guards); + } zend_hash_destroy(object->properties); FREE_HASHTABLE(object->properties); efree(object); @@ -101,10 +105,7 @@ (*object)->ce = class_type; retval.handle = zend_objects_store_put(*object, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_objects_free_object_storage, NULL TSRMLS_CC); retval.handlers = &std_object_handlers; - (*object)->in_get = 0; - (*object)->in_set = 0; - (*object)->in_unset = 0; - (*object)->in_isset = 0; + (*object)->guards = NULL; return retval; } http://cvs.php.net/diff.php/ZendEngine2/zend_reflection_api.c?r1=1.164.2.9&r2=1.164.2.10&ty=u Index: ZendEngine2/zend_reflection_api.c diff -u ZendEngine2/zend_reflection_api.c:1.164.2.9 ZendEngine2/zend_reflection_api.c:1.164.2.10 --- ZendEngine2/zend_reflection_api.c:1.164.2.9 Fri Oct 21 04:03:26 2005 +++ ZendEngine2/zend_reflection_api.c Tue Nov 15 08:35:23 2005 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_reflection_api.c,v 1.164.2.9 2005/10/21 08:03:26 dmitry Exp $ */ +/* $Id: zend_reflection_api.c,v 1.164.2.10 2005/11/15 13:35:23 dmitry Exp $ */ #include "zend.h" #include "zend_API.h" #include "zend_exceptions.h" @@ -203,10 +203,7 @@ *intern_clone = emalloc(sizeof(reflection_object)); (*intern_clone)->zo.ce = intern->zo.ce; - (*intern_clone)->zo.in_get = 0; - (*intern_clone)->zo.in_set = 0; - (*intern_clone)->zo.in_unset = 0; - (*intern_clone)->zo.in_isset = 0; + (*intern_clone)->zo.guards = NULL; ALLOC_HASHTABLE((*intern_clone)->zo.properties); (*intern_clone)->ptr = intern->ptr; (*intern_clone)->free_ptr = intern->free_ptr; @@ -224,10 +221,7 @@ intern = emalloc(sizeof(reflection_object)); intern->zo.ce = class_type; - intern->zo.in_get = 0; - intern->zo.in_set = 0; - intern->zo.in_unset = 0; - intern->zo.in_isset = 0; + intern->zo.guards = NULL; intern->ptr = NULL; intern->obj = NULL; intern->free_ptr = 0;

Thread (3 messages)

« previous php.zend-engine.cvs (#4333) next »