diff options
| author | Andi Gutmans <andi@php.net> | 2001-12-27 14:35:09 +0000 | 
|---|---|---|
| committer | Andi Gutmans <andi@php.net> | 2001-12-27 14:35:09 +0000 | 
| commit | 73b159e0567683f96a2da78d7a2e60cf0f6f0bbc (patch) | |
| tree | 5d077c4f72a7868f75649cf12a2f2b23e684ed6c /Zend/zend_objects.c | |
| parent | b3fd2faac06a6f9f216070b00ad46c13309fa6b3 (diff) | |
| download | php-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.c | 64 | 
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 | 
