1/*
2 * Copyright (c) 2024 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 interface ArkTools {
17    isAOTCompiled(args: any): boolean;
18}
19declare function print(arg:any):string;
20function replace()
21{
22    return "replaced";
23}
24
25function doClear(): any {
26    print(mySet.size);
27    print(mySet.clear());
28    print(mySet.size);
29}
30
31function printClear() {
32    try {
33        doClear();
34    } finally {
35    }
36}
37
38function printClear2(x: any) {
39    try {
40        print(x.clear());
41    } finally {
42    }
43}
44
45let mySet = new Set([0, -5, 2.5]);
46
47// Check without params
48print(mySet.size); //: 3
49//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
50print(mySet.clear()); //: undefined
51print(mySet.size); //: 0
52
53// Check with single param
54let mySet1 = new Set([0, -5, 2.5]);
55print(mySet1.size); //: 3
56//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
57print(mySet1.clear(125)); //: undefined
58print(mySet1.size); //: 0
59
60// Check with 2 params
61let mySet2 = new Set([0, -5, 2.5]);
62print(mySet2.size); //: 3
63//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
64print(mySet2.clear(0, undefined)); //: undefined
65print(mySet2.size); //: 0
66
67mySet.add(0);
68//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
69mySet.add(12);
70//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
71
72// Replace standard builtin
73let true_clear = mySet.clear
74mySet.clear = replace
75// no deopt
76print(mySet.clear()); //: replaced
77
78mySet.clear = true_clear
79printClear(); //: 2
80              //aot: [trace] aot inline builtin: Set.clear, caller function name:#*#doClear@builtinSetClear
81              //: undefined
82              //: 0
83
84// Call standard builtin with non-number param
85mySet.add(0);
86//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
87mySet.add(12);
88//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
89print(mySet.size); //: 2
90//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
91mySet.clear("abc");
92print(mySet.size); //: 0
93
94if (ArkTools.isAOTCompiled(printClear)) {
95    // Replace standard builtin after call to standard builtin was profiled
96    mySet.clear = replace
97}
98
99mySet.add(0);
100//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
101mySet.add(12);
102//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
103printClear(); //: 2
104              //aot: [trace] Check Type: NotCallTarget1
105              //pgo: undefined
106              //pgo: 0
107              //aot: replaced
108              //aot: 2
109
110mySet.clear = true_clear
111//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
112mySet.clear();
113
114// Check IR correctness inside try-block
115try {
116    mySet.add(0);
117    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
118    mySet.add(12);
119    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
120    printClear(); //: 2
121                  //aot: [trace] aot inline builtin: Set.clear, caller function name:#*#doClear@builtinSetClear
122                  //: undefined
123                  //: 0
124} catch (e) {
125}
126
127let obj = {};
128obj.valueOf = (() => { return 0; })
129
130mySet.add(0);
131//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
132mySet.add(12);
133//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
134print(mySet.size); //: 2
135//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
136print(mySet.clear(obj)); //: undefined
137print(mySet.size); //: 0
138
139function Throwing() {
140    this.value = 2;
141    Throwing.prototype.valueOf = function() {
142        if (this.value > 0) {
143            throw new Error("positive");
144        }
145        return this.value;
146    }
147}
148
149let throwingObj = new Throwing();
150try {
151    mySet.add(0);
152    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
153    mySet.add(12);
154    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
155    print(mySet.size); //: 2
156    //aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
157    print(mySet.clear(throwingObj)); //: undefined
158    print(mySet.size); //: 0
159} catch(e) {
160    print(e);
161} finally {
162    mySet.add(0);
163    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
164    mySet.add(12);
165    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
166
167    print(mySet.size); //: 2
168    //aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
169    print(mySet.clear(obj)); //: undefined
170    print(mySet.size); //: 0
171}
172
173let trueclear = Set.prototype.clear;
174let m = new Set();
175m.add(1);
176//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
177m.add(2);
178//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
179m.add("ab");
180//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
181m.add("cd");
182//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
183let obj1 = {};
184m.add(obj1);
185//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
186
187print(m.size); //: 5
188//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetClear
189m.clear();
190print(m.size); //: 0
191
192print("baseline"); //: baseline
193m.add(20);
194//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
195let m2 = new Set([1]);
196let m3 = new Set([1]);
197let m4 = new Set([1]);
198
199print(m.size); //: 1
200//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
201printClear2(m) //: undefined
202print(m.size); //: 0
203
204print(m2.size); //: 1
205//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
206printClear2(m2) //: undefined
207print(m2.size); //: 0
208
209print(m3.size); //: 1
210//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
211printClear2(m3) //: undefined
212print(m3.size); //: 0
213
214print(m4.size); //: 1
215//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
216printClear2(m4) //: undefined
217print(m4.size); //: 0
218
219print("case 0"); //: case 0
220if (ArkTools.isAOTCompiled(printClear2)) {
221    m4.garbage = function(x: any) {
222        return undefined;
223    }
224}
225
226// Nothing changed
227m.add(20);
228//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
229m2.add(20);
230//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
231m3.add(20);
232//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetClear
233m4.add(20); //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
234
235print(m.size); //: 1
236//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
237printClear2(m) //: undefined
238print(m.size); //: 0
239
240print(m2.size); //: 1
241//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
242printClear2(m2) //: undefined
243print(m2.size); //: 0
244
245print(m3.size); //: 1
246//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
247printClear2(m3) //: undefined
248print(m3.size); //: 0
249
250print(m4.size); //: 1
251printClear2(m4) //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
252                //: undefined
253print(m4.size); //: 0
254
255print("case 1"); //: case 1
256if (ArkTools.isAOTCompiled(printClear2)) {
257    m3.clear = function() {
258        return false;
259    }
260}
261
262m.add(20);
263m2.add(20);
264m3.add(20);
265
266print(m.size); //: 1
267//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
268printClear2(m) //: undefined
269print(m.size); //: 0
270
271print(m3.size); //: 1
272printClear2(m3) //pgo: undefined
273                //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
274                //aot: false
275print(m3.size); //pgo: 0
276                //aot: 1
277
278print("case 2"); //: case 2
279let mimicSet = {
280    clear: trueclear
281}
282let mm = new Set([1]);
283
284print(mm.size); //: 1
285//aot: [trace] aot inline builtin: Set.clear, caller function name:#*#printClear2@builtinSetClear
286printClear2(mm) //: undefined
287print(m.size);  //: 0
288
289function checkObjWithSetProto() {
290    let o = {};
291    Object.setPrototypeOf(o, Set.prototype);
292    try {
293        o.clear(1);
294    } catch(e) {
295        print(e);
296    }
297}
298
299//aot: [trace] Check Type: NotCallTarget1
300//: TypeError: obj is not JSSet
301checkObjWithSetProto();
302
303if (ArkTools.isAOTCompiled(printClear2)) {
304    Object.setPrototypeOf(mm, mimicSet)
305}
306
307printClear2(mm) //aot: [trace] Check Type: BuiltinInstanceHClassMismatch
308                //: undefined
309
310print("case 3") //: case 3
311if (ArkTools.isAOTCompiled(printClear2)) {
312    Set.prototype.clear = function(x: any) {
313        return "prototype";
314    }
315}
316
317m.add(20);
318m2.add(20);
319m3.add(20);
320
321print(m.size);  //: 1
322printClear2(m); //pgo: undefined
323                //aot: [trace] Check Type: NotCallTarget1
324                //aot: prototype
325print(m.size);  //pgo: 0
326                //aot: 1
327
328print(m2.size);  //: 1
329printClear2(m2); //pgo: undefined
330                 //aot: [trace] Check Type: NotCallTarget1
331                 //aot: prototype
332print(m2.size);  //pgo: 0
333                 //aot: 1
334