Commit 7eef7c9a9a8 for php.net
commit 7eef7c9a9a813c8f0768108ee6321130aeecec10
Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>
Date: Thu Jul 2 12:45:04 2026 -0700
Reflection: access common function fields through `zend_function.common`
The `zend_function` union has both an `op_array` member for userland code, and
an `internal_function` member for internal code. The elements at the start of
each match, and are also made available under the `common` member which only
has the fields present in both `op_array` and `internal_function`.
For function pointers that have not been checked to determine if they are
userland functions or internal functions, access common fields through
`common`. While technically there shouldn't be a difference due to the common
layout (up through the relevant fields), semantically accessing information
about an internal function through `op_array` or about a userland function
through `internal_function` does not make sense.
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 2c7690d1fe6..0a670c856eb 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -193,12 +193,12 @@ static inline bool is_closure_invoke(const zend_class_entry *ce, const zend_stri
static zend_function *_copy_function(zend_function *fptr) /* {{{ */
{
if (fptr
- && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
+ && (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
{
zend_function *copy_fptr;
copy_fptr = emalloc(sizeof(zend_function));
memcpy(copy_fptr, fptr, sizeof(zend_function));
- copy_fptr->internal_function.function_name = zend_string_copy(fptr->internal_function.function_name);
+ copy_fptr->common.function_name = zend_string_copy(fptr->common.function_name);
return copy_fptr;
} else {
/* no copy needed */
@@ -210,9 +210,9 @@ static zend_function *_copy_function(zend_function *fptr) /* {{{ */
static void _free_function(zend_function *fptr) /* {{{ */
{
if (fptr
- && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
+ && (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
{
- zend_string_release_ex(fptr->internal_function.function_name, false);
+ zend_string_release_ex(fptr->common.function_name, false);
zend_free_trampoline(fptr);
}
}
@@ -930,7 +930,7 @@ static void _function_string(smart_str *str, const zend_function *fptr, const ze
smart_str_appends(str, "function ");
}
- if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ if (fptr->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
smart_str_appendc(str, '&');
}
smart_str_append_printf(str, "%s ] {\n", ZSTR_VAL(fptr->common.function_name));
@@ -948,7 +948,7 @@ static void _function_string(smart_str *str, const zend_function *fptr, const ze
}
_function_parameter_string(str, fptr, ZSTR_VAL(param_indent.s));
smart_str_free(¶m_indent);
- if ((fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
+ if ((fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
smart_str_append_printf(str, " %s- %s [ ", indent, ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]) ? "Tentative return" : "Return");
if (ZEND_TYPE_IS_SET(fptr->common.arg_info[-1].type)) {
zend_string *type_str = zend_type_to_string(fptr->common.arg_info[-1].type);
@@ -2160,7 +2160,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, returnsReference)
GET_REFLECTION_OBJECT_PTR(fptr);
- RETURN_BOOL((fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0);
+ RETURN_BOOL((fptr->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0);
}
/* }}} */
@@ -2392,8 +2392,8 @@ ZEND_METHOD(ReflectionGenerator, getFunction)
zval closure;
ZVAL_OBJ(&closure, ZEND_CLOSURE_OBJECT(func));
reflection_function_factory(func, &closure, return_value);
- } else if (func->op_array.scope) {
- reflection_method_factory(func->op_array.scope, func, NULL, return_value);
+ } else if (func->common.scope) {
+ reflection_method_factory(func->common.scope, func, NULL, return_value);
} else {
reflection_function_factory(func, NULL, return_value);
}
@@ -3650,7 +3650,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, hasReturnType)
GET_REFLECTION_OBJECT_PTR(fptr);
- RETVAL_BOOL((fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]));
+ RETVAL_BOOL((fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]));
}
/* }}} */
@@ -3664,7 +3664,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getReturnType)
GET_REFLECTION_OBJECT_PTR(fptr);
- if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) {
+ if (!(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) {
RETURN_NULL();
}
@@ -3682,7 +3682,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, hasTentativeReturnType)
GET_REFLECTION_OBJECT_PTR(fptr);
- RETVAL_BOOL(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]));
+ RETVAL_BOOL(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]));
}
/* }}} */
@@ -3696,7 +3696,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getTentativeReturnType)
GET_REFLECTION_OBJECT_PTR(fptr);
- if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) {
+ if (!(fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) {
RETURN_NULL();
}