id()()('var_dump')(4);
id(['udef', 'id'])[1]()('var_dump')(5);
-// (id((object) ['a' => 'id', 'b' => 'udef'])->a)();
+(id((object) ['a' => 'id', 'b' => 'udef'])->a)()()()()('var_dump')(6);
+
+$id = function($x) { return $x; };
+
+$id($id)('var_dump')(7);
+
+(function($x) { return $x; })('id')('var_dump')(8);
+
+($f = function($x = null) use (&$f) {
+ return $x ?: $f;
+})()()()('var_dump')(9);
?>
--EXPECT--
int(3)
int(4)
int(5)
+int(6)
+int(7)
+int(8)
+int(9)
function_call_parameter_list { zend_do_end_function_call(NULL, &$$, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { fetch_simple_variable_ex(&$$, &$3, 0, ZEND_FETCH_R TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$$ TSRMLS_CC); }
function_call_parameter_list { zend_do_end_function_call(NULL, &$$, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | directly_callable_variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
+ | callable_expr { zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
function_call_parameter_list { zend_do_end_function_call(&$1, &$$, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
;
| dereferencable_scalar { $$ = $1; zend_do_begin_variable_parse(TSRMLS_C); }
;
-directly_callable_variable:
+callable_expr:
+ callable_variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); $$ = $1; }
+ | '(' expr ')' { $$ = $2; }
+ | dereferencable_scalar { $$ = $1; }
+;
+
+callable_variable:
simple_variable
{ zend_do_begin_variable_parse(TSRMLS_C);
fetch_simple_variable(&$$, &$1, 1 TSRMLS_CC);
;
variable:
- directly_callable_variable { $$ = $1; }
+ callable_variable { $$ = $1; }
| static_member { $$ = $1; $$.EA = ZEND_PARSED_STATIC_MEMBER; }
| dereferencable T_OBJECT_OPERATOR object_member
{ zend_do_fetch_property(&$$, &$1, &$3 TSRMLS_CC); $$.EA = ZEND_PARSED_MEMBER; }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
- } else if (OP2_TYPE != IS_CONST && OP2_TYPE != IS_TMP_VAR &&
+ } else if (OP2_TYPE != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
call->fbc->common.prototype = (zend_function*)function_name_ptr;
- } else {
+ } else if (OP2_TYPE == IS_CV) {
FREE_OP2();
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
- } else if (IS_CONST != IS_CONST && IS_CONST != IS_TMP_VAR &&
+ } else if (IS_CONST != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
call->fbc->common.prototype = (zend_function*)function_name_ptr;
- } else {
+ } else if (IS_CONST == IS_CV) {
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
- } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_TMP_VAR &&
+ } else if (IS_TMP_VAR != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
call->fbc->common.prototype = (zend_function*)function_name_ptr;
- } else {
+ } else if (IS_TMP_VAR == IS_CV) {
zval_dtor(free_op2.var);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
- } else if (IS_VAR != IS_CONST && IS_VAR != IS_TMP_VAR &&
+ } else if (IS_VAR != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
call->fbc->common.prototype = (zend_function*)function_name_ptr;
- } else {
+ } else if (IS_VAR == IS_CV) {
zval_ptr_dtor_nogc(free_op2.var);
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
- } else if (IS_CV != IS_CONST && IS_CV != IS_TMP_VAR &&
+ } else if (IS_CV != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
call->fbc->common.prototype = (zend_function*)function_name_ptr;
- } else {
+ } else if (IS_CV == IS_CV) {
}