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