From e95bb57da91db26d1d5f6410440a1cb1c62ee17f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Nov 2011 06:31:33 +0000 Subject: [PATCH] Fixed bug #60139 (Anonymous functions create cycles not detected by the GC) --- NEWS | 2 ++ Zend/tests/bug60139.phpt | 30 ++++++++++++++++++++++++++++++ Zend/zend_closures.c | 13 +++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 Zend/tests/bug60139.phpt diff --git a/NEWS b/NEWS index e2ac9dcdb88..9e9334542a8 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ PHP NEWS ?? ??? 2011, PHP 5.3.9 - Core: + . Fixed bug #60139 (Anonymous functions create cycles not detected by the + GC). (Dmitry) . Fixed bug #60120 (proc_open's streams may hang with stdin/out/err when the data exceeds or is equal to 2048 bytes). (Pierre, Pascal Borreli) . Fixed bug #60019 (Function time_nanosleep() is undefined on OS X). (Ilia) diff --git a/Zend/tests/bug60139.phpt b/Zend/tests/bug60139.phpt new file mode 100644 index 00000000000..e429fe2b03e --- /dev/null +++ b/Zend/tests/bug60139.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #60139 (Anonymous functions create cycles not detected by the GC) +--FILE-- +x = function() {}; + } +} + +class Bar { + public $x; + + public function __construct() { + $self = $this; + $this->x = function() use ($self) {}; + } +} + +gc_collect_cycles(); +new Foo; +var_dump(gc_collect_cycles()); +new Bar; +var_dump(gc_collect_cycles()); +?> +--EXPECT-- +int(0) +int(2) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index faa3b7705cb..80a8eb89004 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -280,6 +280,18 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_ } /* }}} */ +static HashTable *zend_closure_get_properties(zval *obj TSRMLS_DC) /* {{{ */ +{ + zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC); + + if (GC_G(gc_active)) { + return (closure->func.type == ZEND_USER_FUNCTION) ? closure->func.op_array.static_variables : NULL; + } + + return closure->std.properties; +} +/* }}} */ + /* {{{ proto Closure::__construct() Private constructor preventing instantiation */ ZEND_METHOD(Closure, __construct) @@ -316,6 +328,7 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */ closure_handlers.clone_obj = NULL; closure_handlers.get_debug_info = zend_closure_get_debug_info; closure_handlers.get_closure = zend_closure_get_closure; + closure_handlers.get_properties = zend_closure_get_properties; } /* }}} */