diff options
-rw-r--r-- | Zend/zend_execute.c | 15 | ||||
-rw-r--r-- | Zend/zend_execute.h | 1 | ||||
-rw-r--r-- | Zend/zend_interfaces.c | 19 |
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; |