summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-02-24 22:29:47 +0300
committerDmitry Stogov <dmitry@zend.com>2015-02-24 22:29:47 +0300
commitdcb96c2e037e5198932385b573baea9a9dbf3252 (patch)
treeb86aea3224a3db57fcd9f80b813122f7025aa001
parentbdf1430eeba10d444274642572b9e1ac84013080 (diff)
downloadphp-git-dcb96c2e037e5198932385b573baea9a9dbf3252.tar.gz
Split INIT_FCALL_BY_NAME inti INIT_FCALL_BY_NAME(CONST+STRING) and INIT_DYNAMIC_CALL(CONST-STRING|TMPVAR|CV)
-rw-r--r--Zend/zend_compile.c5
-rw-r--r--Zend/zend_vm_def.h244
-rw-r--r--Zend/zend_vm_execute.h754
-rw-r--r--Zend/zend_vm_opcodes.c2
-rw-r--r--Zend/zend_vm_opcodes.h1
-rw-r--r--ext/opcache/Optimizer/compact_literals.c4
-rw-r--r--ext/opcache/Optimizer/optimize_func_calls.c1
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c7
8 files changed, 493 insertions, 525 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index e7177c7cd0..f22f1c67b7 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2672,16 +2672,17 @@ void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) /
void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
{
zend_op *opline = get_next_op(CG(active_op_array));
- opline->opcode = ZEND_INIT_FCALL_BY_NAME;
- SET_UNUSED(opline->op1);
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);
} else {
+ opline->opcode = ZEND_INIT_DYNAMIC_CALL;
SET_NODE(opline->op2, name_node);
}
+ SET_UNUSED(opline->op1);
zend_compile_call_common(result, args_ast, NULL);
}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index ed7814d8b8..c6372ea557 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2347,6 +2347,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -2534,155 +2535,154 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMPVAR|CV)
+ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST)
{
USE_OPLINE
zend_function *fbc;
zval *function_name, *func;
- if (OP2_TYPE == IS_CONST) {
- if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
- fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ } else {
+ function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
+ if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
+ SAVE_OPLINE();
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
} else {
- if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) {
- goto init_fcall_complex;
- }
- function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
- SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
- } else {
- fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
- }
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
}
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, NULL, NULL, EX(call));
+ }
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+ fbc, opline->extended_value, NULL, NULL, EX(call));
- /*CHECK_EXCEPTION();*/
- ZEND_VM_NEXT_OPCODE();
- } else {
- zend_string *lcname;
- zend_free_op free_op2;
- zend_class_entry *called_scope;
- zend_object *object;
+ /*CHECK_EXCEPTION();*/
+ ZEND_VM_NEXT_OPCODE();
+}
-init_fcall_complex:
- SAVE_OPLINE();
- function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV)
+{
+ USE_OPLINE
+ zend_function *fbc;
+ zval *function_name, *func;
+ zend_string *lcname;
+ zend_free_op free_op2;
+ zend_class_entry *called_scope;
+ zend_object *object;
+
+ SAVE_OPLINE();
+ function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
ZEND_VM_C_LABEL(try_function_name):
- if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
- if (Z_STRVAL_P(function_name)[0] == '\\') {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
- } else {
- lcname = zend_string_tolower(Z_STR_P(function_name));
- }
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
- }
- zend_string_release(lcname);
+ if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+ if (Z_STRVAL_P(function_name)[0] == '\\') {
+ lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
+ zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
+ } else {
+ lcname = zend_string_tolower(Z_STR_P(function_name));
+ }
+ if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
+ }
+ zend_string_release(lcname);
+ FREE_OP2();
+
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
+ } 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, &called_scope, &fbc, &object) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ if (OP2_TYPE == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
+ /* Delay closure destruction until its invocation */
+ fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
+ } else if (OP2_TYPE == IS_CV) {
FREE_OP2();
+ }
+ } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
+ zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
+ zval *obj;
+ zval *method;
+ obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
+ method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
- fbc = Z_FUNC_P(func);
- called_scope = NULL;
- object = NULL;
- } 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, &called_scope, &fbc, &object) == SUCCESS) {
- if (object) {
- GC_REFCOUNT(object)++;
- }
- if (OP2_TYPE == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
- /* Delay closure destruction until its invocation */
- fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
- } else if (OP2_TYPE == IS_CV) {
- FREE_OP2();
- }
- } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
- zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
- zval *obj;
- zval *method;
+ if (!obj || !method) {
+ zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
+ }
- obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
- method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
+ ZVAL_DEREF(obj);
+ if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
+ zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
+ }
- if (!obj || !method) {
- zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
- }
+ ZVAL_DEREF(method);
+ if (Z_TYPE_P(method) != IS_STRING) {
+ zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ }
- ZVAL_DEREF(obj);
- if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
- zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
+ if (Z_TYPE_P(obj) == IS_STRING) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
+ if (UNEXPECTED(called_scope == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- ZVAL_DEREF(method);
- if (Z_TYPE_P(method) != IS_STRING) {
- zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
+ } else {
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
}
-
- if (Z_TYPE_P(obj) == IS_STRING) {
- object = NULL;
- called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
- if (UNEXPECTED(called_scope == NULL)) {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
-
- if (called_scope->get_static_method) {
- fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
- } else {
- fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
- }
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
- }
- if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
- if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT,
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
+ }
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT,
"Non-static method %s::%s() should not be called statically",
fbc->common.scope->name->val, fbc->common.function_name->val);
- } else {
- zend_error_noreturn(
- E_ERROR,
- "Non-static method %s::%s() cannot be called statically",
- fbc->common.scope->name->val, fbc->common.function_name->val);
- }
- }
- } else {
- called_scope = Z_OBJCE_P(obj);
- object = Z_OBJ_P(obj);
-
- fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
- }
-
- if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- object = NULL;
} else {
- GC_REFCOUNT(object)++; /* For $this pointer */
+ zend_error_noreturn(
+ E_ERROR,
+ "Non-static method %s::%s() cannot be called statically",
+ fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- FREE_OP2();
- } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
- function_name = Z_REFVAL_P(function_name);
- ZEND_VM_C_GOTO(try_function_name);
} else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
+
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
}
- zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_CONTINUE(); /* Never reached */
- }
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, called_scope, object, EX(call));
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
+ } else {
+ GC_REFCOUNT(object)++; /* For $this pointer */
+ }
+ }
+ FREE_OP2();
+ } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
+ function_name = Z_REFVAL_P(function_name);
+ ZEND_VM_C_GOTO(try_function_name);
+ } else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+ fbc, opline->extended_value, called_scope, object, EX(call));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)
@@ -5970,6 +5970,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
case ZEND_INIT_FCALL:
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
+ case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_CALL:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
@@ -6015,6 +6016,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
case ZEND_INIT_FCALL:
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
+ case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_CALL:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 31462bc07c..cc1df6ab90 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1260,6 +1260,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
case ZEND_INIT_FCALL:
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
+ case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_CALL:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
@@ -1305,6 +1306,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
case ZEND_INIT_FCALL:
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
+ case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_CALL:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
@@ -1559,148 +1561,147 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
zend_function *fbc;
zval *function_name, *func;
- if (IS_CONST == IS_CONST) {
- if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
- fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
+ fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ } else {
+ function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
+ if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
+ SAVE_OPLINE();
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
} else {
- if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) {
- goto init_fcall_complex;
- }
- function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
- SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
- } else {
- fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
- }
+ fbc = Z_FUNC_P(func);
+ CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
}
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, NULL, NULL, EX(call));
+ }
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+ fbc, opline->extended_value, NULL, NULL, EX(call));
- /*CHECK_EXCEPTION();*/
- ZEND_VM_NEXT_OPCODE();
- } else {
- zend_string *lcname;
- zend_free_op free_op2;
- zend_class_entry *called_scope;
- zend_object *object;
+ /*CHECK_EXCEPTION();*/
+ ZEND_VM_NEXT_OPCODE();
+}
-init_fcall_complex:
- SAVE_OPLINE();
- function_name = EX_CONSTANT(opline->op2);
+static int ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_function *fbc;
+ zval *function_name, *func;
+ zend_string *lcname;
+ zend_free_op free_op2;
+ zend_class_entry *called_scope;
+ zend_object *object;
+
+ SAVE_OPLINE();
+ function_name = EX_CONSTANT(opline->op2);
try_function_name:
- if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
- if (Z_STRVAL_P(function_name)[0] == '\\') {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
- } else {
- lcname = zend_string_tolower(Z_STR_P(function_name));
- }
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
- }
- zend_string_release(lcname);
+ if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+ if (Z_STRVAL_P(function_name)[0] == '\\') {
+ lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
+ zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
+ } else {
+ lcname = zend_string_tolower(Z_STR_P(function_name));
+ }
+ if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
+ }
+ zend_string_release(lcname);
- fbc = Z_FUNC_P(func);
- called_scope = NULL;
- object = NULL;
- } 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, &called_scope, &fbc, &object) == SUCCESS) {
- if (object) {
- GC_REFCOUNT(object)++;
- }
- if (IS_CONST == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
- /* Delay closure destruction until its invocation */
- fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
- } else if (IS_CONST == IS_CV) {
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
+ } 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, &called_scope, &fbc, &object) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ if (IS_CONST == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
+ /* Delay closure destruction until its invocation */
+ fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
+ } else if (IS_CONST == IS_CV) {
- }
- } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
- zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
- zval *obj;
- zval *method;
+ }
+ } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
+ zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
+ zval *obj;
+ zval *method;
+ obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
+ method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
- obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
- method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
+ if (!obj || !method) {
+ zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
+ }
- if (!obj || !method) {
- zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
- }
+ ZVAL_DEREF(obj);
+ if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
+ zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
+ }
- ZVAL_DEREF(obj);
- if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
- zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
- }
+ ZVAL_DEREF(method);
+ if (Z_TYPE_P(method) != IS_STRING) {
+ zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ }
- ZVAL_DEREF(method);
- if (Z_TYPE_P(method) != IS_STRING) {
- zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ if (Z_TYPE_P(obj) == IS_STRING) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
+ if (UNEXPECTED(called_scope == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- if (Z_TYPE_P(obj) == IS_STRING) {
- object = NULL;
- called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
- if (UNEXPECTED(called_scope == NULL)) {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
-
- if (called_scope->get_static_method) {
- fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
- } else {
- fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
- }
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
- }
- if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
- if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT,
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
+ } else {
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
+ }
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
+ }
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT,
"Non-static method %s::%s() should not be called statically",
fbc->common.scope->name->val, fbc->common.function_name->val);
- } else {
- zend_error_noreturn(
- E_ERROR,
- "Non-static method %s::%s() cannot be called statically",
- fbc->common.scope->name->val, fbc->common.function_name->val);
- }
- }
- } else {
- called_scope = Z_OBJCE_P(obj);
- object = Z_OBJ_P(obj);
-
- fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
- }
-
- if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- object = NULL;
} else {
- GC_REFCOUNT(object)++; /* For $this pointer */
+ zend_error_noreturn(
+ E_ERROR,
+ "Non-static method %s::%s() cannot be called statically",
+ fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
-
- } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
- function_name = Z_REFVAL_P(function_name);
- goto try_function_name;
} else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
+
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
+ }
+
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
+ } else {
+ GC_REFCOUNT(object)++; /* For $this pointer */
}
- zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_CONTINUE(); /* Never reached */
}
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, called_scope, object, EX(call));
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
+ function_name = Z_REFVAL_P(function_name);
+ goto try_function_name;
+ } else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+ fbc, opline->extended_value, called_scope, object, EX(call));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1949,154 +1950,128 @@ try_class_name:
}
}
-static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static int ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_function *fbc;
zval *function_name, *func;
+ zend_string *lcname;
+ zend_free_op free_op2;
+ zend_class_entry *called_scope;
+ zend_object *object;
+
+ SAVE_OPLINE();
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
- if (IS_CV == IS_CONST) {
- if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
- fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+try_function_name:
+ if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+ if (Z_STRVAL_P(function_name)[0] == '\\') {
+ lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
+ zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
} else {
- if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) {
- goto init_fcall_complex;
- }
- function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
- SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
- } else {
- fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
- }
+ lcname = zend_string_tolower(Z_STR_P(function_name));
}
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, NULL, NULL, EX(call));
-
- /*CHECK_EXCEPTION();*/
- ZEND_VM_NEXT_OPCODE();
- } else {
- zend_string *lcname;
- zend_free_op free_op2;
- zend_class_entry *called_scope;
- zend_object *object;
+ if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
+ }
+ zend_string_release(lcname);
-init_fcall_complex:
- SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
+ } 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, &called_scope, &fbc, &object) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ if (IS_CV == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
+ /* Delay closure destruction until its invocation */
+ fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
+ } else if (IS_CV == IS_CV) {
-try_function_name:
- if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
- if (Z_STRVAL_P(function_name)[0] == '\\') {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
- } else {
- lcname = zend_string_tolower(Z_STR_P(function_name));
- }
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
- }
- zend_string_release(lcname);
+ }
+ } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
+ zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
+ zval *obj;
+ zval *method;
+ obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
+ method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
- fbc = Z_FUNC_P(func);
- called_scope = NULL;
- object = NULL;
- } 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, &called_scope, &fbc, &object) == SUCCESS) {
- if (object) {
- GC_REFCOUNT(object)++;
- }
- if (IS_CV == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
- /* Delay closure destruction until its invocation */
- fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
- } else if (IS_CV == IS_CV) {
+ if (!obj || !method) {
+ zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
+ }
- }
- } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
- zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
- zval *obj;
- zval *method;
+ ZVAL_DEREF(obj);
+ if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
+ zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
+ }
- obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
- method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
+ ZVAL_DEREF(method);
+ if (Z_TYPE_P(method) != IS_STRING) {
+ zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ }
- if (!obj || !method) {
- zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
+ if (Z_TYPE_P(obj) == IS_STRING) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
+ if (UNEXPECTED(called_scope == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- ZVAL_DEREF(obj);
- if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
- zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
+ } else {
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
}
-
- ZVAL_DEREF(method);
- if (Z_TYPE_P(method) != IS_STRING) {
- zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
}
-
- if (Z_TYPE_P(obj) == IS_STRING) {
- object = NULL;
- called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
- if (UNEXPECTED(called_scope == NULL)) {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
-
- if (called_scope->get_static_method) {
- fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
- } else {
- fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
- }
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
- }
- if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
- if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT,
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT,
"Non-static method %s::%s() should not be called statically",
fbc->common.scope->name->val, fbc->common.function_name->val);
- } else {
- zend_error_noreturn(
- E_ERROR,
- "Non-static method %s::%s() cannot be called statically",
- fbc->common.scope->name->val, fbc->common.function_name->val);
- }
- }
- } else {
- called_scope = Z_OBJCE_P(obj);
- object = Z_OBJ_P(obj);
-
- fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
- }
-
- if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- object = NULL;
} else {
- GC_REFCOUNT(object)++; /* For $this pointer */
+ zend_error_noreturn(
+ E_ERROR,
+ "Non-static method %s::%s() cannot be called statically",
+ fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
-
- } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
- function_name = Z_REFVAL_P(function_name);
- goto try_function_name;
} else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
+
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
+ }
+
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
+ } else {
+ GC_REFCOUNT(object)++; /* For $this pointer */
}
- zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_CONTINUE(); /* Never reached */
}
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, called_scope, object, EX(call));
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
+ function_name = Z_REFVAL_P(function_name);
+ goto try_function_name;
+ } else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+ fbc, opline->extended_value, called_scope, object, EX(call));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -2143,155 +2118,129 @@ try_class_name:
}
}
-static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static int ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_function *fbc;
zval *function_name, *func;
+ zend_string *lcname;
+ zend_free_op free_op2;
+ zend_class_entry *called_scope;
+ zend_object *object;
- if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
- if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
- fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
+ SAVE_OPLINE();
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+
+try_function_name:
+ if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+ if (Z_STRVAL_P(function_name)[0] == '\\') {
+ lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
+ zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
} else {
- if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) {
- goto init_fcall_complex;
- }
- function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
- SAVE_OPLINE();
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
- } else {
- fbc = Z_FUNC_P(func);
- CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
- }
+ lcname = zend_string_tolower(Z_STR_P(function_name));
}
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, NULL, NULL, EX(call));
-
- /*CHECK_EXCEPTION();*/
- ZEND_VM_NEXT_OPCODE();
- } else {
- zend_string *lcname;
- zend_free_op free_op2;
- zend_class_entry *called_scope;
- zend_object *object;
-
-init_fcall_complex:
- SAVE_OPLINE();
- function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
+ }
+ zend_string_release(lcname);
+ zval_ptr_dtor_nogc(free_op2);
-try_function_name:
- if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
- if (Z_STRVAL_P(function_name)[0] == '\\') {
- lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
- zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
- } else {
- lcname = zend_string_tolower(Z_STR_P(function_name));
- }
- if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
- }
- zend_string_release(lcname);
+ fbc = Z_FUNC_P(func);
+ called_scope = NULL;
+ object = NULL;
+ } else if ((IS_TMP_VAR|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, &called_scope, &fbc, &object) == SUCCESS) {
+ if (object) {
+ GC_REFCOUNT(object)++;
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
+ /* Delay closure destruction until its invocation */
+ fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
+ } else if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
zval_ptr_dtor_nogc(free_op2);
+ }
+ } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
+ zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
+ zval *obj;
+ zval *method;
+ obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
+ method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
- fbc = Z_FUNC_P(func);
- called_scope = NULL;
- object = NULL;
- } else if ((IS_TMP_VAR|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, &called_scope, &fbc, &object) == SUCCESS) {
- if (object) {
- GC_REFCOUNT(object)++;
- }
- if ((IS_TMP_VAR|IS_VAR) == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
- /* Delay closure destruction until its invocation */
- fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
- } else if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
- zval_ptr_dtor_nogc(free_op2);
- }
- } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
- zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
- zval *obj;
- zval *method;
+ if (!obj || !method) {
+ zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
+ }
- obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
- method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
+ ZVAL_DEREF(obj);
+ if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
+ zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
+ }
- if (!obj || !method) {
- zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
- }
+ ZVAL_DEREF(method);
+ if (Z_TYPE_P(method) != IS_STRING) {
+ zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ }
- ZVAL_DEREF(obj);
- if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
- zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
+ if (Z_TYPE_P(obj) == IS_STRING) {
+ object = NULL;
+ called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
+ if (UNEXPECTED(called_scope == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- ZVAL_DEREF(method);
- if (Z_TYPE_P(method) != IS_STRING) {
- zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
+ if (called_scope->get_static_method) {
+ fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
+ } else {
+ fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
}
-
- if (Z_TYPE_P(obj) == IS_STRING) {
- object = NULL;
- called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
- if (UNEXPECTED(called_scope == NULL)) {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
-
- if (called_scope->get_static_method) {
- fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
- } else {
- fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
- }
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
- }
- if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
- if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT,
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
+ }
+ if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT,
"Non-static method %s::%s() should not be called statically",
fbc->common.scope->name->val, fbc->common.function_name->val);
- } else {
- zend_error_noreturn(
- E_ERROR,
- "Non-static method %s::%s() cannot be called statically",
- fbc->common.scope->name->val, fbc->common.function_name->val);
- }
- }
- } else {
- called_scope = Z_OBJCE_P(obj);
- object = Z_OBJ_P(obj);
-
- fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
- if (UNEXPECTED(fbc == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
- }
-
- if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- object = NULL;
} else {
- GC_REFCOUNT(object)++; /* For $this pointer */
+ zend_error_noreturn(
+ E_ERROR,
+ "Non-static method %s::%s() cannot be called statically",
+ fbc->common.scope->name->val, fbc->common.function_name->val);
}
}
- zval_ptr_dtor_nogc(free_op2);
- } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
- function_name = Z_REFVAL_P(function_name);
- goto try_function_name;
} else {
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+ called_scope = Z_OBJCE_P(obj);
+ object = Z_OBJ_P(obj);
+
+ fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
+ if (UNEXPECTED(fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
}
- zend_error_noreturn(E_ERROR, "Function name must be a string");
- ZEND_VM_CONTINUE(); /* Never reached */
- }
- EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
- fbc, opline->extended_value, called_scope, object, EX(call));
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ object = NULL;
+ } else {
+ GC_REFCOUNT(object)++; /* For $this pointer */
+ }
+ }
+ zval_ptr_dtor_nogc(free_op2);
+ } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
+ function_name = Z_REFVAL_P(function_name);
+ goto try_function_name;
+ } else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
+ zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_CONTINUE(); /* Never reached */
}
+ EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+ fbc, opline->extended_value, called_scope, object, EX(call));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -19481,6 +19430,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -21687,6 +21637,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -23077,6 +23028,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -26568,6 +26520,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -30796,6 +30749,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -32765,6 +32719,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCO
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -34437,6 +34392,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_O
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -36051,6 +36007,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCO
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -36710,6 +36667,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_
if (opline->opcode == ZEND_INIT_FCALL ||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
+ opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
opline->opcode == ZEND_INIT_METHOD_CALL ||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
opline->opcode == ZEND_INIT_USER_CALL ||
@@ -38448,30 +38406,30 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_DO_FCALL_SPEC_HANDLER,
ZEND_DO_FCALL_SPEC_HANDLER,
ZEND_DO_FCALL_SPEC_HANDLER,
@@ -40172,31 +40130,31 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
+ ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 33f67e6f4b..1ab2a9e0fa 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -150,7 +150,7 @@ const char *zend_vm_opcodes_map[171] = {
"ZEND_FE_RESET_RW",
"ZEND_FE_FETCH_RW",
"ZEND_FE_FREE",
- NULL,
+ "ZEND_INIT_DYNAMIC_CALL",
NULL,
NULL,
NULL,
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 4764e39094..d21ff08e7f 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -152,6 +152,7 @@ END_EXTERN_C()
#define ZEND_FE_RESET_RW 125
#define ZEND_FE_FETCH_RW 126
#define ZEND_FE_FREE 127
+#define ZEND_INIT_DYNAMIC_CALL 128
#define ZEND_PRE_INC_OBJ 132
#define ZEND_PRE_DEC_OBJ 133
#define ZEND_POST_INC_OBJ 134
diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c
index 3e44769cc9..1ac7265e1c 100644
--- a/ext/opcache/Optimizer/compact_literals.c
+++ b/ext/opcache/Optimizer/compact_literals.c
@@ -139,9 +139,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 1);
break;
case ZEND_INIT_FCALL_BY_NAME:
- if (ZEND_OP2_TYPE(opline) == IS_CONST) {
- LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2);
- }
+ LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2);
break;
case ZEND_INIT_NS_FCALL_BY_NAME:
LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 3);
diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c
index 78c6def625..a83adab5ec 100644
--- a/ext/opcache/Optimizer/optimize_func_calls.c
+++ b/ext/opcache/Optimizer/optimize_func_calls.c
@@ -66,6 +66,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
/* break missing intentionally */
case ZEND_NEW:
+ case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_INIT_FCALL:
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 191e13ca1d..eab51c7f66 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -180,6 +180,13 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
zend_optimizer_add_literal(op_array, val);
zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
break;
+ case ZEND_INIT_DYNAMIC_CALL:
+ opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+ Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ zend_optimizer_add_literal(op_array, val);
+ zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
+ break;
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));