Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES
stored instead.
. The zend_active_function{_ex}() functions now return a const zend_function
pointer.
. The zend_get_call_trampoline_func() API now takes the __call or
__callStatic zend_function* instead of a CE and a boolean argument.

========================
2. Build system changes
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -3951,7 +3951,7 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, const
get_function_via_handler:
if (fcc->object && fcc->calling_scope == ce_org) {
if (strict_class && ce_org->__call) {
fcc->function_handler = zend_get_call_trampoline_func(ce_org, mname, 0);
fcc->function_handler = zend_get_call_trampoline_func(ce_org->__call, mname);
call_via_handler = 1;
retval = true;
} else {
Expand Down
33 changes: 8 additions & 25 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1674,19 +1674,17 @@ ZEND_API bool zend_check_protected(const zend_class_entry *ce, const zend_class_
}
/* }}} */

ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce, zend_string *method_name, bool is_static) /* {{{ */
ZEND_API ZEND_ATTRIBUTE_NONNULL zend_function *zend_get_call_trampoline_func(
const zend_function *fbc, zend_string *method_name) /* {{{ */
{
size_t mname_len;
zend_op_array *func;
zend_function *fbc = is_static ? ce->__callstatic : ce->__call;
/* We use non-NULL value to avoid useless run_time_cache allocation.
* The low bit must be zero, to not be interpreted as a MAP_PTR offset.
*/
static const void *dummy = (void*)(intptr_t)2;
static const zend_arg_info arg_info[1] = {{0}};

ZEND_ASSERT(fbc);

if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
func = &EG(trampoline).op_array;
} else {
Expand All @@ -1700,13 +1698,10 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce
func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE
| ZEND_ACC_PUBLIC
| ZEND_ACC_VARIADIC
| (fbc->common.fn_flags & (ZEND_ACC_RETURN_REFERENCE|ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_NODISCARD));
| (fbc->common.fn_flags & (ZEND_ACC_RETURN_REFERENCE|ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_NODISCARD|ZEND_ACC_STATIC));
func->fn_flags2 = 0;
/* Attributes outlive the trampoline because they are created by the compiler. */
func->attributes = fbc->common.attributes;
if (is_static) {
func->fn_flags |= ZEND_ACC_STATIC;
}
func->opcodes = &EG(call_trampoline_op);
ZEND_MAP_PTR_INIT(func->run_time_cache, (void**)dummy);
func->scope = fbc->common.scope;
Expand Down Expand Up @@ -1828,12 +1823,6 @@ ZEND_API zend_function *zend_get_property_hook_trampoline(
return func;
}

static zend_always_inline zend_function *zend_get_user_call_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
{
return zend_get_call_trampoline_func(ce, method_name, false);
}
/* }}} */

ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(const zend_function *fbc, const zend_string *method_name, const zend_class_entry *scope) /* {{{ */
{
zend_throw_error(NULL, "Call to %s method %s::%s() from %s%s",
Expand Down Expand Up @@ -1875,7 +1864,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
ZSTR_ALLOCA_FREE(lc_method_name, use_heap);
}
if (zobj->ce->__call) {
return zend_get_user_call_function(zobj->ce, method_name);
return zend_get_call_trampoline_func(zobj->ce->__call, method_name);
} else {
return NULL;
}
Expand All @@ -1901,7 +1890,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
if (zobj->ce->__call) {
fbc = zend_get_user_call_function(zobj->ce, method_name);
fbc = zend_get_call_trampoline_func(zobj->ce->__call, method_name);
} else {
zend_bad_method_call(fbc, method_name, scope);
fbc = NULL;
Expand All @@ -1922,14 +1911,8 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
}
/* }}} */

static zend_always_inline zend_function *zend_get_user_callstatic_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
{
return zend_get_call_trampoline_func(ce, method_name, true);
}
/* }}} */

static zend_always_inline zend_function *get_static_method_fallback(
zend_class_entry *ce, zend_string *function_name)
const zend_class_entry *ce, zend_string *function_name)
{
zend_object *object;
if (ce->__call &&
Expand All @@ -1939,9 +1922,9 @@ static zend_always_inline zend_function *get_static_method_fallback(
* see: tests/classes/__call_004.phpt */

ZEND_ASSERT(object->ce->__call);
return zend_get_user_call_function(object->ce, function_name);
return zend_get_call_trampoline_func(object->ce->__call, function_name);
} else if (ce->__callstatic) {
return zend_get_user_callstatic_function(ce, function_name);
return zend_get_call_trampoline_func(ce->__callstatic, function_name);
} else {
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_object_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ ZEND_API bool zend_check_protected(const zend_class_entry *ce, const zend_class_

ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_string *prop_info_name, bool is_dynamic);

ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce, zend_string *method_name, bool is_static);
ZEND_API ZEND_ATTRIBUTE_NONNULL zend_function *zend_get_call_trampoline_func(const zend_function *fbc, zend_string *method_name);

ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *member);

Expand Down
Loading