summaryrefslogtreecommitdiff
path: root/Zend/zend_objects.c
diff options
context:
space:
mode:
authorAndi Gutmans <andi@php.net>2001-12-27 14:35:09 +0000
committerAndi Gutmans <andi@php.net>2001-12-27 14:35:09 +0000
commit73b159e0567683f96a2da78d7a2e60cf0f6f0bbc (patch)
tree5d077c4f72a7868f75649cf12a2f2b23e684ed6c /Zend/zend_objects.c
parentb3fd2faac06a6f9f216070b00ad46c13309fa6b3 (diff)
downloadphp-git-73b159e0567683f96a2da78d7a2e60cf0f6f0bbc.tar.gz
- Experimental support for destructors. We need to see if destructors
- will actually work well in the context of PHP so we should consider this - as experimental. Possible problems might be that when the constructor is - run PHP might not be in a stable state.
Diffstat (limited to 'Zend/zend_objects.c')
-rw-r--r--Zend/zend_objects.c64
1 files changed, 56 insertions, 8 deletions
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index f86148158d..776f7d9076 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -27,6 +27,43 @@ void zend_objects_destroy(zend_objects *objects)
efree(objects->object_buckets);
}
+static inline void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC)
+{
+ if (object->ce->destructor) {
+ zval *obj;
+ zval *destructor_func_name;
+ zval *retval_ptr;
+ HashTable symbol_table;
+
+ MAKE_STD_ZVAL(obj);
+ obj->type = IS_OBJECT;
+ obj->value.obj.handle = handle;
+ obj->value.obj.handlers = &zoh;
+ zval_copy_ctor(obj);
+
+
+ /* FIXME: Optimize this so that we use the old_object->ce->destructor function pointer instead of the name */
+ MAKE_STD_ZVAL(destructor_func_name);
+ destructor_func_name->type = IS_STRING;
+ destructor_func_name->value.str.val = estrndup("_destruct", sizeof("_destruct")-1);
+ destructor_func_name->value.str.len = sizeof("_destruct")-1;
+
+ ZEND_INIT_SYMTABLE(&symbol_table);
+
+ call_user_function_ex(NULL, &obj, destructor_func_name, &retval_ptr, 0, NULL, 0, &symbol_table TSRMLS_CC);
+
+ zend_hash_destroy(&symbol_table);
+ zval_ptr_dtor(&obj);
+ zval_ptr_dtor(&destructor_func_name);
+ zval_ptr_dtor(&retval_ptr);
+ }
+
+ /* Nuke the object */
+ zend_hash_destroy(object->properties);
+ efree(object->properties);
+
+}
+
zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type)
{
zend_object_handle handle;
@@ -45,6 +82,7 @@ zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class
handle = EG(objects).top++;
}
EG(objects).object_buckets[handle].valid = 1;
+ EG(objects).object_buckets[handle].constructor_called = 0;
EG(objects).object_buckets[handle].bucket.obj.refcount = 1;
*object = &EG(objects).object_buckets[handle].bucket.obj.object;
@@ -93,9 +131,14 @@ void zend_objects_delete_obj(zend_object_handle handle)
}
object = &EG(objects).object_buckets[handle].bucket.obj.object;
- zend_hash_destroy(object->properties);
- efree(object->properties);
+
+ if (!EG(objects).object_buckets[handle].constructor_called) {
+ EG(objects).object_buckets[handle].constructor_called = 1;
+ zend_objects_destroy_object(object, handle TSRMLS_CC);
+ }
+
EG(objects).object_buckets[handle].valid = 0;
+
#if ZEND_DEBUG_OBJECTS
fprintf(stderr, "Deleted object id #%d\n", handle);
#endif
@@ -110,13 +153,18 @@ void zend_objects_del_ref(zend_object_handle handle)
zend_object *object;
if (EG(objects).object_buckets[handle].valid) {
- object = &EG(objects).object_buckets[handle].bucket.obj.object;
- zend_hash_destroy(object->properties);
- efree(object->properties);
+ if (!EG(objects).object_buckets[handle].constructor_called) {
+ object = &EG(objects).object_buckets[handle].bucket.obj.object;
+ EG(objects).object_buckets[handle].constructor_called = 1;
+ zend_objects_destroy_object(object, handle TSRMLS_CC);
+ }
+ }
+ /* FIXME: Optimizer this so that only if the constructor was called we recheck the refcount */
+ if (EG(objects).object_buckets[handle].bucket.obj.refcount == 0) {
+ EG(objects).object_buckets[handle].bucket.free_list.next = EG(objects).free_list_head;
+ EG(objects).free_list_head = handle;
+ EG(objects).object_buckets[handle].valid = 0;
}
- EG(objects).object_buckets[handle].bucket.free_list.next = EG(objects).free_list_head;
- EG(objects).free_list_head = handle;
- EG(objects).object_buckets[handle].valid = 0;
#if ZEND_DEBUG_OBJECTS
fprintf(stderr, "Deallocated object id #%d\n", handle);
#endif