summaryrefslogtreecommitdiff
path: root/Zend/zend_objects_API.c
diff options
context:
space:
mode:
authorMark A. Hershberger <mah@debian.(none)>2009-03-25 00:36:21 -0400
committerMark A. Hershberger <mah@debian.(none)>2009-03-25 00:36:21 -0400
commitd29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (patch)
treeb38e2e5c6974b9a15f103e5cf884cba9fff90ef4 /Zend/zend_objects_API.c
parenta88a88d0986a4a32288c102cdbfebd78d7e91d99 (diff)
downloadphp-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.c75
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 */