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===
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.