com php-src: Use ZEND_INIT_STATIC_METHOD_CALL for l iterals of form "classname::method": Zend/tes ts/indirect_call_from_constant.phpt Zend/zend_compi
le.c
| From: | Bob Weinand | Date: | Fri, 26 Jun 2015 17:55:13 +0000 |
| Subject: | com php-src: Use ZEND_INIT_STATIC_METHOD_CALL for l iterals of form "classname::method": Zend/tes ts/indirect_call_from_constant.phpt Zend/zend_compi le.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-87547@lists.php.net to get a copy of this message | ||
Commit: 2894bc5bb8e223e7a65492d8c0b2500e8a386351
Author: Bob Weinand <bobwei9@hotmail.com> Fri, 26 Jun 2015 19:55:13 +0200
Parents: 1d704a05eeb56339d89600ea273b17d05c52ec5b
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=2894bc5bb8e223e7a65492d8c0b2500e8a386351
Log:
Use ZEND_INIT_STATIC_METHOD_CALL for literals of form "classname::method"
Changed paths:
A Zend/tests/indirect_call_from_constant.phpt
M Zend/zend_compile.c
Diff:
diff --git a/Zend/tests/indirect_call_from_constant.phpt
b/Zend/tests/indirect_call_from_constant.phpt
new file mode 100644
index 0000000..4e7374a
--- /dev/null
+++ b/Zend/tests/indirect_call_from_constant.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Indirect call with constants.
+--FILE--
+<?php
+
+class Test
+{
+ public static function method()
+ {
+ echo "Method called!\n";
+ }
+}
+
+['Test', 'method']();
+
+'Test::method'();
+
+(['Test', 'method'])();
+
+('Test::method')();
+
+?>
+--EXPECT--
+Method called!
+Method called!
+Method called!
+Method called!
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 29018de..7a776af 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2866,16 +2866,30 @@ void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast
*args_a
{
zend_op *opline = get_next_op(CG(active_op_array));
if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
- opline->opcode = ZEND_INIT_FCALL_BY_NAME;
- opline->op2_type = IS_CONST;
- opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
- Z_STR(name_node->u.constant));
- zend_alloc_cache_slot(opline->op2.constant);
+ const char *colon;
+ zend_string *str = Z_STR(name_node->u.constant);
+ if ((colon = zend_memrchr(str->val, ':', str->len)) != NULL && colon >
str->val && *(colon - 1) == ':') {
+ zend_string *class = zend_string_init(str->val, colon - str->val - 1, 0);
+ zend_string *method = zend_string_init(colon + 1, str->len - (colon - str->val) - 1, 0);
+ opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
+ opline->op1_type = IS_CONST;
+ opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), class);
+ opline->op2_type = IS_CONST;
+ opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), method);
+ zend_alloc_cache_slot(opline->op2.constant);
+ zval_ptr_dtor(&name_node->u.constant);
+ } else {
+ opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+ SET_UNUSED(opline->op1);
+ opline->op2_type = IS_CONST;
+ opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), str);
+ zend_alloc_cache_slot(opline->op2.constant);
+ }
} else {
opline->opcode = ZEND_INIT_DYNAMIC_CALL;
+ SET_UNUSED(opline->op1);
SET_NODE(opline->op2, name_node);
}
- SET_UNUSED(opline->op1);
zend_compile_call_common(result, args_ast, NULL);
}