summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_execute.c15
-rw-r--r--Zend/zend_execute.h1
-rw-r--r--Zend/zend_interfaces.c19
3 files changed, 29 insertions, 6 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index d29db27c34..450be1bde2 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2572,6 +2572,21 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /*
return NULL;
} /* }}} */
+ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len) /* {{{ */
+{
+ zval *zv = zend_hash_str_find(EG(function_table), name, len);
+
+ if (EXPECTED(zv != NULL)) {
+ zend_function *fbc = Z_FUNC_P(zv);
+
+ if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
+ fbc = (zend_function*)init_func_run_time_cache_i(&fbc->op_array, zv);
+ }
+ return fbc;
+ }
+ return NULL;
+} /* }}} */
+
static zend_always_inline void i_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
{
ZEND_ASSERT(EX(func) == (zend_function*)op_array);
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 08a6c78a73..c90531cb22 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -309,6 +309,7 @@ ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, con
void zend_verify_abstract_class(zend_class_entry *ce);
ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name);
+ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len);
ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type);
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index 78c9253442..11cab80633 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -67,12 +67,19 @@ ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_fun
obj_ce = object ? Z_OBJCE_P(object) : NULL;
}
if (!fn_proxy || !*fn_proxy) {
- HashTable *function_table = obj_ce ? &obj_ce->function_table : EG(function_table);
- fcic.function_handler = zend_hash_str_find_ptr(
- function_table, function_name, function_name_len);
- if (fcic.function_handler == NULL) {
- /* error at c-level */
- zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? ZSTR_VAL(obj_ce->name) : "", obj_ce ? "::" : "", function_name);
+ 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;