Skip to content

Commit 84228eb

Browse files
dedup
1 parent 6cdbaf7 commit 84228eb

File tree

2 files changed

+56
-104
lines changed

2 files changed

+56
-104
lines changed

Zend/zend_vm_def.h

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2984,6 +2984,22 @@ ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
29842984
ZEND_VM_NEXT_OPCODE_EX(1, 2);
29852985
}
29862986

2987+
/* Clear IS_PROP_REINITABLE from all promoted readonly properties of the exiting
2988+
* constructor's scope. Called for both 'new Foo()' and 'parent::__construct()'. */
2989+
static zend_always_inline void zend_ctor_clear_promoted_readonly_reinitable(zend_execute_data *ex, uint32_t call_info)
2990+
{
2991+
if ((call_info & ZEND_CALL_HAS_THIS) && (ex->func->common.fn_flags & ZEND_ACC_CTOR)) {
2992+
zend_object *obj = Z_OBJ(ex->This);
2993+
zend_property_info *ctor_prop_info;
2994+
ZEND_HASH_MAP_FOREACH_PTR(&ex->func->common.scope->properties_info, ctor_prop_info) {
2995+
if ((ctor_prop_info->flags & (ZEND_ACC_READONLY | ZEND_ACC_PROMOTED)) == (ZEND_ACC_READONLY | ZEND_ACC_PROMOTED)
2996+
&& IS_VALID_PROPERTY_OFFSET(ctor_prop_info->offset)) {
2997+
Z_PROP_FLAG_P(OBJ_PROP(obj, ctor_prop_info->offset)) &= ~IS_PROP_REINITABLE;
2998+
}
2999+
} ZEND_HASH_FOREACH_END();
3000+
}
3001+
}
3002+
29873003
ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29883004
{
29893005
zend_execute_data *old_execute_data;
@@ -3000,19 +3016,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
30003016
#ifdef ZEND_PREFER_RELOAD
30013017
call_info = EX_CALL_INFO();
30023018
#endif
3003-
/* When a constructor exits, clear IS_PROP_REINITABLE from all promoted readonly
3004-
* properties of the declaring class. Runs for both 'new Foo()' (RELEASE_THIS set)
3005-
* and 'parent::__construct()' (only HAS_THIS set, no RELEASE_THIS). */
3006-
if ((call_info & ZEND_CALL_HAS_THIS) && (EX(func)->common.fn_flags & ZEND_ACC_CTOR)) {
3007-
zend_object *obj = Z_OBJ(execute_data->This);
3008-
zend_property_info *ctor_prop_info;
3009-
ZEND_HASH_MAP_FOREACH_PTR(&EX(func)->common.scope->properties_info, ctor_prop_info) {
3010-
if ((ctor_prop_info->flags & (ZEND_ACC_READONLY | ZEND_ACC_PROMOTED)) == (ZEND_ACC_READONLY | ZEND_ACC_PROMOTED)
3011-
&& IS_VALID_PROPERTY_OFFSET(ctor_prop_info->offset)) {
3012-
Z_PROP_FLAG_P(OBJ_PROP(obj, ctor_prop_info->offset)) &= ~IS_PROP_REINITABLE;
3013-
}
3014-
} ZEND_HASH_FOREACH_END();
3015-
}
3019+
zend_ctor_clear_promoted_readonly_reinitable(execute_data, call_info);
30163020
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
30173021
OBJ_RELEASE(Z_OBJ(execute_data->This));
30183022
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
@@ -3047,19 +3051,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
30473051
* as that may free the op_array. */
30483052
zend_vm_stack_free_extra_args_ex(call_info, execute_data);
30493053

3050-
/* When a constructor exits, clear IS_PROP_REINITABLE from all promoted readonly
3051-
* properties of the declaring class. Runs for both 'new Foo()' (RELEASE_THIS set)
3052-
* and 'parent::__construct()' (only HAS_THIS set, no RELEASE_THIS). */
3053-
if ((call_info & ZEND_CALL_HAS_THIS) && (EX(func)->common.fn_flags & ZEND_ACC_CTOR)) {
3054-
zend_object *obj = Z_OBJ(execute_data->This);
3055-
zend_property_info *ctor_prop_info;
3056-
ZEND_HASH_MAP_FOREACH_PTR(&EX(func)->common.scope->properties_info, ctor_prop_info) {
3057-
if ((ctor_prop_info->flags & (ZEND_ACC_READONLY | ZEND_ACC_PROMOTED)) == (ZEND_ACC_READONLY | ZEND_ACC_PROMOTED)
3058-
&& IS_VALID_PROPERTY_OFFSET(ctor_prop_info->offset)) {
3059-
Z_PROP_FLAG_P(OBJ_PROP(obj, ctor_prop_info->offset)) &= ~IS_PROP_REINITABLE;
3060-
}
3061-
} ZEND_HASH_FOREACH_END();
3062-
}
3054+
zend_ctor_clear_promoted_readonly_reinitable(execute_data, call_info);
30633055
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
30643056
OBJ_RELEASE(Z_OBJ(execute_data->This));
30653057
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {

Zend/zend_vm_execute.h

Lines changed: 38 additions & 78 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)