1--TEST--
2Test interaction with cache slots
3--FILE--
4<?php
5
6class Test {
7    public readonly string $prop;
8    public readonly array $prop2;
9    public readonly object $prop3;
10    public function setProp(string $prop) {
11        $this->prop = $prop;
12    }
13    public function initAndAppendProp2() {
14        $this->prop2 = [];
15        $this->prop2[] = 1;
16    }
17    public function initProp3() {
18        $this->prop3 = new stdClass;
19        $this->prop3->foo = 1;
20    }
21    public function replaceProp3() {
22        $ref =& $this->prop3;
23        $ref = new stdClass;
24    }
25}
26
27$test = new Test;
28$test->setProp("a");
29var_dump($test->prop);
30try {
31    $test->setProp("b");
32} catch (Error $e) {
33    echo $e->getMessage(), "\n";
34}
35var_dump($test->prop);
36echo "\n";
37
38$test = new Test;
39try {
40    $test->initAndAppendProp2();
41} catch (Error $e) {
42    echo $e->getMessage(), "\n";
43}
44try {
45    $test->initAndAppendProp2();
46} catch (Error $e) {
47    echo $e->getMessage(), "\n";
48}
49var_dump($test->prop2);
50echo "\n";
51
52$test = new Test;
53$test->initProp3();
54$test->replaceProp3();
55var_dump($test->prop3);
56$test->replaceProp3();
57var_dump($test->prop3);
58echo "\n";
59
60// Test variations using closure rebinding, so we have unknown property_info in JIT.
61$test = new Test;
62(function() { $this->prop2 = []; })->call($test);
63$appendProp2 = (function() {
64    $this->prop2[] = 1;
65})->bindTo($test, Test::class);
66try {
67    $appendProp2();
68} catch (Error $e) {
69    echo $e->getMessage(), "\n";
70}
71try {
72    $appendProp2();
73} catch (Error $e) {
74    echo $e->getMessage(), "\n";
75}
76var_dump($test->prop2);
77echo "\n";
78
79$test = new Test;
80$replaceProp3 = (function() {
81    $ref =& $this->prop3;
82    $ref = new stdClass;
83})->bindTo($test, Test::class);
84$test->initProp3();
85$replaceProp3();
86var_dump($test->prop3);
87$replaceProp3();
88var_dump($test->prop3);
89
90?>
91--EXPECTF--
92string(1) "a"
93Cannot modify readonly property Test::$prop
94string(1) "a"
95
96Cannot indirectly modify readonly property Test::$prop2
97Cannot modify readonly property Test::$prop2
98array(0) {
99}
100
101object(stdClass)#%d (1) {
102  ["foo"]=>
103  int(1)
104}
105object(stdClass)#%d (1) {
106  ["foo"]=>
107  int(1)
108}
109
110Cannot indirectly modify readonly property Test::$prop2
111Cannot indirectly modify readonly property Test::$prop2
112array(0) {
113}
114
115object(stdClass)#%d (1) {
116  ["foo"]=>
117  int(1)
118}
119object(stdClass)#%d (1) {
120  ["foo"]=>
121  int(1)
122}
123