cvs: ZendEngine2(PHP_5_3) / zend_closures.c zend_closures.h zend_object_handlers.c /tests closure_033.phpt closure_034.phpt
[email protected] ("Marcus Boerger")
| Newsgroups | php.zend-engine.cvs |
|---|---|
| Message-ID | <cvshelly1231004920@cvsserver> |
helly Sat Jan 3 17:48:40 2009 UTC
Added files: (Branch: PHP_5_3)
/ZendEngine2/tests closure_033.phpt closure_034.phpt
Modified files:
/ZendEngine2 zend_closures.c zend_closures.h zend_object_handlers.c
Log:
- MFH Rebind closure when binding to property
helly-20090103174840.txt
(text/plain, 8.6 KB)
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_closures.c?r1=1.3.2.20&r2=1.3.2.21&diff_format=u
Index: ZendEngine2/zend_closures.c
diff -u ZendEngine2/zend_closures.c:1.3.2.20 ZendEngine2/zend_closures.c:1.3.2.21
--- ZendEngine2/zend_closures.c:1.3.2.20 Sat Jan 3 12:25:59 2009
+++ ZendEngine2/zend_closures.c Sat Jan 3 17:48:39 2009
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_closures.c,v 1.3.2.20 2009/01/03 12:25:59 helly Exp $ */
+/* $Id: zend_closures.c,v 1.3.2.21 2009/01/03 17:48:39 helly Exp $ */
#include "zend.h"
#include "zend_API.h"
@@ -118,6 +118,17 @@
}
/* }}} */
+ZEND_API zval* zend_closure_copy(zval *closure_obj, zval *this_ptr TSRMLS_DC) /* {{{ */
+{
+ zend_closure *closure;
+
+ zval_copy_ctor(closure_obj);
+ closure = (zend_closure *)zend_object_store_get_object(closure_obj TSRMLS_CC);
+ closure->this_ptr = this_ptr;
+ return closure_obj;
+}
+/* }}} */
+
static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */
{
char *lc_name;
@@ -238,7 +249,7 @@
}
/* }}} */
-ZEND_API HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
+static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)zend_object_store_get_object(object TSRMLS_CC);
HashTable *rv;
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_closures.h?r1=1.1.2.5&r2=1.1.2.6&diff_format=u
Index: ZendEngine2/zend_closures.h
diff -u ZendEngine2/zend_closures.h:1.1.2.5 ZendEngine2/zend_closures.h:1.1.2.6
--- ZendEngine2/zend_closures.h:1.1.2.5 Sat Jan 3 12:25:59 2009
+++ ZendEngine2/zend_closures.h Sat Jan 3 17:48:39 2009
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_closures.h,v 1.1.2.5 2009/01/03 12:25:59 helly Exp $ */
+/* $Id: zend_closures.h,v 1.1.2.6 2009/01/03 17:48:39 helly Exp $ */
#ifndef ZEND_CLOSURES_H
#define ZEND_CLOSURES_H
@@ -35,6 +35,7 @@
ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC);
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC);
ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC);
+ZEND_API zval* zend_closure_copy(zval *closure, zval *this_ptr TSRMLS_DC);
END_EXTERN_C()
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_object_handlers.c?r1=1.135.2.6.2.22.2.23&r2=1.135.2.6.2.22.2.24&diff_format=u
Index: ZendEngine2/zend_object_handlers.c
diff -u ZendEngine2/zend_object_handlers.c:1.135.2.6.2.22.2.23 ZendEngine2/zend_object_handlers.c:1.135.2.6.2.22.2.24
--- ZendEngine2/zend_object_handlers.c:1.135.2.6.2.22.2.23 Wed Dec 31 11:15:32 2008
+++ ZendEngine2/zend_object_handlers.c Sat Jan 3 17:48:39 2009
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_object_handlers.c,v 1.135.2.6.2.22.2.23 2008/12/31 11:15:32 sebastian Exp $ */
+/* $Id: zend_object_handlers.c,v 1.135.2.6.2.22.2.24 2009/01/03 17:48:39 helly Exp $ */
#include "zend.h"
#include "zend_globals.h"
@@ -405,6 +405,10 @@
member = tmp_member;
}
+ if (value && Z_TYPE_P(value) == IS_OBJECT && Z_OBJCE_P(value) == zend_ce_closure && zend_get_closure_this_ptr(value TSRMLS_CC) != object) {
+ value = zend_closure_copy(value, object TSRMLS_CC);
+ }
+
property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__set != NULL) TSRMLS_CC);
if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) {
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/closure_033.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/closure_033.phpt
+++ ZendEngine2/tests/closure_033.phpt
--TEST--
Closure 033: Dynamic closure property and private function
--FILE--
<?php
class Test {
public $func;
function __construct() {
$this->func = function() {
echo __METHOD__ . "()\n";
};
}
private function func() {
echo __METHOD__ . "()\n";
}
}
$o = new Test;
$f = $o->func;
$f();
$o->func();
?>
===DONE===
--EXPECTF--
Test::{closure}()
Fatal error: Call to private method Test::func() from context '' in %sclosure_033.php on line %d
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/closure_034.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/closure_034.phpt
+++ ZendEngine2/tests/closure_034.phpt
--TEST--
Closure 034: var_dump() of a Closure
--FILE--
<?php
$outer = 25;
class Test {
public $func1;
public $var = 42;
function __construct() {
global $outer;
$this->func1 = function($param, $other = "default") use ($outer) {
};
}
}
$o = new Test;
var_dump($o->func1);
$o->func2 = function($param, $other = "default") use ($outer) {
};
var_dump($o->func2);
$func3 = function($param, $other = "default") use ($outer) {
};
var_dump($func3);
?>
===DONE===
--EXPECTF--
object(Closure)#%d (3) {
["this"]=>
object(Test)#%d (2) {
[u"func1"]=>
object(Closure)#%d (3) {
["this"]=>
object(Test)#%d (2) {
[u"func1"]=>
object(Closure)#%d (3) {
["this"]=>
*RECURSION*
["static"]=>
array(1) {
[u"outer"]=>
int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
[u"var"]=>
int(42)
}
["static"]=>
array(1) {
[u"outer"]=>
int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
[u"var"]=>
int(42)
}
["static"]=>
array(1) {
[u"outer"]=>
int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
object(Closure)#%d (3) {
["this"]=>
object(Test)#%d (3) {
[u"func1"]=>
object(Closure)#%d (3) {
["this"]=>
object(Test)#%d (3) {
[u"func1"]=>
object(Closure)#%d (3) {
["this"]=>
*RECURSION*
["static"]=>
array(1) {
[u"outer"]=>
int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
[u"var"]=>
int(42)
[u"func2"]=>
object(Closure)#%d (3) {
["this"]=>
*RECURSION*
["static"]=>
array(1) {
[u"outer"]=>
&int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
}
["static"]=>
array(1) {
[u"outer"]=>
int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
[u"var"]=>
int(42)
[u"func2"]=>
object(Closure)#%d (3) {
["this"]=>
object(Test)#%d (3) {
[u"func1"]=>
object(Closure)#%d (3) {
["this"]=>
*RECURSION*
["static"]=>
array(1) {
[u"outer"]=>
int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
[u"var"]=>
int(42)
[u"func2"]=>
object(Closure)#%d (3) {
["this"]=>
*RECURSION*
["static"]=>
array(1) {
[u"outer"]=>
&int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
}
["static"]=>
array(1) {
[u"outer"]=>
&int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
}
["static"]=>
array(1) {
[u"outer"]=>
&int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
object(Closure)#%d (3) {
["this"]=>
NULL
["static"]=>
array(1) {
[u"outer"]=>
int(25)
}
["parameter"]=>
array(2) {
["$param"]=>
string(10) "<required>"
["$other"]=>
string(10) "<optional>"
}
}
===DONE===