-
Couldn't load subscription status.
- Fork 8k
Bump fn_flags size #19959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bump fn_flags size #19959
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -341,7 +341,7 @@ typedef struct _zend_oparray_context { | |||||
| /* Class cannot be serialized or unserialized | | | */ | ||||||
| #define ZEND_ACC_NOT_SERIALIZABLE (1 << 29) /* X | | | */ | ||||||
| /* | | | */ | ||||||
| /* Function Flags (unused: 30) | | | */ | ||||||
| /* Function Flags (unused: 30,32-63) | | | */ | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can just say
Suggested change
like property flags above |
||||||
| /* ============== | | | */ | ||||||
| /* | | | */ | ||||||
| /* Function returning by reference | | | */ | ||||||
|
|
@@ -443,7 +443,7 @@ static zend_always_inline uint32_t zend_visibility_to_set_visibility(uint32_t vi | |||||
| // Must not clash with ZEND_SHORT_CIRCUITING_CHAIN_MASK | ||||||
| #define ZEND_JMP_NULL_BP_VAR_IS 4 | ||||||
|
|
||||||
| const char *zend_visibility_string(uint32_t fn_flags); | ||||||
| const char *zend_visibility_string(uint32_t flags); | ||||||
|
|
||||||
| #define ZEND_PROPERTY_HOOK_COUNT 2 | ||||||
| #define ZEND_PROPERTY_HOOK_STRUCT_SIZE (sizeof(zend_function*) * ZEND_PROPERTY_HOOK_COUNT) | ||||||
|
|
@@ -512,11 +512,13 @@ typedef struct _zend_internal_function_info { | |||||
| const char *default_value; | ||||||
| } zend_internal_function_info; | ||||||
|
|
||||||
| typedef uint64_t zend_fn_flags; | ||||||
|
|
||||||
| struct _zend_op_array { | ||||||
| /* Common elements */ | ||||||
| uint8_t type; | ||||||
| uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ | ||||||
| uint32_t fn_flags; | ||||||
| zend_fn_flags fn_flags; | ||||||
| zend_string *function_name; | ||||||
| zend_class_entry *scope; | ||||||
| zend_function *prototype; | ||||||
|
|
@@ -575,7 +577,7 @@ typedef struct _zend_internal_function { | |||||
| /* Common elements */ | ||||||
| uint8_t type; | ||||||
| uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ | ||||||
| uint32_t fn_flags; | ||||||
| zend_fn_flags fn_flags; | ||||||
| zend_string* function_name; | ||||||
| zend_class_entry *scope; | ||||||
| zend_function *prototype; | ||||||
|
|
@@ -604,7 +606,7 @@ union _zend_function { | |||||
| struct { | ||||||
| uint8_t type; /* never used */ | ||||||
| uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ | ||||||
| uint32_t fn_flags; | ||||||
| zend_fn_flags fn_flags; | ||||||
| zend_string *function_name; | ||||||
| zend_class_entry *scope; | ||||||
| zend_function *prototype; | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -200,27 +200,27 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ | |
| } | ||
| /* }}} */ | ||
|
|
||
| const char *zend_visibility_string(uint32_t fn_flags) /* {{{ */ | ||
| const char *zend_visibility_string(uint32_t flags) /* {{{ */ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this not updated to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is used for non-functions (e.g. class constants). For functions, we'll simply drop the high-bits when calling the function. The assertion makes sense, though it can probably be a static assert. |
||
| { | ||
| if (fn_flags & ZEND_ACC_PUBLIC) { | ||
| if (flags & ZEND_ACC_PUBLIC) { | ||
| return "public"; | ||
| } else if (fn_flags & ZEND_ACC_PRIVATE) { | ||
| } else if (flags & ZEND_ACC_PRIVATE) { | ||
| return "private"; | ||
| } else { | ||
| ZEND_ASSERT(fn_flags & ZEND_ACC_PROTECTED); | ||
| ZEND_ASSERT(flags & ZEND_ACC_PROTECTED); | ||
| return "protected"; | ||
| } | ||
| } | ||
| /* }}} */ | ||
|
|
||
| static const char *zend_asymmetric_visibility_string(uint32_t fn_flags) /* {{{ */ | ||
| static const char *zend_asymmetric_visibility_string(uint32_t flags) /* {{{ */ | ||
| { | ||
| if (fn_flags & ZEND_ACC_PRIVATE_SET) { | ||
| if (flags & ZEND_ACC_PRIVATE_SET) { | ||
| return "private(set)"; | ||
| } else if (fn_flags & ZEND_ACC_PROTECTED_SET) { | ||
| } else if (flags & ZEND_ACC_PROTECTED_SET) { | ||
| return "protected(set)"; | ||
| } else { | ||
| ZEND_ASSERT(!(fn_flags & ZEND_ACC_PUBLIC_SET)); | ||
| ZEND_ASSERT(!(flags & ZEND_ACC_PUBLIC_SET)); | ||
| return "omitted"; | ||
| } | ||
| } | ||
|
|
@@ -1126,8 +1126,8 @@ static inheritance_status do_inheritance_check_on_method( | |
| zend_function *parent, zend_class_entry *parent_scope, | ||
| zend_class_entry *ce, zval *child_zv, uint32_t flags) /* {{{ */ | ||
| { | ||
| uint32_t child_flags; | ||
| uint32_t parent_flags = parent->common.fn_flags; | ||
| zend_fn_flags child_flags; | ||
| zend_fn_flags parent_flags = parent->common.fn_flags; | ||
| zend_function *proto; | ||
|
|
||
| #define SEPARATE_METHOD() do { \ | ||
|
|
@@ -1408,7 +1408,7 @@ static void inherit_property_hook( | |
|
|
||
| child->common.prototype = parent->common.prototype ? parent->common.prototype : parent; | ||
|
|
||
| uint32_t parent_flags = parent->common.fn_flags; | ||
| zend_fn_flags parent_flags = parent->common.fn_flags; | ||
| if (parent_flags & ZEND_ACC_PRIVATE) { | ||
| child->common.fn_flags |= ZEND_ACC_CHANGED; | ||
| return; | ||
|
|
@@ -2440,7 +2440,7 @@ static void zend_fixup_trait_method(zend_function *fn, zend_class_entry *ce) /* | |
| } | ||
| /* }}} */ | ||
|
|
||
| static void zend_traits_check_private_final_inheritance(uint32_t original_fn_flags, const zend_function *fn_copy, const zend_string *name) | ||
| static void zend_traits_check_private_final_inheritance(zend_fn_flags original_fn_flags, const zend_function *fn_copy, const zend_string *name) | ||
| { | ||
| /* If the function was originally already private+final, then it will have | ||
| * already been warned about. Only emit this error when the used trait method | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4629,7 +4629,7 @@ static struct jit_observer_fcall_is_unobserved_data jit_observer_fcall_is_unobse | |
| // JIT: if (function->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_GENERATOR)) { | ||
| ZEND_ASSERT(rx != IR_UNUSED); | ||
| ir_ref if_trampoline_or_generator = ir_IF(ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_function, common.fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func_ref, offsetof(zend_function, common.fn_flags)))), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand the JIT enough to be confident in this comment, but it seems that this makes it so that only 32 of the bits are usable here? Or that at least Same with some of the other flags down below There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They need to be in the bottom bits, yes. I haven't tested it, but IR should be able to optimize this back to a
They are (nothing uses the high bits yet), but we can also add an assert. |
||
| ir_CONST_U32(ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_GENERATOR))); | ||
| ir_IF_TRUE(if_trampoline_or_generator); | ||
| ir_END_list(data.ir_end_inputs); | ||
|
|
@@ -8440,7 +8440,7 @@ static int zend_jit_free_trampoline(zend_jit_ctx *jit, ir_ref func) | |
| { | ||
| // JIT: if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) | ||
| ir_ref if_trampoline = ir_IF(ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func, offsetof(zend_function, common.fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func, offsetof(zend_function, common.fn_flags)))), | ||
| ir_CONST_U32(ZEND_ACC_CALL_VIA_TRAMPOLINE))); | ||
|
|
||
| ir_IF_TRUE(if_trampoline); | ||
|
|
@@ -8665,7 +8665,7 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co | |
| // (closure->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE); | ||
| call_info = ir_OR_U32( | ||
| ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func.common.fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func.common.fn_flags)))), | ||
| ir_CONST_U32(ZEND_ACC_FAKE_CLOSURE)), | ||
| ir_CONST_U32(ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_CLOSURE)); | ||
| // JIT: if (Z_TYPE(closure->this_ptr) != IS_UNDEF) { | ||
|
|
@@ -9117,7 +9117,7 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit, | |
| if (!func) { | ||
| // JIT: if (fbc->common.fn_flags & ZEND_ACC_STATIC) { | ||
| if_static = ir_IF(ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_function, common.fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func_ref, offsetof(zend_function, common.fn_flags)))), | ||
| ir_CONST_U32(ZEND_ACC_STATIC))); | ||
| ir_IF_TRUE_cold(if_static); | ||
| } | ||
|
|
@@ -9288,7 +9288,7 @@ static int zend_jit_init_static_method_call(zend_jit_ctx *jit, | |
| if (!func) { | ||
| // JIT: if (fbc->common.fn_flags & ZEND_ACC_STATIC) { | ||
| if_static = ir_IF(ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_function, common.fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func_ref, offsetof(zend_function, common.fn_flags)))), | ||
| ir_CONST_U32(ZEND_ACC_STATIC))); | ||
| ir_IF_FALSE_cold(if_static); | ||
| } | ||
|
|
@@ -10104,7 +10104,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen | |
| func_ref = ir_LOAD_A(jit_CALL(rx, func)); | ||
| ir_GUARD_NOT( | ||
| ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags)))), | ||
| ir_CONST_U32(ZEND_ACC_DEPRECATED|ZEND_ACC_NODISCARD)), | ||
| ir_CONST_ADDR(exit_addr)); | ||
| } | ||
|
|
@@ -10136,7 +10136,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen | |
| uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD; | ||
|
|
||
| if_deprecated_nodiscard = ir_IF(ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags)))), | ||
| ir_CONST_U32(ZEND_ACC_DEPRECATED|no_discard))); | ||
| ir_IF_TRUE_cold(if_deprecated_nodiscard); | ||
|
|
||
|
|
@@ -10349,7 +10349,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen | |
| if (!func) { | ||
| // JIT: if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) | ||
| ir_ref if_has_type_hints = ir_IF(ir_AND_U32( | ||
| ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags))), | ||
| ir_TRUNC_U32(ir_LOAD_U64(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags)))), | ||
| ir_CONST_U32(ZEND_ACC_HAS_TYPE_HINTS))); | ||
| ir_IF_TRUE(if_has_type_hints); | ||
| ir_END_list(merge_inputs); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be easier to introduce yet another filed (e.g. flags2).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be easier indeed, but also a bit more confusing (i.e. having to remember which field is stored in which flag). This can be partially mitigated by naming the flags accordingly (e.g.
ZEND_ACC2_*). But ok, Niels has suggested the same thing, so let me implement that instead.