diff options
author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:36:21 -0400 |
---|---|---|
committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:36:21 -0400 |
commit | d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (patch) | |
tree | b38e2e5c6974b9a15f103e5cf884cba9fff90ef4 /Zend/zend_objects_API.c | |
parent | a88a88d0986a4a32288c102cdbfebd78d7e91d99 (diff) | |
download | php-d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76.tar.gz |
Imported Upstream version 5.2.0upstream/5.2.0
Diffstat (limited to 'Zend/zend_objects_API.c')
-rw-r--r-- | Zend/zend_objects_API.c | 75 |
1 files changed, 60 insertions, 15 deletions
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 48b37b3ab..5a9a7a835 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_objects_API.c,v 1.47.2.6 2006/03/28 21:58:01 tony2001 Exp $ */ +/* $Id: zend_objects_API.c,v 1.47.2.6.2.3 2006/08/07 15:15:20 dmitry Exp $ */ #include "zend.h" #include "zend_globals.h" @@ -97,7 +97,7 @@ ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_st { zend_object_handle handle; struct _store_object *obj; - + if (EG(objects_store).free_list_head != -1) { handle = EG(objects_store).free_list_head; EG(objects_store).free_list_head = EG(objects_store).object_buckets[handle].bucket.free_list.next; @@ -125,6 +125,13 @@ ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_st return handle; } +ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC) +{ + zend_object_handle handle = Z_OBJ_HANDLE_P(object); + + return EG(objects_store).object_buckets[handle].bucket.obj.refcount; +} + ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC) { zend_object_handle handle = Z_OBJ_HANDLE_P(object); @@ -135,6 +142,14 @@ ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC) #endif } +/* + * Add a reference to an objects store entry given the object handle. + */ +ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC) +{ + EG(objects_store).object_buckets[handle].bucket.obj.refcount++; +} + #define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST() \ EG(objects_store).object_buckets[handle].bucket.free_list.next = EG(objects_store).free_list_head; \ EG(objects_store).free_list_head = handle; \ @@ -143,33 +158,52 @@ ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC) ZEND_API void zend_objects_store_del_ref(zval *zobject TSRMLS_DC) { zend_object_handle handle; + + handle = Z_OBJ_HANDLE_P(zobject); + + zobject->refcount++; + zend_objects_store_del_ref_by_handle(handle TSRMLS_CC); + zobject->refcount--; +} + +/* + * 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) +{ struct _store_object *obj; + int failure = 0; if (!EG(objects_store).object_buckets) { return; } - handle = Z_OBJ_HANDLE_P(zobject); obj = &EG(objects_store).object_buckets[handle].bucket.obj; /* Make sure we hold a reference count during the destructor call otherwise, when the destructor ends the storage might be freed when the refcount reaches 0 a second time - */ + */ if (EG(objects_store).object_buckets[handle].valid) { if (obj->refcount == 1) { if (!EG(objects_store).object_buckets[handle].destructor_called) { EG(objects_store).object_buckets[handle].destructor_called = 1; if (obj->dtor) { - zobject->refcount++; - obj->dtor(obj->object, handle TSRMLS_CC); - zobject->refcount--; + zend_try { + obj->dtor(obj->object, handle TSRMLS_CC); + } zend_catch { + failure = 1; + } zend_end_try(); } } if (obj->refcount == 1) { if (obj->free_storage) { - obj->free_storage(obj->object TSRMLS_CC); + zend_try { + obj->free_storage(obj->object TSRMLS_CC); + } zend_catch { + failure = 1; + } zend_end_try(); } ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(); } @@ -185,6 +219,9 @@ ZEND_API void zend_objects_store_del_ref(zval *zobject TSRMLS_DC) fprintf(stderr, "Decreased refcount of object id #%d\n", handle); } #endif + if (failure) { + zend_bailout(); + } } ZEND_API zend_object_value zend_objects_store_clone_obj(zval *zobject TSRMLS_DC) @@ -195,16 +232,16 @@ ZEND_API zend_object_value zend_objects_store_clone_obj(zval *zobject TSRMLS_DC) zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); obj = &EG(objects_store).object_buckets[handle].bucket.obj; - + if (obj->clone == NULL) { zend_error(E_CORE_ERROR, "Trying to clone uncloneable object of class %s", Z_OBJCE_P(zobject)->name); - } + } obj->clone(obj->object, &new_object TSRMLS_CC); retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC); retval.handlers = Z_OBJ_HT_P(zobject); - + return retval; } @@ -215,6 +252,14 @@ ZEND_API void *zend_object_store_get_object(zval *zobject TSRMLS_DC) return EG(objects_store).object_buckets[handle].bucket.obj.object; } +/* + * Retrieve an entry from the objects store given the object handle. + */ +ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC) +{ + return EG(objects_store).object_buckets[handle].bucket.obj.object; +} + /* zend_object_store_set_object: * It is ONLY valid to call this function from within the constructor of an * overloaded object. Its purpose is to set the object pointer for the object @@ -274,10 +319,10 @@ ZEND_API zval *zend_object_create_proxy(zval *object, zval *member TSRMLS_DC) zval_add_ref(&pobj->object); MAKE_STD_ZVAL(retval); - retval->type = IS_OBJECT; + Z_TYPE_P(retval) = IS_OBJECT; Z_OBJ_HANDLE_P(retval) = zend_objects_store_put(pobj, NULL, (zend_objects_free_object_storage_t) zend_objects_proxy_free_storage, (zend_objects_store_clone_t) zend_objects_proxy_clone TSRMLS_CC); Z_OBJ_HT_P(retval) = &zend_object_proxy_handlers; - + return retval; } @@ -312,7 +357,7 @@ ZEND_API zend_object_handlers *zend_get_std_object_handlers() static zend_object_handlers zend_object_proxy_handlers = { ZEND_OBJECTS_STORE_HANDLERS, - + NULL, /* read_property */ NULL, /* write_property */ NULL, /* read dimension */ |