Re: [ZEND-ENGINE-CVS] cvs: ZendEngine2 / zend_gc.c zend_objects.c zend_objects_API.c zend_objects_API.h
[email protected] (Marcus Boerger)
| Newsgroups | php.zend-engine.cvs |
|---|---|
| Message-ID | <[email protected]> |
Hello all,
the better way might be to require the handlers in zend_objects_store_put()
but that would have been a change in an API call that is in use throughout
PHP and PECL. So I went with this version that works in all cases I
checked. In case someone wants to do the real fix, they just need to add
the handlers as a parameter to said function, set the handlers already
there and then fix all invocations.
marcus
Sunday, August 24, 2008, 6:45:50 PM, you wrote:
> helly Sun Aug 24 16:45:50 2008 UTC
> Modified files:
> /ZendEngine2 zend_objects_API.c zend_objects_API.h zend_objects.c
> zend_gc.c
> Log:
> - Fix issue with destruction of overloaded objects
> # The issue is that we assume default object handlers when calling method
> # __destruct(). Now the default handlers might not be compatible with the
> # correct handlers which would result in crashes or they simply do cannot
> # support everything the object was supposed to do. The latter case will be
> # demonstrated in ext/spl/tests/iterator_068.phpt.
>
>
> http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_objects_API.c?r1=1.70&r2=1.71&diff_format=u
> Index: ZendEngine2/zend_objects_API.c
> diff -u ZendEngine2/zend_objects_API.c:1.70 ZendEngine2/zend_objects_API.c:1.71
> --- ZendEngine2/zend_objects_API.c:1.70 Tue Aug 12 17:15:59 2008
> +++ ZendEngine2/zend_objects_API.c Sun Aug 24 16:45:49 2008
> @@ -17,7 +17,7 @@
>
> +----------------------------------------------------------------------+
> */
>
> -/* $Id: zend_objects_API.c,v 1.70 2008/08/12 17:15:59 felipe Exp $ */
> +/* $Id: zend_objects_API.c,v 1.71 2008/08/24 16:45:49 helly Exp $ */
>
> #include "zend.h"
> #include "zend_globals.h"
> @@ -125,8 +125,8 @@
> obj->object = object;
> obj->dtor =
> dtor?dtor:(zend_objects_store_dtor_t)zend_objects_destroy_object;
> obj->free_storage = free_storage;
> -
> obj->clone = clone;
> + obj->handlers = NULL;
>
> #if ZEND_DEBUG_OBJECTS
> fprintf(stderr, "Allocated object id #%d\n", handle);
> @@ -184,7 +184,7 @@
> handle = Z_OBJ_HANDLE_P(zobject);
>
> Z_ADDREF_P(zobject);
> - zend_objects_store_del_ref_by_handle(handle TSRMLS_CC);
> + zend_objects_store_del_ref_by_handle_ex(handle, Z_OBJ_HT_P(zobject) TSRMLS_CC);
> Z_DELREF_P(zobject);
>
> GC_ZOBJ_CHECK_POSSIBLE_ROOT(zobject);
> @@ -194,7 +194,7 @@
> /*
> * Delete a reference to an objects store entry given the object handle.
> */
> -ZEND_API void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC) /* {{{ */
> +ZEND_API void
> zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const
> zend_object_handlers *handlers TSRMLS_DC) /* {{{ */
> {
> struct _store_object *obj;
> int failure = 0;
> @@ -215,6 +215,9 @@
>
> EG(objects_store).object_buckets[handle].destructor_called = 1;
>
> if (obj->dtor) {
> + if (handlers && !obj->handlers) {
> + obj->handlers = handlers;
> + }
> zend_try {
> obj->dtor(obj->object, handle TSRMLS_CC);
> } zend_catch {
> @@ -268,6 +271,7 @@
>
> retval.handle = zend_objects_store_put(new_object, obj->dtor,
> obj->free_storage, obj->clone TSRMLS_CC);
> retval.handlers = Z_OBJ_HT_P(zobject);
> + EG(objects_store).object_buckets[handle].bucket.obj.handlers = retval.handlers;
>
> return retval;
> }
> @@ -309,8 +313,10 @@
> ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC) /* {{{ */
> {
> zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
> -
> - EG(objects_store).object_buckets[handle].destructor_called = 1;
> + zend_object_store_bucket *obj_bucket =
> &EG(objects_store).object_buckets[handle];
> +
> + obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject);;
> + obj_bucket->destructor_called = 1;
> }
> /* }}} */
>
> http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_objects_API.h?r1=1.31&r2=1.32&diff_format=u
> Index: ZendEngine2/zend_objects_API.h
> diff -u ZendEngine2/zend_objects_API.h:1.31 ZendEngine2/zend_objects_API.h:1.32
> --- ZendEngine2/zend_objects_API.h:1.31 Tue Aug 12 17:15:59 2008
> +++ ZendEngine2/zend_objects_API.h Sun Aug 24 16:45:49 2008
> @@ -17,7 +17,7 @@
>
> +----------------------------------------------------------------------+
> */
>
> -/* $Id: zend_objects_API.h,v 1.31 2008/08/12 17:15:59 felipe Exp $ */
> +/* $Id: zend_objects_API.h,v 1.32 2008/08/24 16:45:49 helly Exp $ */
>
> #ifndef ZEND_OBJECTS_API_H
> #define ZEND_OBJECTS_API_H
> @@ -37,6 +37,7 @@
> zend_objects_store_dtor_t dtor;
> zend_objects_free_object_storage_t free_storage;
> zend_objects_store_clone_t clone;
> + const zend_object_handlers *handlers;
> zend_uint refcount;
> gc_root_buffer *buffered;
> } obj;
> @@ -66,7 +67,10 @@
> ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC);
> ZEND_API void zend_objects_store_del_ref(zval *object TSRMLS_DC);
> ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC);
> -ZEND_API void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC);
> +ZEND_API void
> zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const
> zend_object_handlers *handlers TSRMLS_DC);
> +static inline void
> zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC)
> + zend_objects_store_del_ref_by_handle_ex(handle, NULL TSRMLS_CC);
> +}
> ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC);
> ZEND_API int zend_objects_is_destructor_called(zend_object_handle handle TSRMLS_DC);
> ZEND_API zend_object_value zend_objects_store_clone_obj(zval *object TSRMLS_DC);
> http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_objects.c?r1=1.79&r2=1.80&diff_format=u
> Index: ZendEngine2/zend_objects.c
> diff -u ZendEngine2/zend_objects.c:1.79 ZendEngine2/zend_objects.c:1.80
> --- ZendEngine2/zend_objects.c:1.79 Thu Aug 14 10:06:39 2008
> +++ ZendEngine2/zend_objects.c Sun Aug 24 16:45:49 2008
> @@ -17,7 +17,7 @@
>
> +----------------------------------------------------------------------+
> */
>
> -/* $Id: zend_objects.c,v 1.79 2008/08/14 10:06:39 helly Exp $ */
> +/* $Id: zend_objects.c,v 1.80 2008/08/24 16:45:49 helly Exp $ */
>
> #include "zend.h"
> #include "zend_globals.h"
> @@ -55,6 +55,7 @@
>
> if (destructor) {
> zval *obj;
> + zend_object_store_bucket *obj_bucket;
>
> if (destructor->op_array.fn_flags &
> (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
> if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
> @@ -89,7 +90,11 @@
> MAKE_STD_ZVAL(obj);
> Z_TYPE_P(obj) = IS_OBJECT;
> Z_OBJ_HANDLE_P(obj) = handle;
> - Z_OBJ_HT_P(obj) = &std_object_handlers;
> + obj_bucket = &EG(objects_store).object_buckets[handle];
> + if (!obj_bucket->bucket.obj.handlers) {
> + obj_bucket->bucket.obj.handlers = &std_object_handlers;
> + }
> + Z_OBJ_HT_P(obj) = obj_bucket->bucket.obj.handlers;
> zval_copy_ctor(obj);
>
> /* Make sure that destructors are protected from previously thrown exceptions.
> http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_gc.c?r1=1.16&r2=1.17&diff_format=u
> Index: ZendEngine2/zend_gc.c
> diff -u ZendEngine2/zend_gc.c:1.16 ZendEngine2/zend_gc.c:1.17
> --- ZendEngine2/zend_gc.c:1.16 Fri Aug 15 19:45:25 2008
> +++ ZendEngine2/zend_gc.c Sun Aug 24 16:45:50 2008
> @@ -17,7 +17,7 @@
>
> +----------------------------------------------------------------------+
> */
>
> -/* $Id: zend_gc.c,v 1.16 2008/08/15 19:45:25 felipe Exp $ */
> +/* $Id: zend_gc.c,v 1.17 2008/08/24 16:45:50 helly Exp $ */
>
> #include "zend.h"
> #include "zend_API.h"
> @@ -571,7 +571,7 @@
>
> EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount <= 0) {
>
> EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount = 1;
> Z_TYPE(p->z) = IS_NULL;
> -
> zend_objects_store_del_ref_by_handle(Z_OBJ_HANDLE(p->z) TSRMLS_CC);
> +
> zend_objects_store_del_ref_by_handle_ex(Z_OBJ_HANDLE(p->z), Z_OBJ_HT(p->z) TSRMLS_CC);
> }
> } else if (Z_TYPE(p->z) == IS_ARRAY) {
> Z_TYPE(p->z) = IS_NULL;
Best regards,
Marcus