diff --git a/Zend/Optimizer/compact_literals.c b/Zend/Optimizer/compact_literals.c index db973572aca3a..202cb7c2d6114 100644 --- a/Zend/Optimizer/compact_literals.c +++ b/Zend/Optimizer/compact_literals.c @@ -69,7 +69,7 @@ static size_t type_num_classes(const zend_op_array *op_array, uint32_t arg_num) } ZEND_ASSERT(ZEND_TYPE_IS_UNION(arg_info->type)); size_t count = 0; - zend_type *list_type; + const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(arg_info->type), list_type) { if (ZEND_TYPE_IS_INTERSECTION(*list_type)) { diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index 2c3aaae065997..bf85764c93b49 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -254,7 +254,7 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op free_alloca(shiftlist, use_heap); } -static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) { +static bool safe_instanceof(const zend_class_entry *ce1, const zend_class_entry *ce2) { if (ce1 == ce2) { return 1; } @@ -267,9 +267,9 @@ static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) { static inline bool can_elide_list_type( const zend_script *script, const zend_op_array *op_array, - const zend_ssa_var_info *use_info, zend_type type) + const zend_ssa_var_info *use_info, const zend_type type) { - zend_type *single_type; + const zend_type *single_type; /* For intersection: result==false is failure, default is success. * For union: result==true is success, default is failure. */ bool is_intersection = ZEND_TYPE_IS_INTERSECTION(type); @@ -280,7 +280,7 @@ static inline bool can_elide_list_type( } if (ZEND_TYPE_HAS_NAME(*single_type)) { zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(*single_type)); - zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname); + const zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname); zend_string_release(lcname); bool result = ce && safe_instanceof(use_info->ce, ce); if (result == !is_intersection) { diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 4c31fba5e506e..e0006e7d7275f 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2914,14 +2914,14 @@ static zend_always_inline void zend_normalize_internal_type(zend_type *type) { ZEND_ASSERT(!ZEND_TYPE_CONTAINS_CODE(*type, IS_RESOURCE) && "resource is not allowed in a zend_type"); } zend_type *current; - ZEND_TYPE_FOREACH(*type, current) { + ZEND_TYPE_FOREACH_MUTABLE(*type, current) { if (ZEND_TYPE_HAS_NAME(*current)) { zend_string *name = zend_new_interned_string(ZEND_TYPE_NAME(*current)); zend_alloc_ce_cache(name); ZEND_TYPE_SET_PTR(*current, name); } else if (ZEND_TYPE_HAS_LIST(*current)) { zend_type *inner; - ZEND_TYPE_FOREACH(*current, inner) { + ZEND_TYPE_FOREACH_MUTABLE(*current, inner) { ZEND_ASSERT(!ZEND_TYPE_HAS_LITERAL_NAME(*inner) && !ZEND_TYPE_HAS_LIST(*inner)); if (ZEND_TYPE_HAS_NAME(*inner)) { zend_string *name = zend_new_interned_string(ZEND_TYPE_NAME(*inner)); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2e405de30ea62..3fa4c3959cb43 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1407,10 +1407,10 @@ static zend_string *resolve_class_name(zend_string *name, zend_class_entry *scop } static zend_string *add_intersection_type(zend_string *str, - zend_type_list *intersection_type_list, zend_class_entry *scope, + const zend_type_list *intersection_type_list, zend_class_entry *scope, bool is_bracketed) { - zend_type *single_type; + const zend_type *single_type; zend_string *intersection_str = NULL; ZEND_TYPE_LIST_FOREACH(intersection_type_list, single_type) { @@ -1432,7 +1432,7 @@ static zend_string *add_intersection_type(zend_string *str, return str; } -zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scope) { +zend_string *zend_type_to_string_resolved(const zend_type type, zend_class_entry *scope) { zend_string *str = NULL; /* Pure intersection type */ @@ -1441,7 +1441,7 @@ zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scop str = add_intersection_type(str, ZEND_TYPE_LIST(type), scope, /* is_bracketed */ false); } else if (ZEND_TYPE_HAS_LIST(type)) { /* A union type might not be a list */ - zend_type *list_type; + const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) { if (ZEND_TYPE_IS_INTERSECTION(*list_type)) { str = add_intersection_type(str, ZEND_TYPE_LIST(*list_type), scope, /* is_bracketed */ true); @@ -1527,7 +1527,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type) { return zend_type_to_string_resolved(type, NULL); } -static bool is_generator_compatible_class_type(zend_string *name) { +static bool is_generator_compatible_class_type(const zend_string *name) { return zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_TRAVERSABLE)) || zend_string_equals_literal_ci(name, "Iterator") || zend_string_equals_literal_ci(name, "Generator"); @@ -1541,10 +1541,10 @@ static void zend_mark_function_as_generator(void) /* {{{ */ } if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { - zend_type return_type = CG(active_op_array)->arg_info[-1].type; + const zend_type return_type = CG(active_op_array)->arg_info[-1].type; bool valid_type = (ZEND_TYPE_FULL_MASK(return_type) & MAY_BE_OBJECT) != 0; if (!valid_type) { - zend_type *single_type; + const zend_type *single_type; ZEND_TYPE_FOREACH(return_type, single_type) { if (ZEND_TYPE_HAS_NAME(*single_type) && is_generator_compatible_class_type(ZEND_TYPE_NAME(*single_type))) { @@ -2621,7 +2621,7 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */ /* }}} */ /* Remember to update type_num_classes() in compact_literals.c when changing this function */ -static size_t zend_type_get_num_classes(zend_type type) { +static size_t zend_type_get_num_classes(const zend_type type) { if (!ZEND_TYPE_IS_COMPLEX(type)) { return 0; } @@ -2632,7 +2632,7 @@ static size_t zend_type_get_num_classes(zend_type type) { } ZEND_ASSERT(ZEND_TYPE_IS_UNION(type)); size_t count = 0; - zend_type *list_type; + const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) { if (ZEND_TYPE_IS_INTERSECTION(*list_type)) { @@ -7048,7 +7048,7 @@ static zend_type zend_compile_single_typename(zend_ast *ast) } } -static void zend_are_intersection_types_redundant(zend_type left_type, zend_type right_type) +static void zend_are_intersection_types_redundant(const zend_type left_type, const zend_type right_type) { ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(left_type)); ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(right_type)); @@ -7067,9 +7067,9 @@ static void zend_are_intersection_types_redundant(zend_type left_type, zend_type } unsigned int sum = 0; - zend_type *outer_type; + const zend_type *outer_type; ZEND_TYPE_LIST_FOREACH(smaller_type_list, outer_type) - zend_type *inner_type; + const zend_type *inner_type; ZEND_TYPE_LIST_FOREACH(larger_type_list, inner_type) if (zend_string_equals_ci(ZEND_TYPE_NAME(*inner_type), ZEND_TYPE_NAME(*outer_type))) { sum++; @@ -7098,12 +7098,12 @@ static void zend_are_intersection_types_redundant(zend_type left_type, zend_type } } -static void zend_is_intersection_type_redundant_by_single_type(zend_type intersection_type, zend_type single_type) +static void zend_is_intersection_type_redundant_by_single_type(const zend_type intersection_type, const zend_type single_type) { ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(intersection_type)); ZEND_ASSERT(!ZEND_TYPE_IS_INTERSECTION(single_type)); - zend_type *single_intersection_type = NULL; + const zend_type *single_intersection_type = NULL; ZEND_TYPE_FOREACH(intersection_type, single_intersection_type) if (zend_string_equals_ci(ZEND_TYPE_NAME(*single_intersection_type), ZEND_TYPE_NAME(single_type))) { zend_string *single_type_str = zend_type_to_string(single_type); @@ -7115,7 +7115,7 @@ static void zend_is_intersection_type_redundant_by_single_type(zend_type interse } /* Used by both intersection and union types prior to transforming the type list to a full zend_type */ -static void zend_is_type_list_redundant_by_single_type(zend_type_list *type_list, zend_type type) +static void zend_is_type_list_redundant_by_single_type(const zend_type_list *type_list, const zend_type type) { ZEND_ASSERT(!ZEND_TYPE_IS_INTERSECTION(type)); for (size_t i = 0; i < type_list->num_types - 1; i++) { diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 4fed2af3a92fd..786cd60ef1401 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -609,7 +609,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg zend_string_release(func_name); } -static zend_never_inline ZEND_COLD void zend_throw_auto_init_in_prop_error(zend_property_info *prop) { +static zend_never_inline ZEND_COLD void zend_throw_auto_init_in_prop_error(const zend_property_info *prop) { zend_string *type_str = zend_type_to_string(prop->type); zend_type_error( "Cannot auto-initialize an array inside property %s::$%s of type %s", @@ -619,7 +619,7 @@ static zend_never_inline ZEND_COLD void zend_throw_auto_init_in_prop_error(zend_ zend_string_release(type_str); } -static zend_never_inline ZEND_COLD void zend_throw_auto_init_in_ref_error(zend_property_info *prop) { +static zend_never_inline ZEND_COLD void zend_throw_auto_init_in_ref_error(const zend_property_info *prop) { zend_string *type_str = zend_type_to_string(prop->type); zend_type_error( "Cannot auto-initialize an array inside a reference held by property %s::$%s of type %s", @@ -630,7 +630,7 @@ static zend_never_inline ZEND_COLD void zend_throw_auto_init_in_ref_error(zend_p } static zend_never_inline ZEND_COLD void zend_throw_access_uninit_prop_by_ref_error( - zend_property_info *prop) { + const zend_property_info *prop) { zend_throw_error(NULL, "Cannot access uninitialized non-nullable property %s::$%s by reference", ZSTR_VAL(prop->ce->name), @@ -638,7 +638,7 @@ static zend_never_inline ZEND_COLD void zend_throw_access_uninit_prop_by_ref_err } /* this should modify object only if it's empty */ -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(const zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) { zend_string *tmp_property_name; zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); @@ -673,7 +673,7 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_erro } static ZEND_COLD void zend_verify_type_error_common( - const zend_function *zf, const zend_arg_info *arg_info, zval *value, + const zend_function *zf, const zend_arg_info *arg_info, const zval *value, const char **fname, const char **fsep, const char **fclass, zend_string **need_msg, const char **given_kind) { @@ -696,9 +696,9 @@ static ZEND_COLD void zend_verify_type_error_common( } ZEND_API ZEND_COLD void zend_verify_arg_error( - const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, zval *value) + const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value) { - zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; + const zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; const char *fname, *fsep, *fclass; zend_string *need_msg; const char *given_msg; @@ -909,7 +909,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modificati ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type) +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(const uint8_t type) { zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(type)); } @@ -975,9 +975,9 @@ static zend_always_inline const zend_class_entry *zend_ce_from_type( } static bool zend_check_intersection_for_property_or_class_constant_class_type( - const zend_class_entry *scope, zend_type_list *intersection_type_list, const zend_class_entry *value_ce) + const zend_class_entry *scope, const zend_type_list *intersection_type_list, const zend_class_entry *value_ce) { - zend_type *list_type; + const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(intersection_type_list, list_type) { ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type)); @@ -990,13 +990,13 @@ static bool zend_check_intersection_for_property_or_class_constant_class_type( } static bool zend_check_and_resolve_property_or_class_constant_class_type( - const zend_class_entry *scope, zend_type member_type, const zend_class_entry *value_ce) { + const zend_class_entry *scope, const zend_type member_type, const zend_class_entry *value_ce) { if (ZEND_TYPE_HAS_LIST(member_type)) { - zend_type *list_type; if (ZEND_TYPE_IS_INTERSECTION(member_type)) { return zend_check_intersection_for_property_or_class_constant_class_type( scope, ZEND_TYPE_LIST(member_type), value_ce); } else { + const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(member_type), list_type) { if (ZEND_TYPE_IS_INTERSECTION(*list_type)) { if (zend_check_intersection_for_property_or_class_constant_class_type( @@ -1059,7 +1059,7 @@ ZEND_API bool zend_never_inline zend_verify_property_type(const zend_property_in return i_zend_verify_property_type(info, property, strict); } -static zend_never_inline zval* zend_assign_to_typed_prop(zend_property_info *info, zval *property_val, zval *value, zend_refcounted **garbage_ptr EXECUTE_DATA_DC) +static zend_never_inline zval* zend_assign_to_typed_prop(const zend_property_info *info, zval *property_val, zval *value, zend_refcounted **garbage_ptr EXECUTE_DATA_DC) { zval tmp; @@ -1087,7 +1087,7 @@ static zend_never_inline zval* zend_assign_to_typed_prop(zend_property_info *inf return zend_assign_to_variable_ex(property_val, &tmp, IS_TMP_VAR, EX_USES_STRICT_TYPES(), garbage_ptr); } -static zend_always_inline bool zend_value_instanceof_static(zval *zv) { +static zend_always_inline bool zend_value_instanceof_static(const zval *zv) { if (Z_TYPE_P(zv) != IS_OBJECT) { return 0; } @@ -1110,7 +1110,7 @@ static zend_always_inline bool zend_value_instanceof_static(zval *zv) { #define PROGRESS_CACHE_SLOT() if (HAVE_CACHE_SLOT) {cache_slot++;} static zend_always_inline zend_class_entry *zend_fetch_ce_from_cache_slot( - void **cache_slot, zend_type *type) + void **cache_slot, const zend_type *type) { if (EXPECTED(HAVE_CACHE_SLOT && *cache_slot)) { return (zend_class_entry *) *cache_slot; @@ -1140,17 +1140,18 @@ static zend_always_inline zend_class_entry *zend_fetch_ce_from_cache_slot( return ce; } -static bool zend_check_intersection_type_from_cache_slot(zend_type_list *intersection_type_list, - zend_class_entry *arg_ce, void ***cache_slot_ptr) +static bool zend_check_intersection_type_from_cache_slot( + const zend_type_list *intersection_type_list, + const zend_class_entry *arg_ce, + void ***cache_slot_ptr) { void **cache_slot = *cache_slot_ptr; - zend_class_entry *ce; - zend_type *list_type; + const zend_type *list_type; bool status = true; ZEND_TYPE_LIST_FOREACH(intersection_type_list, list_type) { /* Only check classes if the type might be valid */ if (status) { - ce = zend_fetch_ce_from_cache_slot(cache_slot, list_type); + zend_class_entry *ce = zend_fetch_ce_from_cache_slot(cache_slot, list_type); /* If type is not an instance of one of the types taking part in the * intersection it cannot be a valid instance of the whole intersection type. */ if (!ce || !instanceof_function(arg_ce, ce)) { @@ -1166,17 +1167,16 @@ static bool zend_check_intersection_type_from_cache_slot(zend_type_list *interse } static zend_always_inline bool zend_check_type_slow( - zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, + const zend_type *type, zval *arg, const zend_reference *ref, void **cache_slot, bool is_return_type, bool is_internal) { - uint32_t type_mask; if (ZEND_TYPE_IS_COMPLEX(*type) && EXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) { zend_class_entry *ce; if (UNEXPECTED(ZEND_TYPE_HAS_LIST(*type))) { - zend_type *list_type; if (ZEND_TYPE_IS_INTERSECTION(*type)) { return zend_check_intersection_type_from_cache_slot(ZEND_TYPE_LIST(*type), Z_OBJCE_P(arg), &cache_slot); } else { + const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*type), list_type) { if (ZEND_TYPE_IS_INTERSECTION(*list_type)) { if (zend_check_intersection_type_from_cache_slot(ZEND_TYPE_LIST(*list_type), Z_OBJCE_P(arg), &cache_slot)) { @@ -1204,7 +1204,7 @@ static zend_always_inline bool zend_check_type_slow( } } - type_mask = ZEND_TYPE_FULL_MASK(*type); + const uint32_t type_mask = ZEND_TYPE_FULL_MASK(*type); if ((type_mask & MAY_BE_CALLABLE) && zend_is_callable(arg, is_internal ? IS_CALLABLE_SUPPRESS_DEPRECATIONS : 0, NULL)) { return 1; @@ -1232,10 +1232,10 @@ static zend_always_inline bool zend_check_type_slow( } static zend_always_inline bool zend_check_type( - zend_type *type, zval *arg, void **cache_slot, zend_class_entry *scope, + const zend_type *type, zval *arg, void **cache_slot, zend_class_entry *scope, bool is_return_type, bool is_internal) { - zend_reference *ref = NULL; + const zend_reference *ref = NULL; ZEND_ASSERT(ZEND_TYPE_IS_SET(*type)); if (UNEXPECTED(Z_ISREF_P(arg))) { @@ -1251,15 +1251,15 @@ static zend_always_inline bool zend_check_type( } ZEND_API bool zend_check_user_type_slow( - zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, bool is_return_type) + const zend_type *type, zval *arg, const zend_reference *ref, void **cache_slot, bool is_return_type) { return zend_check_type_slow( type, arg, ref, cache_slot, is_return_type, /* is_internal */ false); } -static zend_always_inline bool zend_verify_recv_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, void **cache_slot) +static zend_always_inline bool zend_verify_recv_arg_type(const zend_function *zf, uint32_t arg_num, zval *arg, void **cache_slot) { - zend_arg_info *cur_arg_info; + const zend_arg_info *cur_arg_info; ZEND_ASSERT(arg_num <= zf->common.num_args); cur_arg_info = &zf->common.arg_info[arg_num-1]; @@ -1274,7 +1274,7 @@ static zend_always_inline bool zend_verify_recv_arg_type(zend_function *zf, uint } static zend_always_inline bool zend_verify_variadic_arg_type( - zend_function *zf, zend_arg_info *arg_info, uint32_t arg_num, zval *arg, void **cache_slot) + const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, zval *arg, void **cache_slot) { ZEND_ASSERT(ZEND_TYPE_IS_SET(arg_info->type)); if (UNEXPECTED(!zend_check_type(&arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) { @@ -1285,7 +1285,7 @@ static zend_always_inline bool zend_verify_variadic_arg_type( return 1; } -static zend_never_inline ZEND_ATTRIBUTE_UNUSED bool zend_verify_internal_arg_types(zend_function *fbc, zend_execute_data *call) +static zend_never_inline ZEND_ATTRIBUTE_UNUSED bool zend_verify_internal_arg_types(const zend_function *fbc, zend_execute_data *call) { uint32_t i; uint32_t num_args = ZEND_CALL_NUM_ARGS(call); @@ -1314,7 +1314,7 @@ static zend_never_inline ZEND_ATTRIBUTE_UNUSED bool zend_verify_internal_arg_typ /* Determine whether an internal call should throw, because the passed arguments violate * an arginfo constraint. This is only checked in debug builds. In release builds, we * trust that arginfo matches what is enforced by zend_parse_parameters. */ -ZEND_API bool zend_internal_call_should_throw(zend_function *fbc, zend_execute_data *call) +ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_execute_data *call) { if (fbc->internal_function.handler == ZEND_FN(pass) || (fbc->internal_function.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { /* Be lenient about the special pass function and about fake closures. */ @@ -1341,7 +1341,7 @@ ZEND_API bool zend_internal_call_should_throw(zend_function *fbc, zend_execute_d return 0; } -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc) +ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc) { zend_error_noreturn(E_ERROR, "Arginfo / zpp mismatch during call of %s%s%s()", fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", @@ -1353,10 +1353,10 @@ ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc) # define ZEND_VERIFY_FUNC_INFO 0 #endif -static void zend_verify_internal_func_info(zend_function *fn, zval *retval) { +static void zend_verify_internal_func_info(const zend_function *fn, const zval *retval) { #if ZEND_VERIFY_FUNC_INFO zend_string *name = fn->common.function_name; - uint32_t type_mask = zend_get_internal_func_info(fn, NULL, NULL); + const uint32_t type_mask = zend_get_internal_func_info(fn, NULL, NULL); if (!type_mask) { return; } @@ -1371,14 +1371,14 @@ static void zend_verify_internal_func_info(zend_function *fn, zval *retval) { } } - uint32_t type = 1u << Z_TYPE_P(retval); + const uint32_t type = 1u << Z_TYPE_P(retval); if (!(type_mask & type)) { zend_error_noreturn(E_CORE_ERROR, "%s() missing type %s", ZSTR_VAL(name), zend_get_type_by_const(Z_TYPE_P(retval))); } if (Z_TYPE_P(retval) == IS_ARRAY) { - HashTable *ht = Z_ARRVAL_P(retval); + const HashTable *ht = Z_ARRVAL_P(retval); uint32_t num_checked = 0; zend_string *str; zval *val; @@ -1395,7 +1395,7 @@ static void zend_verify_internal_func_info(zend_function *fn, zval *retval) { } } - uint32_t array_type = 1u << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT); + const uint32_t array_type = 1u << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT); if (!(type_mask & array_type)) { zend_error_noreturn(E_CORE_ERROR, "%s() missing array element type %s", @@ -1412,9 +1412,9 @@ static void zend_verify_internal_func_info(zend_function *fn, zval *retval) { } #endif -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data) +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data) { - zend_execute_data *ptr = EX(prev_execute_data); + const zend_execute_data *ptr = EX(prev_execute_data); if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) { zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %s%s%s(), %d passed in %s on line %d and %s %d expected", @@ -1437,7 +1437,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data * } } -ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, zval *value) +ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1464,7 +1464,7 @@ ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf) } #if ZEND_DEBUG -static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, zval *value) +static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1496,9 +1496,9 @@ static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, con fclass, fsep, fname, returned_msg, returned_kind); } -ZEND_API bool zend_verify_internal_return_type(zend_function *zf, zval *ret) +ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *ret) { - zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1; + const zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1; if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_VOID) { if (UNEXPECTED(Z_TYPE_P(ret) != IS_NULL)) { @@ -1523,7 +1523,7 @@ static ZEND_COLD void zend_verify_missing_return_type(const zend_function *zf) zend_verify_return_error(zf, NULL); } -static zend_always_inline bool zend_check_class_constant_type(zend_class_constant *c, zval *constant) +static zend_always_inline bool zend_check_class_constant_type(const zend_class_constant *c, zval *constant) { ZEND_ASSERT(!Z_ISREF_P(constant)); if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(c->type, Z_TYPE_P(constant)))) { @@ -1540,7 +1540,7 @@ static zend_always_inline bool zend_check_class_constant_type(zend_class_constan return zend_verify_scalar_type_hint(type_mask, constant, true, false); } -ZEND_API bool zend_never_inline zend_verify_class_constant_type(zend_class_constant *c, const zend_string *name, zval *constant) +ZEND_API bool zend_never_inline zend_verify_class_constant_type(const zend_class_constant *c, const zend_string *name, zval *constant) { if (!zend_check_class_constant_type(c, constant)) { zend_verify_class_constant_type_error(c, name, constant); @@ -1709,7 +1709,7 @@ static zend_never_inline void zend_binary_assign_op_typed_ref(zend_reference *re } } -static zend_never_inline void zend_binary_assign_op_typed_prop(zend_property_info *prop_info, zval *zptr, zval *value OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_binary_assign_op_typed_prop(const zend_property_info *prop_info, zval *zptr, zval *value OPLINE_DC EXECUTE_DATA_DC) { zval z_copy; diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index e96a217a2904f..75c2d07e5e5cb 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -60,7 +60,7 @@ ZEND_API zend_result zend_eval_stringl_ex(const char *str, size_t str_len, zval /* export zend_pass_function to allow comparisons against it */ extern ZEND_API const zend_internal_function zend_pass_function; -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_nodiscard_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_class_constant *c, const zend_string *constant_name); @@ -95,23 +95,23 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_pr ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *info, const char *operation); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *prop_info, const char *operation); ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool strict, bool is_internal_arg); ZEND_API ZEND_COLD void zend_verify_arg_error( - const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, zval *value); + const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value); ZEND_API ZEND_COLD void zend_verify_return_error( - const zend_function *zf, zval *value); + const zend_function *zf, const zval *value); ZEND_API ZEND_COLD void zend_verify_never_error( const zend_function *zf); ZEND_API bool zend_verify_ref_array_assignable(zend_reference *ref); ZEND_API bool zend_check_user_type_slow( - zend_type *type, zval *arg, zend_reference *ref, void **cache_slot, bool is_return_type); + const zend_type *type, zval *arg, const zend_reference *ref, void **cache_slot, bool is_return_type); #if ZEND_DEBUG -ZEND_API bool zend_internal_call_should_throw(zend_function *fbc, zend_execute_data *call); -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc); -ZEND_API bool zend_verify_internal_return_type(zend_function *zf, zval *ret); +ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_execute_data *call); +ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc); +ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *ret); #endif #define ZEND_REF_TYPE_SOURCES(ref) \ @@ -522,7 +522,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal #define ZEND_CLASS_HAS_READONLY_PROPS(ce) ((bool)(ce->ce_flags & ZEND_ACC_HAS_READONLY_PROPS)) -ZEND_API bool zend_verify_class_constant_type(zend_class_constant *c, const zend_string *name, zval *constant); +ZEND_API bool zend_verify_class_constant_type(const zend_class_constant *c, const zend_string *name, zval *constant); ZEND_COLD void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant); ZEND_API bool zend_verify_property_type(const zend_property_info *info, zval *property, bool strict); diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 53cd8533fd3e1..090b1049418d2 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -83,7 +83,7 @@ static void zend_type_list_copy_ctor( } zend_type *list_type; - ZEND_TYPE_LIST_FOREACH(new_list, list_type) { + ZEND_TYPE_LIST_FOREACH_MUTABLE(new_list, list_type) { zend_type_copy_ctor(list_type, use_arena, persistent); } ZEND_TYPE_LIST_FOREACH_END(); } @@ -362,7 +362,7 @@ static bool unlinked_instanceof(const zend_class_entry *ce1, const zend_class_en } static bool zend_type_permits_self( - zend_type type, const zend_class_entry *scope, zend_class_entry *self) { + const zend_type type, const zend_class_entry *scope, zend_class_entry *self) { if (ZEND_TYPE_FULL_MASK(type) & MAY_BE_OBJECT) { return 1; } @@ -370,7 +370,7 @@ static bool zend_type_permits_self( /* Any types that may satisfy self must have already been loaded at this point * (as a parent or interface), so we never need to register delayed variance obligations * for this case. */ - zend_type *single_type; + const zend_type *single_type; ZEND_TYPE_FOREACH(type, single_type) { if (ZEND_TYPE_HAS_NAME(*single_type)) { zend_string *name = resolve_class_name(scope, ZEND_TYPE_NAME(*single_type)); @@ -428,12 +428,12 @@ static void track_class_dependency(zend_class_entry *ce, zend_string *class_name /* Check whether any type in the fe_type intersection type is a subtype of the proto class. */ static inheritance_status zend_is_intersection_subtype_of_class( - zend_class_entry *fe_scope, zend_type fe_type, + zend_class_entry *fe_scope, const zend_type fe_type, zend_class_entry *proto_scope, zend_string *proto_class_name, zend_class_entry *proto_ce) { ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(fe_type)); bool have_unresolved = false; - zend_type *single_type; + const zend_type *single_type; /* Traverse the list of child types and check that at least one is * a subtype of the parent type being checked */ @@ -473,7 +473,7 @@ static inheritance_status zend_is_intersection_subtype_of_class( /* Check whether a single class proto type is a subtype of a potentially complex fe_type. */ static inheritance_status zend_is_class_subtype_of_type( zend_class_entry *fe_scope, zend_string *fe_class_name, - zend_class_entry *proto_scope, zend_type proto_type) { + zend_class_entry *proto_scope, const zend_type proto_type) { zend_class_entry *fe_ce = NULL; bool have_unresolved = 0; @@ -513,7 +513,7 @@ static inheritance_status zend_is_class_subtype_of_type( } } - zend_type *single_type; + const zend_type *single_type; /* Traverse the list of parent types and check if the current child (FE) * class is the subtype of at least one of them (union) or all of them (intersection). */ @@ -584,15 +584,15 @@ static inheritance_status zend_is_class_subtype_of_type( return is_intersection ? INHERITANCE_SUCCESS : INHERITANCE_ERROR; } -static zend_string *get_class_from_type(const zend_class_entry *scope, zend_type single_type) { +static zend_string *get_class_from_type(const zend_class_entry *scope, const zend_type single_type) { if (ZEND_TYPE_HAS_NAME(single_type)) { return resolve_class_name(scope, ZEND_TYPE_NAME(single_type)); } return NULL; } -static void register_unresolved_classes(zend_class_entry *scope, zend_type type) { - zend_type *single_type; +static void register_unresolved_classes(zend_class_entry *scope, const zend_type type) { + const zend_type *single_type; ZEND_TYPE_FOREACH(type, single_type) { if (ZEND_TYPE_HAS_LIST(*single_type)) { register_unresolved_classes(scope, *single_type); @@ -606,11 +606,11 @@ static void register_unresolved_classes(zend_class_entry *scope, zend_type type) } static inheritance_status zend_is_intersection_subtype_of_type( - zend_class_entry *fe_scope, zend_type fe_type, - zend_class_entry *proto_scope, zend_type proto_type) + zend_class_entry *fe_scope, const zend_type fe_type, + zend_class_entry *proto_scope, const zend_type proto_type) { bool have_unresolved = false; - zend_type *single_type; + const zend_type *single_type; uint32_t proto_type_mask = ZEND_TYPE_PURE_MASK(proto_type); /* Currently, for object type any class name would be allowed here. @@ -672,8 +672,8 @@ static inheritance_status zend_is_intersection_subtype_of_type( } ZEND_API inheritance_status zend_perform_covariant_type_check( - zend_class_entry *fe_scope, zend_type fe_type, - zend_class_entry *proto_scope, zend_type proto_type) + zend_class_entry *fe_scope, const zend_type fe_type, + zend_class_entry *proto_scope, const zend_type proto_type) { ZEND_ASSERT(ZEND_TYPE_IS_SET(fe_type) && ZEND_TYPE_IS_SET(proto_type)); @@ -727,7 +727,7 @@ ZEND_API inheritance_status zend_perform_covariant_type_check( * We need to iterate over fe_type (U_i) first and the logic is independent of * whether proto_type is a union or intersection (only the inner check differs). */ early_exit_status = INHERITANCE_ERROR; - zend_type *single_type; + const zend_type *single_type; ZEND_TYPE_FOREACH(fe_type, single_type) { inheritance_status status; /* Union has an intersection type as it's member */ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index ce052024ae7a0..b25152ec1248b 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -112,7 +112,7 @@ ZEND_API void destroy_zend_function(zend_function *function) ZEND_API void zend_type_release(zend_type type, bool persistent) { if (ZEND_TYPE_HAS_LIST(type)) { zend_type *list_type; - ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) { + ZEND_TYPE_LIST_FOREACH_MUTABLE(ZEND_TYPE_LIST(type), list_type) { zend_type_release(*list_type, persistent); } ZEND_TYPE_LIST_FOREACH_END(); if (!ZEND_TYPE_USES_ARENA(type)) { diff --git a/Zend/zend_types.h b/Zend/zend_types.h index f839cec3b3667..7676a1d42a5f4 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -209,8 +209,14 @@ typedef struct { /* This iterates over a zend_type_list. */ #define ZEND_TYPE_LIST_FOREACH(list, type_ptr) do { \ + const zend_type *_list = (list)->types; \ + const zend_type *_end = _list + (list)->num_types; \ + for (; _list < _end; _list++) { \ + type_ptr = _list; + +#define ZEND_TYPE_LIST_FOREACH_MUTABLE(list, type_ptr) do { \ zend_type *_list = (list)->types; \ - zend_type *_end = _list + (list)->num_types; \ + const zend_type *_end = _list + (list)->num_types; \ for (; _list < _end; _list++) { \ type_ptr = _list; @@ -221,7 +227,22 @@ typedef struct { /* This iterates over any zend_type. If it's a type list, all list elements will * be visited. If it's a single type, only the single type is visited. */ #define ZEND_TYPE_FOREACH(type, type_ptr) do { \ - zend_type *_cur, *_end; \ + const zend_type *_cur, *_end; \ + if (ZEND_TYPE_HAS_LIST(type)) { \ + zend_type_list *_list = ZEND_TYPE_LIST(type); \ + _cur = _list->types; \ + _end = _cur + _list->num_types; \ + } else { \ + _cur = &(type); \ + _end = _cur + 1; \ + } \ + do { \ + type_ptr = _cur; + + +#define ZEND_TYPE_FOREACH_MUTABLE(type, type_ptr) do { \ + zend_type *_cur; \ + const zend_type *_end; \ if (ZEND_TYPE_HAS_LIST(type)) { \ zend_type_list *_list = ZEND_TYPE_LIST(type); \ _cur = _list->types; \ diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 8caa0cbd4398e..704846c4a860f 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -626,7 +626,7 @@ static inline void accel_copy_permanent_list_types( zend_new_interned_string_func_t new_interned_string, zend_type type) { zend_type *single_type; - ZEND_TYPE_FOREACH(type, single_type) { + ZEND_TYPE_FOREACH_MUTABLE(type, single_type) { if (ZEND_TYPE_HAS_LIST(*single_type)) { ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(*single_type)); accel_copy_permanent_list_types(new_interned_string, *single_type); diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index a2346a56d458e..d2b714d937dac 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -468,7 +468,7 @@ static void zend_file_cache_serialize_type( UNSERIALIZE_PTR(list); zend_type *list_type; - ZEND_TYPE_LIST_FOREACH(list, list_type) { + ZEND_TYPE_LIST_FOREACH_MUTABLE(list, list_type) { zend_file_cache_serialize_type(list_type, script, info, buf); } ZEND_TYPE_LIST_FOREACH_END(); } else if (ZEND_TYPE_HAS_NAME(*type)) { @@ -1348,7 +1348,7 @@ static void zend_file_cache_unserialize_type( ZEND_TYPE_SET_PTR(*type, list); zend_type *list_type; - ZEND_TYPE_LIST_FOREACH(list, list_type) { + ZEND_TYPE_LIST_FOREACH_MUTABLE(list, list_type) { zend_file_cache_unserialize_type(list_type, scope, script, buf); } ZEND_TYPE_LIST_FOREACH_END(); } else if (ZEND_TYPE_HAS_NAME(*type)) { diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 3d45c63a98781..a384cdd2b9a06 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -367,7 +367,7 @@ static void zend_persist_type(zend_type *type) { } zend_type *single_type; - ZEND_TYPE_FOREACH(*type, single_type) { + ZEND_TYPE_FOREACH_MUTABLE(*type, single_type) { if (ZEND_TYPE_HAS_LIST(*single_type)) { zend_persist_type(single_type); continue; diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index bb4f9c7170f28..42a6cf76d62da 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -197,7 +197,7 @@ static void zend_persist_type_calc(zend_type *type) } zend_type *single_type; - ZEND_TYPE_FOREACH(*type, single_type) { + ZEND_TYPE_FOREACH_MUTABLE(*type, single_type) { if (ZEND_TYPE_HAS_LIST(*single_type)) { zend_persist_type_calc(single_type); continue; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index b53b7b97c9bc9..bff617cfb61de 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3170,7 +3170,7 @@ ZEND_METHOD(ReflectionUnionType, getTypes) array_init(return_value); if (ZEND_TYPE_HAS_LIST(param->type)) { - zend_type *list_type; + const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(param->type), list_type) { append_type(return_value, *list_type); } ZEND_TYPE_LIST_FOREACH_END(); @@ -3221,7 +3221,7 @@ ZEND_METHOD(ReflectionIntersectionType, getTypes) { reflection_object *intern; type_reference *param; - zend_type *list_type; + const zend_type *list_type; ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param);