cvs: ZendEngine2 / zend_API.c zend_closures.c zend_compile.c /tests closure_016.phpt

"Dmitry Stogov" <[email protected]>
Newsgroups gmane.comp.php.cvs.zend
Message-ID <cvsdmitry1216037837@cvsserver>
dmitry		Mon Jul 14 12:17:17 2008 UTC

  Added files:                 
    /ZendEngine2/tests	closure_016.phpt 

  Modified files:              
    /ZendEngine2	zend_API.c zend_closures.c zend_compile.c 
  Log:
  Fixed is_callable() to support closures and return appropriate function name
  
  
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_API.c?r1=1.474&r2=1.475&diff_format=u
Index: ZendEngine2/zend_API.c
diff -u ZendEngine2/zend_API.c:1.474 ZendEngine2/zend_API.c:1.475
--- ZendEngine2/zend_API.c:1.474	Tue Jul  8 07:05:03 2008
+++ ZendEngine2/zend_API.c	Mon Jul 14 12:17:16 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_API.c,v 1.474 2008/07/08 07:05:03 dmitry Exp $ */
+/* $Id: zend_API.c,v 1.475 2008/07/14 12:17:16 dmitry Exp $ */
 
 #include "zend.h"
 #include "zend_execute.h"
@@ -3097,7 +3097,21 @@
 		case IS_OBJECT:
 			if (zend_get_closure(callable, ce_ptr, fptr_ptr, NULL, zobj_ptr_ptr TSRMLS_CC) == SUCCESS) {
 				if (callable_name) {
-					ZVAL_ZSTR(callable_name, UG(unicode) ? IS_UNICODE : IS_STRING, (*fptr_ptr)->common.function_name, 1);
+					zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */
+
+					if (UG(unicode)) {
+						Z_TYPE_P(callable_name) = IS_UNICODE;
+						Z_USTRLEN_P(callable_name) = ce->name_length + sizeof("::__invoke") - 1;
+						Z_USTRVAL_P(callable_name) = eumalloc(Z_USTRLEN_P(callable_name)+1);
+						u_memcpy(Z_USTRVAL_P(callable_name), ce->name.u, ce->name_length);
+						u_charsToUChars("::__invoke", Z_USTRVAL_P(callable_name) + ce->name_length, sizeof("::__invoke"));
+					} else {
+						Z_TYPE_P(callable_name) = IS_STRING;
+						Z_STRLEN_P(callable_name) = ce->name_length + sizeof("::__invoke") - 1;
+						Z_STRVAL_P(callable_name) = emalloc(Z_STRLEN_P(callable_name) + 1);
+						memcpy(Z_STRVAL_P(callable_name), ce->name.s, ce->name_length);
+						memcpy(Z_STRVAL_P(callable_name) + ce->name_length, "::__invoke", sizeof("::__invoke"));
+					}
 				}
 				return 1;
 			}
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_closures.c?r1=1.3&r2=1.4&diff_format=u
Index: ZendEngine2/zend_closures.c
diff -u ZendEngine2/zend_closures.c:1.3 ZendEngine2/zend_closures.c:1.4
--- ZendEngine2/zend_closures.c:1.3	Thu Jul 10 07:55:48 2008
+++ ZendEngine2/zend_closures.c	Mon Jul 14 12:17:16 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_closures.c,v 1.3 2008/07/10 07:55:48 dmitry Exp $ */
+/* $Id: zend_closures.c,v 1.4 2008/07/14 12:17:16 dmitry Exp $ */
 
 #include "zend.h"
 #include "zend_API.h"
@@ -70,6 +70,12 @@
 }
 /* }}} */
 
+const static zend_function_entry closure_functions[] = { /* {{{ */
+	ZEND_ME(Closure, __invoke, NULL, 0)
+	{NULL, NULL, NULL}
+};
+/* }}} */
+
 static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */
 {
 	zend_error(E_ERROR, "Instantiation of 'Closure' is not allowed");
@@ -193,7 +199,7 @@
 {
 	zend_class_entry ce;
 
-	INIT_CLASS_ENTRY(ce, "Closure", NULL);
+	INIT_CLASS_ENTRY(ce, "Closure", closure_functions);
 	zend_ce_closure = zend_register_internal_class(&ce TSRMLS_CC);
 	zend_ce_closure->ce_flags |= ZEND_ACC_FINAL_CLASS;
 	zend_ce_closure->create_object = zend_closure_new;
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.828&r2=1.829&diff_format=u
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.828 ZendEngine2/zend_compile.c:1.829
--- ZendEngine2/zend_compile.c:1.828	Tue Jul  8 07:05:03 2008
+++ ZendEngine2/zend_compile.c	Mon Jul 14 12:17:16 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_compile.c,v 1.828 2008/07/08 07:05:03 dmitry Exp $ */
+/* $Id: zend_compile.c,v 1.829 2008/07/14 12:17:16 dmitry Exp $ */
 
 #include <zend_language_parser.h>
 #include "zend.h"
@@ -1482,7 +1482,7 @@
 	zend_op       *current_op;
 
 	function_name.op_type = IS_CONST;
-	ZVAL_ASCII_STRING(&function_name.u.constant, "lambda", ZSTR_DUPLICATE);
+	ZVAL_ASCII_STRING(&function_name.u.constant, "", ZSTR_DUPLICATE);
 
 	zend_do_begin_function_declaration(function_token, &function_name, 0, return_reference, NULL TSRMLS_CC);
 

http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/closure_016.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/closure_016.phpt
+++ ZendEngine2/tests/closure_016.phpt
--TEST--
Closure 016: closures and is_callable()
--FILE--
<?php
class Foo {
	function __invoke() {
		echo "Hello World!\n";
	}
}

function foo() {
	return function() {
		echo "Hello World!\n";
	};
}
$test = new Foo;
var_dump(is_callable($test, true, $name));
echo $name."\n";
var_dump(is_callable($test, false, $name));
echo $name."\n";
var_dump(is_callable(array($test,"__invoke"), true, $name));
echo $name."\n";
var_dump(is_callable(array($test,"__invoke"), false, $name));
echo $name."\n";
$test = foo();
var_dump(is_callable($test, true, $name));
echo $name."\n";
var_dump(is_callable($test, false, $name));
echo $name."\n";
var_dump(is_callable(array($test,"__invoke"), true, $name));
echo $name."\n";
var_dump(is_callable(array($test,"__invoke"), false, $name));
echo $name."\n";
?>
--EXPECT--
bool(true)
Foo::__invoke
bool(true)
Foo::__invoke
bool(true)
Foo::__invoke
bool(true)
Foo::__invoke
bool(true)
Closure::__invoke
bool(true)
Closure::__invoke
bool(true)
Closure::__invoke
bool(true)
Closure::__invoke



-- 
Zend Engine CVS Mailing List (http://cvs.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
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.