diff --git a/Zend/Optimizer/compact_literals.c b/Zend/Optimizer/compact_literals.c index 447a034530e1b..20c4c7d3cf321 100644 --- a/Zend/Optimizer/compact_literals.c +++ b/Zend/Optimizer/compact_literals.c @@ -514,15 +514,18 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: if (opline->op2_type == IS_CONST) { + uint32_t obj_flags = (opline->opcode == ZEND_ASSIGN_OBJ || opline->opcode == ZEND_ASSIGN_OBJ_REF) + ? ZEND_ASSIGN_OBJ_FLAGS + : ZEND_FETCH_OBJ_FLAGS; // op2 property if (opline->op1_type == IS_UNUSED && property_slot[opline->op2.constant] >= 0) { - opline->extended_value = property_slot[opline->op2.constant] | (opline->extended_value & ZEND_FETCH_OBJ_FLAGS); + opline->extended_value = property_slot[opline->op2.constant] | (opline->extended_value & obj_flags); } else { - opline->extended_value = cache_size | (opline->extended_value & ZEND_FETCH_OBJ_FLAGS); + opline->extended_value = cache_size | (opline->extended_value & obj_flags); cache_size += 3 * sizeof(void *); if (opline->op1_type == IS_UNUSED) { - property_slot[opline->op2.constant] = opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS; + property_slot[opline->op2.constant] = opline->extended_value & ~obj_flags; } } } diff --git a/Zend/tests/readonly_props/cpp_reassign_after_parent.phpt b/Zend/tests/readonly_props/cpp_reassign_after_parent.phpt new file mode 100644 index 0000000000000..ad17d9b1af6be --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_after_parent.phpt @@ -0,0 +1,43 @@ +--TEST-- +Promoted readonly property reassignment - child can reassign after parent::__construct() +--FILE-- +getMessage(), "\n"; + } + // Child should still be able to reassign its own CPP property + $this->x = 'C_reassigned'; + } +} + +$c = new C(); +var_dump($c->x); + +// Also test with multiple instances +$c2 = new C(); +var_dump($c2->x); + +?> +--EXPECT-- +Error: Cannot modify readonly property C::$x +string(12) "C_reassigned" +Error: Cannot modify readonly property C::$x +string(12) "C_reassigned" diff --git a/Zend/tests/readonly_props/cpp_reassign_basic.phpt b/Zend/tests/readonly_props/cpp_reassign_basic.phpt new file mode 100644 index 0000000000000..c1b68761bd911 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +Promoted readonly property reassignment in constructor - basic +--FILE-- +x = abs($x); + $this->y = abs($y); + } +} + +$point = new Point(); +var_dump($point->x, $point->y); + +$point2 = new Point(-5, -3); +var_dump($point2->x, $point2->y); + +?> +--EXPECT-- +int(0) +int(0) +int(5) +int(3) diff --git a/Zend/tests/readonly_props/cpp_reassign_child_class.phpt b/Zend/tests/readonly_props/cpp_reassign_child_class.phpt new file mode 100644 index 0000000000000..d054585861aa3 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_child_class.phpt @@ -0,0 +1,89 @@ +--TEST-- +Promoted readonly property reassignment in constructor - child cannot reassign parent's property +--FILE-- +prop = 'child override'; + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$child = new Child1(); +var_dump($child->prop); + +// Case 2: Parent USES reassignment, child cannot +class Parent2 { + public function __construct( + public readonly string $prop = 'parent default', + ) { + $this->prop = 'parent set'; // Uses the one reassignment + } +} + +class Child2 extends Parent2 { + public function __construct() { + parent::__construct(); + // Child cannot reassign parent-owned promoted property + try { + $this->prop = 'child override'; + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$child2 = new Child2(); +var_dump($child2->prop); + +// Case 3: Child with its own promoted property +class Parent3 { + public function __construct( + public readonly string $parentProp = 'parent default', + ) { + // Parent does NOT reassign here + } +} + +class Child3 extends Parent3 { + public function __construct( + public readonly string $childProp = 'child default', + ) { + parent::__construct(); + // Child cannot reassign parent's property, but can reassign its own + try { + $this->parentProp = 'child set parent'; + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + $this->childProp = 'child set own'; + } +} + +$child3 = new Child3(); +var_dump($child3->parentProp, $child3->childProp); + +?> +--EXPECT-- +Error: Cannot modify readonly property Parent1::$prop +string(14) "parent default" +Error: Cannot modify readonly property Parent2::$prop +string(10) "parent set" +Error: Cannot modify readonly property Parent3::$parentProp +string(14) "parent default" +string(13) "child set own" diff --git a/Zend/tests/readonly_props/cpp_reassign_child_preempt_parent.phpt b/Zend/tests/readonly_props/cpp_reassign_child_preempt_parent.phpt new file mode 100644 index 0000000000000..db2bb81c9eb10 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_child_preempt_parent.phpt @@ -0,0 +1,31 @@ +--TEST-- +Promoted readonly property reassignment in constructor - child preempt then parent ctor throws +--FILE-- +prop = 'parent set'; + } +} + +class ChildCPP extends ParentCPP { + public function __construct() { + $this->prop = 'child set'; + try { + parent::__construct(); + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$c = new ChildCPP(); +var_dump($c->prop); + +?> +--EXPECT-- +Error: Cannot modify readonly property ParentCPP::$prop +string(9) "child set" diff --git a/Zend/tests/readonly_props/cpp_reassign_child_redefine.phpt b/Zend/tests/readonly_props/cpp_reassign_child_redefine.phpt new file mode 100644 index 0000000000000..1cd82db84f528 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_child_redefine.phpt @@ -0,0 +1,84 @@ +--TEST-- +Promoted readonly property reassignment in constructor - child redefines parent property +--FILE-- +x = 'C'; + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$c1 = new C1(); +var_dump($c1->x); + +// Case 2: Parent uses CPP and reassigns; child redefines as non-promoted. +// The child does not use CPP, so it does not claim CPP ownership of the property. +// P2's CPP "owns" the reassignment window: P2's body write succeeds. +class P2 { + public function __construct( + public readonly string $x = 'P1', + ) { + $this->x = 'P2'; + } +} + +class C2 extends P2 { + public readonly string $x; + + public function __construct() { + parent::__construct(); + } +} + +$c2 = new C2(); +var_dump($c2->x); + +// Case 3: Parent uses CPP, child uses CPP redefinition. +// Child's CPP opens the reassignment window for C3::$x. When parent::__construct() +// runs, P3's CPP tries to initialize C3::$x again, which must fail since C3 +// owns the property and has already initialized it. +class P3 { + public function __construct( + public readonly string $x = 'P', + ) {} +} + +class C3 extends P3 { + public function __construct( + public readonly string $x = 'C1', + ) { + try { + parent::__construct(); + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$c3 = new C3(); +var_dump($c3->x); + +?> +--EXPECT-- +Error: Cannot modify readonly property C1::$x +string(1) "P" +string(2) "P2" +Error: Cannot modify readonly property C3::$x +string(2) "C1" diff --git a/Zend/tests/readonly_props/cpp_reassign_conditional.phpt b/Zend/tests/readonly_props/cpp_reassign_conditional.phpt new file mode 100644 index 0000000000000..e67177e76e3c2 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_conditional.phpt @@ -0,0 +1,23 @@ +--TEST-- +Promoted readonly property reassignment in constructor - conditional initialization +--FILE-- +cacheDir ??= '/tmp/app_cache'; + } +} + +$config1 = new Config(); +var_dump($config1->cacheDir); + +$config2 = new Config('/custom/cache'); +var_dump($config2->cacheDir); + +?> +--EXPECT-- +string(14) "/tmp/app_cache" +string(13) "/custom/cache" diff --git a/Zend/tests/readonly_props/cpp_reassign_different_object.phpt b/Zend/tests/readonly_props/cpp_reassign_different_object.phpt new file mode 100644 index 0000000000000..293826f2ee13a --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_different_object.phpt @@ -0,0 +1,34 @@ +--TEST-- +Promoted readonly property reassignment in constructor - different object fails +--FILE-- +x = $x * 2; + if ($other !== null) { + try { + $other->x = 999; + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } + } +} + +$a = new Foo(5); +var_dump($a->x); + +$b = new Foo(3, $a); +var_dump($a->x, $b->x); // $a unchanged + +?> +--EXPECT-- +int(10) +Error: Cannot modify readonly property Foo::$x +int(10) +int(6) diff --git a/Zend/tests/readonly_props/cpp_reassign_direct_ctor_call.phpt b/Zend/tests/readonly_props/cpp_reassign_direct_ctor_call.phpt new file mode 100644 index 0000000000000..5ff246eaa46eb --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_direct_ctor_call.phpt @@ -0,0 +1,29 @@ +--TEST-- +Promoted readonly properties cannot be reassigned when __construct() is called directly +--FILE-- +value = strtoupper($this->value); + } +} + +$obj = new Foo('hello'); +var_dump($obj->value); + +// Direct call fails: CPP assignment cannot reinitialize an already-set property +try { + $obj->__construct('world'); +} catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} +var_dump($obj->value); + +?> +--EXPECT-- +string(5) "HELLO" +Error: Cannot modify readonly property Foo::$value +string(5) "HELLO" diff --git a/Zend/tests/readonly_props/cpp_reassign_grandchild_redefine.phpt b/Zend/tests/readonly_props/cpp_reassign_grandchild_redefine.phpt new file mode 100644 index 0000000000000..b068846b7a034 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_grandchild_redefine.phpt @@ -0,0 +1,39 @@ +--TEST-- +Promoted readonly property reassignment - grandchild non-CPP redeclare preserves child CPP window +--FILE-- +getMessage(), "\n"; + } + $this->x = 'C2'; + } +} + +class D extends C { + public readonly string $x; + + public function __construct() { + parent::__construct(); + var_dump($this->x); + } +} + +new D(); + +?> +--EXPECT-- +Error: Cannot modify readonly property D::$x +string(2) "C2" diff --git a/Zend/tests/readonly_props/cpp_reassign_indirect_allowed.phpt b/Zend/tests/readonly_props/cpp_reassign_indirect_allowed.phpt new file mode 100644 index 0000000000000..3437d54dffbc5 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_indirect_allowed.phpt @@ -0,0 +1,47 @@ +--TEST-- +Promoted readonly property reassignment in constructor - indirect reassignment allowed +--FILE-- +initProp(); + } + + private function initProp(): void { + $this->prop = 'from method'; + } +} + +$cm = new CalledMethod(); +var_dump($cm->prop); + +// But second reassignment still fails +class MultipleReassign { + public function __construct( + public readonly string $prop = 'default', + ) { + $this->initProp("first from method"); + try { + $this->initProp("second from method"); // Second call - should fail + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } + + private function initProp(string $v): void { + $this->prop = $v; + } +} + +$mr = new MultipleReassign(); +var_dump($mr->prop); + +?> +--EXPECT-- +string(11) "from method" +Error: Cannot modify readonly property MultipleReassign::$prop +string(17) "first from method" diff --git a/Zend/tests/readonly_props/cpp_reassign_indirect_ops.phpt b/Zend/tests/readonly_props/cpp_reassign_indirect_ops.phpt new file mode 100644 index 0000000000000..e39c3e18d8885 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_indirect_ops.phpt @@ -0,0 +1,42 @@ +--TEST-- +Promoted readonly property reassignment in constructor - indirect operations (++, --, +=) +--FILE-- +count++; + } +} + +$c = new Counter(5); +var_dump($c->count); + +// Multiple operations count as reassignments - second fails +class MultiOp { + public function __construct( + public readonly int $value = 10, + ) { + $this->value += 5; // First modification - allowed + try { + $this->value++; // Second modification - should fail + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$m = new MultiOp(); +var_dump($m->value); + +?> +--EXPECT-- +int(6) +Error: Cannot modify readonly property MultiOp::$value +int(15) diff --git a/Zend/tests/readonly_props/cpp_reassign_multi_instance.phpt b/Zend/tests/readonly_props/cpp_reassign_multi_instance.phpt new file mode 100644 index 0000000000000..325b114e40195 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_multi_instance.phpt @@ -0,0 +1,46 @@ +--TEST-- +Promoted readonly property reassignment - multiple instantiations (VM cache warm) +--FILE-- +getMessage(), "\n"; + } + } +} + +// First instantiation (slow path) +$c1 = new C(); +var_dump($c1->x); + +// Second instantiation (fast path - cache warm) +$c2 = new C(); +var_dump($c2->x); + +// Third for good measure +$c3 = new C(); +var_dump($c3->x); + +?> +--EXPECT-- +Error: Cannot modify readonly property C::$x +string(1) "C" +Error: Cannot modify readonly property C::$x +string(1) "C" +Error: Cannot modify readonly property C::$x +string(1) "C" diff --git a/Zend/tests/readonly_props/cpp_reassign_multiple_fail.phpt b/Zend/tests/readonly_props/cpp_reassign_multiple_fail.phpt new file mode 100644 index 0000000000000..fcbce0a372bae --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_multiple_fail.phpt @@ -0,0 +1,25 @@ +--TEST-- +Promoted readonly property reassignment in constructor - multiple reassignments fail +--FILE-- +value = 'first'; // OK - first reassignment + try { + $this->value = 'second'; // Error - second reassignment + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$ex = new Example(); +var_dump($ex->value); + +?> +--EXPECT-- +Error: Cannot modify readonly property Example::$value +string(5) "first" diff --git a/Zend/tests/readonly_props/cpp_reassign_nonpromoted.phpt b/Zend/tests/readonly_props/cpp_reassign_nonpromoted.phpt new file mode 100644 index 0000000000000..092c496c87936 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_nonpromoted.phpt @@ -0,0 +1,49 @@ +--TEST-- +Promoted readonly property reassignment in constructor - non-promoted properties unchanged +--FILE-- +prop = 'first'; + try { + $this->prop = 'second'; // Should fail - not a promoted property + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$np = new NonPromoted(); +var_dump($np->prop); + +// Test mixed: promoted and non-promoted in same class +class MixedProps { + public readonly string $nonPromoted; + + public function __construct( + public readonly string $promoted = 'default', + ) { + $this->nonPromoted = 'first'; + $this->promoted = 'reassigned'; // Allowed (promoted, first reassignment) + try { + $this->nonPromoted = 'second'; // Should fail (non-promoted) + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$m = new MixedProps(); +var_dump($m->promoted, $m->nonPromoted); + +?> +--EXPECT-- +Error: Cannot modify readonly property NonPromoted::$prop +string(5) "first" +Error: Cannot modify readonly property MixedProps::$nonPromoted +string(10) "reassigned" +string(5) "first" diff --git a/Zend/tests/readonly_props/cpp_reassign_outside_ctor.phpt b/Zend/tests/readonly_props/cpp_reassign_outside_ctor.phpt new file mode 100644 index 0000000000000..f6d0308c49948 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_outside_ctor.phpt @@ -0,0 +1,43 @@ +--TEST-- +Promoted readonly property reassignment in constructor - outside constructor fails +--FILE-- +x = abs($x); + } + + public function tryModify(): void { + $this->x = 999; + } +} + +$point = new Point(-5); +var_dump($point->x); + +// Cannot reassign from outside constructor +try { + $point->x = 100; +} catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} +var_dump($point->x); + +// Cannot reassign from a method +try { + $point->tryModify(); +} catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} +var_dump($point->x); + +?> +--EXPECT-- +int(5) +Error: Cannot modify readonly property Point::$x +int(5) +Error: Cannot modify readonly property Point::$x +int(5) diff --git a/Zend/tests/readonly_props/cpp_reassign_reflection.phpt b/Zend/tests/readonly_props/cpp_reassign_reflection.phpt new file mode 100644 index 0000000000000..8f3033e0f13a5 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_reflection.phpt @@ -0,0 +1,41 @@ +--TEST-- +Promoted readonly property reassignment works when object created via reflection +--FILE-- +bar = strtoupper($bar); + } +} + +$ref = new ReflectionClass(Foo::class); +$obj = $ref->newInstanceWithoutConstructor(); + +// Property is uninitialized at this point +try { + var_dump($obj->bar); +} catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} + +// First constructor call: CPP reassignment allowed +$obj->__construct('explicit call'); +var_dump($obj->bar); + +// Second call fails: property no longer uninitialized +try { + $obj->__construct('second call'); +} catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} +var_dump($obj->bar); + +?> +--EXPECT-- +Error: Typed property Foo::$bar must not be accessed before initialization +string(13) "EXPLICIT CALL" +Error: Cannot modify readonly property Foo::$bar +string(13) "EXPLICIT CALL" diff --git a/Zend/tests/readonly_props/cpp_reassign_through_function.phpt b/Zend/tests/readonly_props/cpp_reassign_through_function.phpt new file mode 100644 index 0000000000000..994ea71220059 --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_through_function.phpt @@ -0,0 +1,30 @@ +--TEST-- +Promoted readonly property reassignment through plain function should error +--FILE-- +prop++; + } +} + +function set($c) { + try { + $c->set(); + } catch (Error $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; + } +} + +$c = new C(42); +var_dump($c->prop); + +?> +--EXPECT-- +Error: Cannot modify readonly property C::$prop +int(42) diff --git a/Zend/tests/readonly_props/cpp_reassign_validation.phpt b/Zend/tests/readonly_props/cpp_reassign_validation.phpt new file mode 100644 index 0000000000000..f8f9609f5773d --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_validation.phpt @@ -0,0 +1,30 @@ +--TEST-- +Promoted readonly property reassignment in constructor - validation +--FILE-- +email = strtolower($email); // Normalize + } +} + +$user = new User('TEST@Example.COM'); +var_dump($user->email); + +try { + new User('not-an-email'); +} catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +string(16) "test@example.com" +ValueError: Invalid email diff --git a/Zend/tests/readonly_props/cpp_reassign_visibility.phpt b/Zend/tests/readonly_props/cpp_reassign_visibility.phpt new file mode 100644 index 0000000000000..340e14478407f --- /dev/null +++ b/Zend/tests/readonly_props/cpp_reassign_visibility.phpt @@ -0,0 +1,106 @@ +--TEST-- +Promoted readonly property reassignment in constructor - visibility rules apply +--FILE-- +init(); + } + + protected function init(): void { + } +} + +class Child1 extends Parent1 { + protected function init(): void { + try { + $this->prop = 'child override'; + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$child1 = new Child1(); +var_dump($child1->prop); + +// Case 2: protected(set) - child's init() CAN modify within CPP window +class Parent2 { + public function __construct( + protected(set) public readonly string $prop = 'parent default', + ) { + $this->init(); + } + + protected function init(): void { + } +} + +class Child2 extends Parent2 { + protected function init(): void { + $this->prop = 'child set'; + } +} + +$child2 = new Child2(); +var_dump($child2->prop); + +// Case 3: public(set) - child's init() CAN modify within CPP window +class Parent3 { + public function __construct( + public public(set) readonly string $prop = 'parent default', + ) { + $this->init(); + } + + protected function init(): void { + } +} + +class Child3 extends Parent3 { + protected function init(): void { + $this->prop = 'child set'; + } +} + +$child3 = new Child3(); +var_dump($child3->prop); + +// Case 4: protected(set) with parent using reassignment - child cannot (window closed) +class Parent4 { + public function __construct( + protected(set) public readonly string $prop = 'parent default', + ) { + $this->prop = 'parent set'; // Uses the one reassignment + $this->init(); + } + + protected function init(): void { + } +} + +class Child4 extends Parent4 { + protected function init(): void { + try { + $this->prop = 'child override'; + } catch (Throwable $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; + } + } +} + +$child4 = new Child4(); +var_dump($child4->prop); + +?> +--EXPECT-- +Error: Cannot modify private(set) property Parent1::$prop from scope Child1 +string(14) "parent default" +string(9) "child set" +string(9) "child set" +Error: Cannot modify readonly property Parent4::$prop +string(10) "parent set" diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 3147fda23e9fd..66b0254c4e94c 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8310,6 +8310,9 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 zend_op *opline = zend_emit_op(NULL, is_ref ? ZEND_ASSIGN_OBJ_REF : ZEND_ASSIGN_OBJ, NULL, &name_node); opline->extended_value = zend_alloc_cache_slots(3); + if ((flags & ZEND_ACC_READONLY) != 0) { + opline->extended_value |= ZEND_ASSIGN_OBJ_PROMOTED_READONLY_INIT; + } zend_emit_op_data(&value_node); } } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 5414467f3f874..61358d29fd62d 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1097,6 +1097,9 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_FETCH_DIM_WRITE 2 #define ZEND_FETCH_OBJ_FLAGS 3 +#define ZEND_ASSIGN_OBJ_PROMOTED_READONLY_INIT (1u << 31) +#define ZEND_ASSIGN_OBJ_FLAGS (ZEND_FETCH_OBJ_FLAGS | ZEND_ASSIGN_OBJ_PROMOTED_READONLY_INIT) + /* Used to mark what kind of operation a writing FETCH_DIM is used in, * to produce a more precise error on incorrect string offset use. */ #define ZEND_FETCH_DIM_REF 1 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 37278c5cb9a23..8d04d116fcfe9 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1071,16 +1071,9 @@ ZEND_API bool zend_never_inline zend_verify_property_type(const zend_property_in 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; - - if (UNEXPECTED(info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { - if ((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE)) { - zend_readonly_property_modification_error(info); - return &EG(uninitialized_zval); - } - if (info->flags & ZEND_ACC_PPP_SET_MASK && !zend_asymmetric_property_has_set_access(info)) { - zend_asymmetric_visibility_property_modification_error(info, "modify"); - return &EG(uninitialized_zval); - } + zend_property_write_kind prop_write_kind = zend_verify_readonly_and_avis(property_val, info, false); + if (prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN) { + return &EG(uninitialized_zval); } ZVAL_DEREF(value); @@ -1091,7 +1084,7 @@ static zend_never_inline zval* zend_assign_to_typed_prop(const zend_property_inf return &EG(uninitialized_zval); } - Z_PROP_FLAG_P(property_val) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(property_val, prop_write_kind); return zend_assign_to_variable_ex(property_val, &tmp, IS_TMP_VAR, EX_USES_STRICT_TYPES(), garbage_ptr); } @@ -3654,7 +3647,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c static zend_always_inline void zend_assign_to_property_reference(zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zval variable, *variable_ptr = &variable; - void **cache_addr = (prop_op_type == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_RETURNS_FUNCTION) : NULL; + void **cache_addr = (prop_op_type == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~(ZEND_RETURNS_FUNCTION | ZEND_ASSIGN_OBJ_PROMOTED_READONLY_INIT)) : NULL; zend_refcounted *garbage = NULL; zend_property_info *prop_info = NULL; @@ -5964,3 +5957,49 @@ ZEND_API void zend_return_unwrap_ref(zend_execute_data *execute_data, zval *retu zend_unwrap_reference(return_value); } + +static zend_always_inline bool zend_has_ctor_for_cpp_reassignment( + const zend_execute_data *ex, zend_object *obj, zend_string *property_name) +{ + for (const zend_execute_data *frame = ex; frame != NULL; frame = frame->prev_execute_data) { + if (!(ZEND_CALL_INFO(frame) & ZEND_CALL_HAS_THIS) || Z_OBJ(frame->This) != obj) { + return false; + } + if (!(frame->func->common.fn_flags & ZEND_ACC_CTOR)) { + continue; + } + + zend_class_entry *scope = frame->func->common.scope; + ZEND_ASSERT(scope); + + zend_property_info *scope_prop = (zend_property_info *) zend_hash_find_ptr(&scope->properties_info, property_name); + ZEND_ASSERT(scope_prop); + return scope_prop->ce == scope && (scope_prop->flags & (ZEND_ACC_READONLY|ZEND_ACC_PROMOTED)) == (ZEND_ACC_READONLY|ZEND_ACC_PROMOTED); + } + + return false; +} + +ZEND_API ZEND_COLD zend_property_write_kind zend_verify_readonly_slow(zval *property_val, const zend_property_info *info) +{ + ZEND_ASSERT(info->flags & ZEND_ACC_READONLY); + + if (Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE) { + return ZEND_PROPERTY_WRITE_READONLY_REINITABLE; + } + if (Z_PROP_FLAG_P(property_val) & IS_PROP_CTOR_REASSIGNED) { + return ZEND_PROPERTY_WRITE_FORBIDDEN; + } + zend_execute_data *execute_data = EG(current_execute_data); + if (!execute_data || !(EX_CALL_INFO() & ZEND_CALL_HAS_THIS)) { + return ZEND_PROPERTY_WRITE_FORBIDDEN; + } + const zend_op *opline = EX(opline); + zend_object *obj = zend_get_object_from_slot(property_val, info); + if (!zend_has_ctor_for_cpp_reassignment(execute_data, obj, info->name) + || ((opline->opcode == ZEND_ASSIGN_OBJ || opline->opcode == ZEND_ASSIGN_OBJ_REF) + && opline->extended_value & ZEND_ASSIGN_OBJ_PROMOTED_READONLY_INIT)) { + return ZEND_PROPERTY_WRITE_FORBIDDEN; + } + return ZEND_PROPERTY_WRITE_READONLY_CTOR_REASSIGNED; +} diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 89a9e79143a82..d4d55231f3b09 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -584,6 +584,45 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal #define ZEND_CLASS_HAS_TYPE_HINTS(ce) ((bool)(ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS)) #define ZEND_CLASS_HAS_READONLY_PROPS(ce) ((bool)(ce->ce_flags & ZEND_ACC_HAS_READONLY_PROPS)) +typedef enum _zend_property_write_kind { + ZEND_PROPERTY_WRITE_FORBIDDEN = 0, /* Write disallowed */ + ZEND_PROPERTY_WRITE_OK, /* Write allowed */ + ZEND_PROPERTY_WRITE_READONLY_REINITABLE, /* Clone reinit window: clear IS_PROP_REINITABLE after write */ + ZEND_PROPERTY_WRITE_READONLY_CTOR_REASSIGNED, /* CPP ctor reassignment: set IS_PROP_CTOR_REASSIGNED after write */ +} zend_property_write_kind; + +ZEND_API ZEND_COLD zend_property_write_kind zend_verify_readonly_slow(zval *property_val, const zend_property_info *info); + +static zend_always_inline zend_property_write_kind zend_verify_readonly_and_avis( + zval *property_val, const zend_property_info *info, bool indirect) +{ + if (UNEXPECTED(info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { + zend_property_write_kind prop_write_kind = ZEND_PROPERTY_WRITE_OK; + if ((info->flags & ZEND_ACC_READONLY) && !Z_ISUNDEF_P(property_val)) { + prop_write_kind = zend_verify_readonly_slow(property_val, info); + if (prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN) { + zend_readonly_property_modification_error(info); + return ZEND_PROPERTY_WRITE_FORBIDDEN; + } + } + if ((info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(info)) { + const char *operation = indirect ? "indirectly modify" : "modify"; + zend_asymmetric_visibility_property_modification_error(info, operation); + return ZEND_PROPERTY_WRITE_FORBIDDEN; + } + return prop_write_kind; + } + return ZEND_PROPERTY_WRITE_OK; +} + +static zend_always_inline void zend_property_write_commit(zval *property_val, zend_property_write_kind kind) +{ + if (kind == ZEND_PROPERTY_WRITE_READONLY_REINITABLE) { + Z_PROP_FLAG_P(property_val) &= ~IS_PROP_REINITABLE; + } else if (kind == ZEND_PROPERTY_WRITE_READONLY_CTOR_REASSIGNED) { + Z_PROP_FLAG_P(property_val) |= IS_PROP_CTOR_REASSIGNED; + } +} 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); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 45eac02949d15..e3dcb9f7a17c7 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1049,6 +1049,7 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva uintptr_t property_offset; const zend_property_info *prop_info = NULL; uint32_t *guard = NULL; + zend_property_write_kind prop_write_kind = ZEND_PROPERTY_WRITE_OK; ZEND_ASSERT(!Z_ISREF_P(value)); property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__set != NULL), cache_slot, &prop_info); @@ -1066,15 +1067,8 @@ ZEND_API zval *zend_std_write_property(zend_object *zobj, zend_string *name, zva error = (*guard) & IN_SET; } if (error) { - if ((prop_info->flags & ZEND_ACC_READONLY) - && Z_TYPE_P(variable_ptr) != IS_UNDEF - && !(Z_PROP_FLAG_P(variable_ptr) & IS_PROP_REINITABLE)) { - zend_readonly_property_modification_error(prop_info); - variable_ptr = &EG(error_zval); - goto exit; - } - if ((prop_info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(prop_info)) { - zend_asymmetric_visibility_property_modification_error(prop_info, "modify"); + prop_write_kind = zend_verify_readonly_and_avis(variable_ptr, prop_info, false); + if (prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN) { variable_ptr = &EG(error_zval); goto exit; } @@ -1112,6 +1106,8 @@ found:; variable_ptr = zend_assign_to_variable_ex( variable_ptr, value, IS_TMP_VAR, property_uses_strict_types(), &garbage); + zend_property_write_commit(variable_ptr, prop_write_kind); + if (garbage) { if (GC_DELREF(garbage) == 0) { zend_execute_data *execute_data = EG(current_execute_data); diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index 86c3a49f8c8c5..793caf945efcf 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -137,6 +137,11 @@ static inline zend_property_info *zend_get_typed_property_info_for_slot(zend_obj return NULL; } +static zend_always_inline zend_object *zend_get_object_from_slot(const zval *slot, const zend_property_info *prop_info) +{ + return (zend_object *)((char *)slot - prop_info->offset); +} + static zend_always_inline bool zend_check_method_accessible(const zend_function *fn, const zend_class_entry *scope) { if (!(fn->common.fn_flags & ZEND_ACC_PUBLIC) diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 22dbfa9be879b..9a00ea86d91fe 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -1594,6 +1594,7 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { #define IS_PROP_UNINIT (1<<0) #define IS_PROP_REINITABLE (1<<1) /* It has impact only on readonly properties */ #define IS_PROP_LAZY (1<<2) +#define IS_PROP_CTOR_REASSIGNED (1<<3) /* Extra ctor reassignment already consumed */ #define Z_PROP_FLAG_P(z) Z_EXTRA_P(z) #define ZVAL_COPY_VALUE_PROP(z, v) \ do { *(z) = *(v); } while (0) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 86708f8c97a29..832aad6c81947 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2512,8 +2512,8 @@ ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLO ZEND_VM_C_LABEL(assign_object): zobj = Z_OBJ_P(object); if (OP2_TYPE == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -2619,7 +2619,7 @@ ZEND_VM_C_LABEL(fast_assign_obj): ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (OP2_TYPE != IS_CONST) { zend_tmp_string_release(tmp_name); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cbfae90802cfa..d9caa1efa8976 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -24403,8 +24403,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -24511,7 +24511,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -24560,8 +24560,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -24667,7 +24667,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -24715,8 +24715,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -24823,7 +24823,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -27111,8 +27111,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -27219,7 +27219,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -27267,8 +27267,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -27374,7 +27374,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -27421,8 +27421,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -27529,7 +27529,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -30935,8 +30935,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -31043,7 +31043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -31092,8 +31092,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -31199,7 +31199,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -31247,8 +31247,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -31355,7 +31355,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -33469,8 +33469,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -33577,7 +33577,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -33627,8 +33627,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -33734,7 +33734,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -33783,8 +33783,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -33891,7 +33891,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -35567,8 +35567,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -35675,7 +35675,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -35724,8 +35724,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -35831,7 +35831,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -35879,8 +35879,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -35987,7 +35987,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -38136,8 +38136,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -38244,7 +38244,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -38294,8 +38294,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -38401,7 +38401,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -38450,8 +38450,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -38558,7 +38558,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -42505,8 +42505,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -42613,7 +42613,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -42663,8 +42663,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -42770,7 +42770,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -42819,8 +42819,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -42927,7 +42927,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -46328,8 +46328,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -46436,7 +46436,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -46485,8 +46485,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -46592,7 +46592,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -46640,8 +46640,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -46748,7 +46748,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -51442,8 +51442,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -51550,7 +51550,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -51600,8 +51600,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -51707,7 +51707,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -51756,8 +51756,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -51864,7 +51864,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -76805,8 +76805,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -76913,7 +76913,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -76962,8 +76962,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -77069,7 +77069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -77117,8 +77117,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -77225,7 +77225,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -79513,8 +79513,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -79621,7 +79621,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -79669,8 +79669,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -79776,7 +79776,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -79823,8 +79823,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -79931,7 +79931,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -83337,8 +83337,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -83445,7 +83445,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -83494,8 +83494,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -83601,7 +83601,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -83649,8 +83649,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -83757,7 +83757,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -85871,8 +85871,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -85979,7 +85979,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -86029,8 +86029,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -86136,7 +86136,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -86185,8 +86185,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -86293,7 +86293,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -87969,8 +87969,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -88077,7 +88077,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -88126,8 +88126,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -88233,7 +88233,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -88281,8 +88281,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -88389,7 +88389,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -90538,8 +90538,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -90646,7 +90646,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -90696,8 +90696,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -90803,7 +90803,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -90852,8 +90852,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -90960,7 +90960,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -94907,8 +94907,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -95015,7 +95015,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -95065,8 +95065,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -95172,7 +95172,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -95221,8 +95221,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -95329,7 +95329,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -98730,8 +98730,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -98838,7 +98838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -98887,8 +98887,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -98994,7 +98994,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -99042,8 +99042,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_TMP_VAR == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -99150,7 +99150,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -103742,8 +103742,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -103850,7 +103850,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -103900,8 +103900,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -104007,7 +104007,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -104056,8 +104056,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV assign_object: zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS))) { + void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; zend_property_info *prop_info; @@ -104164,7 +104164,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) : NULL); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 59bb9401d9a98..4c2d77c7f3f22 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2803,22 +2803,6 @@ static void ZEND_FASTCALL zend_jit_assign_obj_helper(zend_object *zobj, zend_str } } -static zend_always_inline bool verify_readonly_and_avis(zval *property_val, zend_property_info *info, bool indirect) -{ - if (UNEXPECTED(info->flags & (ZEND_ACC_READONLY|ZEND_ACC_PPP_SET_MASK))) { - if ((info->flags & ZEND_ACC_READONLY) && !(Z_PROP_FLAG_P(property_val) & IS_PROP_REINITABLE)) { - zend_readonly_property_modification_error(info); - return false; - } - if ((info->flags & ZEND_ACC_PPP_SET_MASK) && !zend_asymmetric_property_has_set_access(info)) { - const char *operation = indirect ? "indirectly modify" : "modify"; - zend_asymmetric_visibility_property_modification_error(info, operation); - return false; - } - } - return true; -} - static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend_property_info *info, zval *value, zval *result) { zend_execute_data *execute_data = EG(current_execute_data); @@ -2832,7 +2816,8 @@ static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend value = &EG(uninitialized_zval); } - if (UNEXPECTED(!verify_readonly_and_avis(property_val, info, false))) { + zend_property_write_kind prop_write_kind = zend_verify_readonly_and_avis(property_val, info, false); + if (UNEXPECTED(prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN)) { if (result) { ZVAL_UNDEF(result); } @@ -2850,7 +2835,7 @@ static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend return; } - Z_PROP_FLAG_P(property_val) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(property_val, prop_write_kind); value = zend_assign_to_variable_ex(property_val, &tmp, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); if (result) { @@ -2893,7 +2878,8 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_prop(zval *zptr, zend_prop zend_execute_data *execute_data = EG(current_execute_data); zval z_copy; - if (UNEXPECTED(!verify_readonly_and_avis(zptr, prop_info, true))) { + zend_property_write_kind prop_write_kind = zend_verify_readonly_and_avis(zptr, prop_info, true); + if (UNEXPECTED(prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN)) { return; } @@ -2907,7 +2893,7 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_prop(zval *zptr, zend_prop binary_op(&z_copy, zptr, value); if (EXPECTED(zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - Z_PROP_FLAG_P(zptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(zptr, prop_write_kind); zval_ptr_dtor(zptr); ZVAL_COPY_VALUE(zptr, &z_copy); } else { @@ -2987,7 +2973,8 @@ static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_i { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { + zend_property_write_kind prop_write_kind = zend_verify_readonly_and_avis(var_ptr, prop_info, true); + if (UNEXPECTED(prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN)) { return; } @@ -3004,13 +2991,13 @@ static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_i zend_long val = _zend_jit_throw_inc_prop_error(prop_info); ZVAL_LONG(var_ptr, val); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); } } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { zval_ptr_dtor(var_ptr); ZVAL_COPY_VALUE(var_ptr, &tmp); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); zval_ptr_dtor(&tmp); } } @@ -3019,7 +3006,8 @@ static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_i { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { + zend_property_write_kind prop_write_kind = zend_verify_readonly_and_avis(var_ptr, prop_info, true); + if (UNEXPECTED(prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN)) { return; } @@ -3036,13 +3024,13 @@ static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_i zend_long val = _zend_jit_throw_dec_prop_error(prop_info); ZVAL_LONG(var_ptr, val); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); } } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { zval_ptr_dtor(var_ptr); ZVAL_COPY_VALUE(var_ptr, &tmp); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); zval_ptr_dtor(&tmp); } } @@ -3065,7 +3053,8 @@ static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_prope { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { + zend_property_write_kind prop_write_kind = zend_verify_readonly_and_avis(var_ptr, prop_info, true); + if (UNEXPECTED(prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN)) { if (result) { ZVAL_UNDEF(result); } @@ -3084,14 +3073,14 @@ static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_prope zend_long val = _zend_jit_throw_inc_prop_error(prop_info); ZVAL_LONG(var_ptr, val); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); } } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { zval_ptr_dtor(var_ptr); ZVAL_COPY_VALUE(var_ptr, result); ZVAL_UNDEF(result); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); } } @@ -3099,7 +3088,8 @@ static void ZEND_FASTCALL zend_jit_post_dec_typed_prop(zval *var_ptr, zend_prope { ZEND_ASSERT(Z_TYPE_P(var_ptr) != IS_UNDEF); - if (UNEXPECTED(!verify_readonly_and_avis(var_ptr, prop_info, true))) { + zend_property_write_kind prop_write_kind = zend_verify_readonly_and_avis(var_ptr, prop_info, true); + if (UNEXPECTED(prop_write_kind == ZEND_PROPERTY_WRITE_FORBIDDEN)) { if (result) { ZVAL_UNDEF(result); } @@ -3118,14 +3108,14 @@ static void ZEND_FASTCALL zend_jit_post_dec_typed_prop(zval *var_ptr, zend_prope zend_long val = _zend_jit_throw_dec_prop_error(prop_info); ZVAL_LONG(var_ptr, val); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); } } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { zval_ptr_dtor(var_ptr); ZVAL_COPY_VALUE(var_ptr, result); ZVAL_UNDEF(result); } else { - Z_PROP_FLAG_P(var_ptr) &= ~IS_PROP_REINITABLE; + zend_property_write_commit(var_ptr, prop_write_kind); } } diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 19b3ce125733a..ca957dce92520 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -14874,7 +14874,7 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, if (!prop_info) { ir_ref run_time_cache = ir_LOAD_A(jit_EX(run_time_cache)); - ir_ref ref = ir_LOAD_A(ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS)); + ir_ref ref = ir_LOAD_A(ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS)); ir_ref if_same = ir_IF(ir_EQ(ref, ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_object, ce))))); ir_IF_FALSE_cold(if_same); @@ -14882,7 +14882,7 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ir_IF_TRUE(if_same); ir_ref offset_ref = ir_LOAD_A( - ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*))); + ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) + sizeof(void*))); ir_ref if_dynamic = ir_IF(ir_LT(offset_ref, ir_CONST_ADDR(ZEND_FIRST_PROPERTY_OFFSET))); ir_IF_TRUE_cold(if_dynamic); @@ -14900,7 +14900,7 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, if (!ce || ce_is_instanceof || (ce->ce_flags & (ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_TRAIT))) { ir_ref arg3, arg4; ir_ref prop_info_ref = ir_LOAD_A( - ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2)); + ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) + sizeof(void*) * 2)); ir_ref if_has_prop_info = ir_IF(prop_info_ref); ir_IF_TRUE_cold(if_has_prop_info); @@ -15068,7 +15068,7 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, obj_ref, ir_CONST_ADDR(name), arg3, - ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS), + ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS), arg5); ir_END_list(end_inputs); @@ -15232,7 +15232,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, if (!prop_info) { ir_ref run_time_cache = ir_LOAD_A(jit_EX(run_time_cache)); - ir_ref ref = ir_LOAD_A(ir_ADD_OFFSET(run_time_cache, (opline+1)->extended_value & ~ZEND_FETCH_OBJ_FLAGS)); + ir_ref ref = ir_LOAD_A(ir_ADD_OFFSET(run_time_cache, (opline+1)->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS)); ir_ref if_same = ir_IF(ir_EQ(ref, ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_object, ce))))); ir_IF_FALSE_cold(if_same); @@ -15241,7 +15241,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, ir_IF_TRUE(if_same); if (!ce || ce_is_instanceof || (ce->ce_flags & (ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_TRAIT))) { ir_ref prop_info_ref = ir_LOAD_A( - ir_ADD_OFFSET(run_time_cache, ((opline+1)->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2)); + ir_ADD_OFFSET(run_time_cache, ((opline+1)->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) + sizeof(void*) * 2)); ir_ref if_has_prop_info = ir_IF(prop_info_ref); ir_IF_TRUE_cold(if_has_prop_info); ir_END_list(slow_inputs); @@ -15249,7 +15249,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, ir_IF_FALSE(if_has_prop_info); } ir_ref offset_ref = ir_LOAD_A( - ir_ADD_OFFSET(run_time_cache, ((opline+1)->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*))); + ir_ADD_OFFSET(run_time_cache, ((opline+1)->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) + sizeof(void*))); ir_ref if_dynamic = ir_IF(ir_LT(offset_ref, ir_CONST_ADDR(ZEND_FIRST_PROPERTY_OFFSET))); ir_IF_TRUE_cold(if_dynamic); @@ -15508,7 +15508,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, obj_ref, ir_CONST_ADDR(name), arg3, - ir_ADD_OFFSET(run_time_cache, (opline+1)->extended_value & ~ZEND_FETCH_OBJ_FLAGS), + ir_ADD_OFFSET(run_time_cache, (opline+1)->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS), ir_CONST_FC_FUNC(binary_op)); ir_END_list(end_inputs); @@ -15655,7 +15655,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, if (!prop_info) { ir_ref run_time_cache = ir_LOAD_A(jit_EX(run_time_cache)); - ir_ref ref = ir_LOAD_A(ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS)); + ir_ref ref = ir_LOAD_A(ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS)); ir_ref if_same = ir_IF(ir_EQ(ref, ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_object, ce))))); ir_IF_FALSE_cold(if_same); @@ -15664,7 +15664,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, ir_IF_TRUE(if_same); if (!ce || ce_is_instanceof || (ce->ce_flags & (ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_TRAIT))) { ir_ref prop_info_ref = ir_LOAD_A( - ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2)); + ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) + sizeof(void*) * 2)); ir_ref if_has_prop_info = ir_IF(prop_info_ref); ir_IF_TRUE_cold(if_has_prop_info); ir_END_list(slow_inputs); @@ -15672,7 +15672,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, ir_IF_FALSE(if_has_prop_info); } ir_ref offset_ref = ir_LOAD_A( - ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*))); + ir_ADD_OFFSET(run_time_cache, (opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS) + sizeof(void*))); ir_ref if_dynamic = ir_IF(ir_LT(offset_ref, ir_CONST_ADDR(ZEND_FIRST_PROPERTY_OFFSET))); ir_IF_TRUE_cold(if_dynamic); @@ -15993,7 +15993,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, ir_CALL_4(IR_VOID, ir_CONST_FC_FUNC(func), obj_ref, ir_CONST_ADDR(name), - ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS), + ir_ADD_OFFSET(run_time_cache, opline->extended_value & ~ZEND_ASSIGN_OBJ_FLAGS), (opline->result_type == IS_UNUSED) ? IR_NULL : jit_ZVAL_ADDR(jit, res_addr)); ir_END_list(end_inputs);