summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-06-09 10:09:48 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-06-09 10:10:58 +0200
commitbe540b35d295b09e0a3f474775b13d23c8ba0243 (patch)
tree451d762d4615638c1e6ae2838a31ad6a59688733
parent596561009c8d7208db1b6506b68d92eefb11e6a2 (diff)
downloadphp-git-be540b35d295b09e0a3f474775b13d23c8ba0243.tar.gz
Remove some special-casing in zend_call_method()
Don't treat the !fn_proxy && !obj_ce case differently. There doesn't seem to be any need for it, and it will result in subtly different behavior (e.g. it will accept "Foo::bar" syntax, but break as soon as you pass in an fn_proxy cache).
-rw-r--r--Zend/zend_interfaces.c80
1 files changed, 36 insertions, 44 deletions
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index 8fffde76ff..6ad81c0805 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -36,6 +36,7 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
{
int result;
zend_fcall_info fci;
+ zend_fcall_info_cache fcic;
zval retval;
zval params[2];
@@ -52,58 +53,49 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
fci.param_count = param_count;
fci.params = params;
fci.no_separation = 1;
+ ZVAL_UNDEF(&fci.function_name); /* Unused */
- if (!fn_proxy && !obj_ce) {
- /* no interest in caching and no information already present that is
- * needed later inside zend_call_function. */
- ZVAL_STRINGL(&fci.function_name, function_name, function_name_len);
- result = zend_call_function(&fci, NULL);
- zval_ptr_dtor(&fci.function_name);
- } else {
- zend_fcall_info_cache fcic;
- ZVAL_UNDEF(&fci.function_name); /* Unused */
-
- if (!obj_ce) {
- obj_ce = object ? object->ce : NULL;
- }
- if (!fn_proxy || !*fn_proxy) {
- if (EXPECTED(obj_ce)) {
- fcic.function_handler = zend_hash_str_find_ptr(
- &obj_ce->function_table, function_name, function_name_len);
- if (UNEXPECTED(fcic.function_handler == NULL)) {
- /* error at c-level */
- zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name);
- }
- } else {
- fcic.function_handler = zend_fetch_function_str(function_name, function_name_len);
- if (UNEXPECTED(fcic.function_handler == NULL)) {
- /* error at c-level */
- zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name);
- }
- }
- if (fn_proxy) {
- *fn_proxy = fcic.function_handler;
+ if (!obj_ce) {
+ obj_ce = object ? object->ce : NULL;
+ }
+ if (!fn_proxy || !*fn_proxy) {
+ if (EXPECTED(obj_ce)) {
+ fcic.function_handler = zend_hash_str_find_ptr(
+ &obj_ce->function_table, function_name, function_name_len);
+ if (UNEXPECTED(fcic.function_handler == NULL)) {
+ /* error at c-level */
+ zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name);
}
} else {
- fcic.function_handler = *fn_proxy;
+ fcic.function_handler = zend_fetch_function_str(function_name, function_name_len);
+ if (UNEXPECTED(fcic.function_handler == NULL)) {
+ /* error at c-level */
+ zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name);
+ }
}
+ if (fn_proxy) {
+ *fn_proxy = fcic.function_handler;
+ }
+ } else {
+ fcic.function_handler = *fn_proxy;
+ }
- if (object) {
- fcic.called_scope = object->ce;
+ if (object) {
+ fcic.called_scope = object->ce;
+ } else {
+ zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
+
+ if (obj_ce &&
+ (!called_scope ||
+ !instanceof_function(called_scope, obj_ce))) {
+ fcic.called_scope = obj_ce;
} else {
- zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
-
- if (obj_ce &&
- (!called_scope ||
- !instanceof_function(called_scope, obj_ce))) {
- fcic.called_scope = obj_ce;
- } else {
- fcic.called_scope = called_scope;
- }
+ fcic.called_scope = called_scope;
}
- fcic.object = object;
- result = zend_call_function(&fci, &fcic);
}
+ fcic.object = object;
+ result = zend_call_function(&fci, &fcic);
+
if (result == FAILURE) {
/* error at c-level */
if (!obj_ce) {