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
25// Several params:
26//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
27print(Math.sign(3, -0.12)) //: 1
28//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
29print(Math.sign(-3, 0.12)) //: -1
30//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
31print(Math.sign(-3, 0.12, -0.0)) //: -1
32//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
33print(Math.sign(-4, 0.12, -0.0, 0.0)) //: -1
34
35//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
36print(Math.sign(3)) //: 1
37//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
38print(Math.sign(-3)) //: -1
39
40// Test +0.0 and -0.0
41// 0.0 and -0.0:
42//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
43print(1 / Math.sign(0)) //: Infinity
44//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
45print(1 / Math.sign(-0)) //: -Infinity
46
47// Infinities
48//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
49print(Math.sign(-Infinity)) //: -1
50//aot: [trace] aot inline builtin: Math.sign, caller function name:func_main_0@builtinMathSign
51print(Math.sign(Infinity)) //: 1
52
53// Replace, no deopt
54let trueSign = Math.sign
55Math.sign = replace
56print(Math.sign(-12)) //: -12
57Math.sign = trueSign
58
59// Replace for the callee:
60function doSign(a : any): number
61{
62    return Math.sign(a)
63}
64
65function printSign(a: any)
66{
67    try {
68        print(doSign(a))
69    } finally {
70    }
71}
72
73// Check:
74//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
75printSign(1) //: 1
76//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
77printSign(Math.PI) //: 1
78//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
79printSign(-Math.PI) //: -1
80//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
81printSign(NaN) //: NaN
82//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
83printSign(-1.5) //: -1
84//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
85printSign(Infinity) //: 1
86
87if (ArkTools.isAOTCompiled(printSign)) {
88    // Replace standard builtin after call to standard builtin was profiled
89    Math.sign = replace
90}
91
92// Check deopt from compiled
93printSign(2)         //pgo: 1
94//aot: [trace] Check Type: NotCallTarget1
95//aot: 2
96
97printSign(-Math.PI)  //pgo: -1
98//aot: [trace] Check Type: NotCallTarget1
99//aot: -3.141592653589793
100
101Math.sign = trueSign
102let obj = {};
103obj.valueOf = (() => { return -23; })
104//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
105//aot: [trace] Check Type: NotNumber2
106printSign(obj);      //: -1
107//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
108printSign(-1.5)      //: -1
109//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
110printSign(Infinity)  //: 1
111
112class C {
113    constructor() {
114        return Math.sign("3");
115    }
116}
117
118//aot: [trace] aot inline builtin: Math.sign, caller function name:#~C=#C@builtinMathSign
119//aot: [trace] Check Type: NotNumber2
120new C();
121
122// Check IR correctness inside try-block
123try {
124    //aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
125    printSign(-12) //: -1
126    //aot: [trace] aot inline builtin: Math.sign, caller function name:#*#doSign@builtinMathSign
127    //aot: [trace] Check Type: NotNumber2
128    printSign("-12") //: -1
129} catch (e) {
130    print(e)
131}
132
133function Throwing() {
134    this.value = -14;
135}
136Throwing.prototype.valueOf = function() {
137    if (this.value > 0) {
138        throw new Error("exception");
139    }
140    return this.value;
141}
142let throwingObj = new Throwing();
143
144function tryCatchTest(obj: any, v : number)
145{
146    try {
147        let x = obj.valueOf(); // exception
148        print(Math.sign(x));
149        print(Math.sign(v));
150    } catch(e) {
151        print(e);
152        print(Math.sign(-v));
153    } finally {
154        print(Math.sign(0)); // 0
155    }
156}
157
158// Test try-catch-deopt 1
159tryCatchTest(throwingObj, ArkTools.isAOTCompiled(tryCatchTest) * 1)
160//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#tryCatchTest@builtinMathSign
161//: -1
162//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#tryCatchTest@builtinMathSign
163//pgo: 0
164//aot: 1
165//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#tryCatchTest@builtinMathSign
166//: 0
167
168// Test try-catch-deopt 2
169throwingObj.value = 14
170tryCatchTest(throwingObj, ArkTools.isAOTCompiled(tryCatchTest) * 1)
171//: Error: exception
172//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#tryCatchTest@builtinMathSign
173//pgo: 0
174//aot: -1
175//aot: [trace] aot inline builtin: Math.sign, caller function name:#*#tryCatchTest@builtinMathSign
176//: 0
177