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(x : any)
21{
22    return x;
23}
24
25function doAdd(x : any) {
26    return mySet.add(x);
27}
28
29function printAdd(x : any) {
30    try {
31        print(doAdd(x));
32    } finally {
33    }
34}
35
36function tryAdd(x: any, y : any) {
37    try {
38        print(x.add(y));
39    } finally {
40    }
41}
42
43let mySet = new Set();
44
45// Check without params
46print(mySet.add());
47//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
48//: [object Set]
49print(mySet.size);
50//: 1
51print(mySet.has(undefined));
52//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
53//: true
54
55// Check with single param
56mySet.add(125);
57//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
58print(mySet.size);
59//: 2
60print(mySet.has(125));
61//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
62//: true
63
64// Check with 2 params
65mySet.add(0, undefined);
66//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
67print(mySet.size);
68//: 3
69print(mySet.has(0));
70//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
71//: true
72
73// Check with 3 params
74mySet.add(0, "ab", 14);
75//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
76print(mySet.size);
77//: 3
78print(mySet.has(0));
79//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
80//: true
81
82
83// Call standard builtin with non-number param
84mySet.add("abc");
85//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
86print(mySet.has("abc"));
87//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
88//: true
89
90
91let true_add = mySet.add
92mySet.add = replace
93
94print(mySet.add(12)) //: 12
95
96mySet.add = true_add
97
98//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
99print(mySet.add(12)) //: [object Set]
100//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
101print(mySet.add(12)) //: [object Set]
102
103print(mySet.has(12));
104//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
105//: true
106
107if (ArkTools.isAOTCompiled(printAdd)) {
108    // Replace standard builtin after call to standard builtin was profiled
109    mySet.add = replace
110}
111
112printAdd(42);
113//pgo: [object Set]
114//aot: [trace] Check Type: NotCallTarget1
115//aot: 42
116print(mySet.has(42));
117//pgo: true
118//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
119//aot: false
120
121mySet.add = true_add
122
123print(mySet.add("xyz"));
124//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
125//: [object Set]
126print(mySet.has("xyz"));
127//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
128//: true
129
130// Check IR correctness inside try-block
131try {
132    printAdd(2.5);
133    //aot: [trace] aot inline builtin: Set.add, caller function name:#*#doAdd@builtinSetAdd
134    //: [object Set]
135    printAdd("oops");
136    //aot: [trace] aot inline builtin: Set.add, caller function name:#*#doAdd@builtinSetAdd
137    //: [object Set]
138    print(mySet.has(2.5));
139    //aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
140    //: true
141    print(mySet.has("oops"));
142    //aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
143    //: true
144} catch (e) {
145}
146
147// Specific object
148let obj = {};
149obj.valueOf = (() => { return 7; })
150
151mySet.add(obj);
152//aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
153print(mySet.has(obj));
154//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
155//: true
156print(mySet.has(7));
157//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
158//: false
159mySet.clear();
160//aot: [trace] aot inline builtin: Set.clear, caller function name:func_main_0@builtinSetAdd
161
162let throwingObj = new Throwing();
163try {
164    mySet.add(throwingObj);
165    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
166    print(mySet.has(throwingObj));
167    //aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
168    //: true
169    print(mySet.has(2));
170    //aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
171    //: false
172} catch(e) {
173    print(e);
174} finally {
175    mySet.add(obj);
176    //aot: [trace] aot inline builtin: Set.add, caller function name:func_main_0@builtinSetAdd
177    print(mySet.has(obj));
178    //aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
179    //: true
180    print(mySet.has(7));
181    //aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
182    //: false
183}
184
185function checkObjWithSetProto() {
186    let o = {};
187    Object.setPrototypeOf(o, Set.prototype);
188    try {
189        o.add(1);
190    } catch(e) {
191        print(e);
192    }
193}
194
195//aot: [trace] Check Type: NotCallTarget1
196//: TypeError: obj is not JSSet
197checkObjWithSetProto();
198
199function Throwing() {
200    this.value = 2;
201    Throwing.prototype.valueOf = function() {
202        if (this.value > 0) {
203            throw new Error("positive");
204        }
205        return this.value;
206    }
207}
208
209let m = new Set();
210
211print("baseline"); //: baseline
212let m2 = new Set([1]);
213let m3 = new Set([1]);
214let m4 = new Set([1]);
215
216tryAdd(m, 13);
217//aot: [trace] aot inline builtin: Set.add, caller function name:#*#tryAdd@builtinSetAdd
218//: [object Set]
219print(m.has(13));
220//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
221//: true
222
223tryAdd(m2, 13);
224//aot: [trace] aot inline builtin: Set.add, caller function name:#*#tryAdd@builtinSetAdd
225//: [object Set]
226print(m2.has(13));
227//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
228//: true
229
230tryAdd(m3, 13);
231//aot: [trace] aot inline builtin: Set.add, caller function name:#*#tryAdd@builtinSetAdd
232//: [object Set]
233print(m3.has(13));
234//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
235//: true
236
237tryAdd(m4, 13);
238//aot: [trace] aot inline builtin: Set.add, caller function name:#*#tryAdd@builtinSetAdd
239//: [object Set]
240print(m4.has(13));
241//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
242//: true
243
244print("case 0"); //: case 0
245if (ArkTools.isAOTCompiled(tryAdd)) {
246    m4.garbage = function(x: any) {
247        return undefined;
248    }
249}
250
251// Nothing changed
252tryAdd(m, 25);
253//aot: [trace] aot inline builtin: Set.add, caller function name:#*#tryAdd@builtinSetAdd
254//: [object Set]
255print(m.has(25));
256//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
257//: true
258
259tryAdd(m2, 25);
260//aot: [trace] aot inline builtin: Set.add, caller function name:#*#tryAdd@builtinSetAdd
261//: [object Set]
262print(m2.has(25));
263//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
264//: true
265
266tryAdd(m3, 25);
267//aot: [trace] aot inline builtin: Set.add, caller function name:#*#tryAdd@builtinSetAdd
268//: [object Set]
269print(m3.has(25));
270//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
271//: true
272
273tryAdd(m4);
274//aot: [trace] Check Type: BuiltinInstanceHClassMismatch
275//: [object Set]
276print(m3.has(25));
277//aot: [trace] aot inline builtin: Set.has, caller function name:func_main_0@builtinSetAdd
278//: true
279