1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16declare function print(arg: any): string;
17
18class A {
19    #a_: number;
20    constructor() {
21        this.#a_ = 0;
22    }
23    get #a() {
24        return this.#a_;
25    }
26    set #a(v) {
27        this.#a_ = v;
28    }
29    foo() {
30        return this.#a;
31    }
32    bar() {
33        this.#a = 1;
34    }
35}
36
37for (let i = 0; i < 5; i++) {
38    let a = new A();
39    print(a.foo());
40    a.bar();
41    print(a.foo());
42}
43
44// hcdata with object (phc)
45class B {}
46B.prototype.foo = function () {
47    return 1;
48};
49
50// primitive symbol no pgo
51const symbol = Symbol();
52const namedSymbol = Symbol("symbol");
53print(symbol.toString());
54print(namedSymbol.toString());
55
56class BitwiseAnd {
57    #setterCalledWith: number = 0;
58    get #field() {
59        return 0b010111;
60    }
61    set #field(value) {
62        this.#setterCalledWith = value;
63    }
64    compoundAssignment() {
65        return this.#field &= 0b101011;
66    }
67    setterCalledWithValue() {
68        return this.#setterCalledWith;
69    }
70}
71
72const o = new BitwiseAnd();
73// Check that CALL_PRIVATE_GETTER/CALL_PRIVATE_SETTER are processed correctly in NumberSpeculativeRetype
74print(o.compoundAssignment());
75print(o.setterCalledWithValue());
76
77// Test if the `slotid` is read correctly in the `ldprivateproperty`/`stprivateproperty`
78function testReadIcSlotInPrivatePropertyIns() {
79    let a;
80    class C3 {
81        #b;
82        constructor() {
83            this.#b = Uint8Array;
84            this.#b = Uint8Array;
85            this.#b = Uint8Array;
86            this.#b = Uint8Array;
87            this.#b = Uint8Array;
88            this.#b = Uint8Array;
89            this.#b = Uint8Array;
90            this.#b = Uint8Array;
91            this.#b = Uint8Array;
92            this.#b = Uint8Array;
93            this.#b = Uint8Array;
94            this.#b = Uint8Array;
95            this.#b = Uint8Array;
96            this.#b = Uint8Array;
97            this.#b = Uint8Array;
98            this.#b = Uint8Array;
99            this.#b = Uint8Array;
100            this.#b = Uint8Array;
101            this.#b = Uint8Array;
102            this.#b = Uint8Array;
103            this.#b = Uint8Array;
104            this.#b = Uint8Array;
105            this.#b = Uint8Array;
106            this.#b = Uint8Array;
107            this.#b = Uint8Array;
108            this.#b = Uint8Array;
109            this.#b = Uint8Array;
110            this.#b = Uint8Array;
111            this.#b = Uint8Array;
112            this.#b = Uint8Array;
113            this.#b = Uint8Array;
114            this.#b = Uint8Array;
115            this.#b = Uint8Array;
116            this.#b = Uint8Array;
117            this.#b = Uint8Array;
118            this.#b = Uint8Array;
119            this.#b = Uint8Array;
120            this.#b = Uint8Array;
121            this.#b = Uint8Array;
122            this.#b = Uint8Array;
123            this.#b = Uint8Array;
124            this.#b = Uint8Array;
125            this.#b = Uint8Array;
126            this.#b = Uint8Array;
127            this.#b = Uint8Array;
128            this.#b = Uint8Array;
129            this.#b = Uint8Array;
130            this.#b = Uint8Array;
131            this.#b = Uint8Array;
132            this.#b = Uint8Array;
133            this.#b = Uint8Array;
134            this.#b = Uint8Array;
135            this.#b = Uint8Array;
136            this.#b = Uint8Array;
137            this.#b = Uint8Array;
138            this.#b = Uint8Array;
139            a = this.#b;
140        }
141    }
142
143    new C3();
144    print("testReadIcSlotInPrivatePropertyIns success")
145}
146
147testReadIcSlotInPrivatePropertyIns();
148
149// Invalid private key check for ldPrivateProperty
150const v1 = [1];
151const v2 = [2];
152class C {
153    #m(x) {
154        x[0] = this;
155        return this;
156    }
157    constructor() {
158        try {
159            v1.#m(v2);
160        } catch(e) {
161            print(e.name + " : " + e.message);
162        }
163    }
164}
165const v3 = new C();
166
167// Invalid private key check for stPrivateProperty
168class OutSide {
169    #x = 42;
170  
171    innerclass() {
172      return class {
173        f() {
174          this.#x = 1;
175        }
176      }
177    }
178  }
179  
180  var Inner = new OutSide().innerclass();
181  var i = new Inner();
182  
183  try {
184    i.f();
185  } catch(e) {
186    print(e.name + " : " + e.message);
187}
188
189// Invalid private key check for ldPrivateProperty2
190let createClass = function () {
191    return class {
192      static #m = 111;
193  
194      static access() {
195        return this.#m;
196      }
197    }
198};
199  
200let C1 = createClass(); 
201let C2 = createClass();
202try {
203    C2.access();
204    C1.access.call(C2); // C2 try to access private property of C1, forbidden
205} catch(e) {
206    print(e)
207}
208
209// Invalid private key check for stPrivateProperty2
210let createClass2 = function () {
211    return class {
212      static #m = 111;
213  
214      static store() {
215        return this.#m = 11;
216      }
217    }
218  };
219  
220  let C3 = createClass2(); 
221  let C4 = createClass2();
222  
223try {
224    C3.store();
225    C4.store.call(C3); // C3 try to access private property of C4, forbidden
226} catch(e) {
227    print(e)
228}