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;
20
21function printZero(x: any) {
22    if (Object.is(x, -0)) {
23        print("-0");
24    } else {
25        print(x);
26    }
27}
28
29function replace(a : number)
30{
31    return a;
32}
33
34// Use try to prevent inlining to main
35function printExp(x: any) {
36    try {
37        print(Math.exp(x));
38    } finally {
39    }
40}
41
42let doubleObj = {
43    valueOf: () => { return 2.7; }
44}
45
46let nanObj = {
47    valueOf: () => { return "something"; }
48}
49
50let obj = {
51    valueOf: () => {
52        print("obj.valueOf")
53        return -23;
54    }
55};
56
57// Check without params
58//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
59print(Math.exp()); //: NaN
60
61// Check with single param
62//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
63print(Math.exp(0)); //: 1
64//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
65print(Math.exp(-0)); //: 1
66//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
67print(Math.exp(1)); //: 2.718281828459045
68//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
69print(Math.exp(-100)); //: 3.720075976020836e-44
70//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
71print(Math.exp(100)); //: 2.6881171418161356e+43
72//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
73print(Math.exp(10e-10)); //: 1.000000001
74
75// Check with special float params
76//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
77//aot: [trace] aot inline function name: #*#printZero@builtinMathExp caller function name: func_main_0@builtinMathExp
78//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathExp
79printZero(Math.exp(-Infinity)); //: 0
80//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
81print(Math.exp(Infinity)); //: Infinity
82//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
83print(Math.exp(NaN)); //: NaN
84
85// Check with 2 params
86//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
87print(Math.exp(1, 1)); //: 2.718281828459045
88
89// Check with 3 params
90//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
91print(Math.exp(1, 1, 1)); //: 2.718281828459045
92
93// Check with 4 params
94//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
95print(Math.exp(1, 1, 1, 1)); //: 2.718281828459045
96
97// Check with 5 params
98//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
99print(Math.exp(1, 1, 1, 1, 1)); //: 2.718281828459045
100
101try {
102    //aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinMathExp
103    print(Math.exp(1)); //: 2.718281828459045
104} catch(e) {}
105
106// Replace standart builtin
107let trueExp = Math.exp
108Math.exp = replace
109print(Math.exp(111)); //: 111
110Math.exp = trueExp
111
112//aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
113printExp(1); //: 2.718281828459045
114
115// Call standart builtin with non-number param
116//aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
117//aot: [trace] Check Type: NotNumber1
118printExp("1"); //: 2.718281828459045
119//aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
120//aot: [trace] Check Type: NotNumber1
121printExp("NaN"); //: NaN
122//aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
123//aot: [trace] Check Type: NotNumber1
124printExp("abc"); //: NaN
125
126if (ArkTools.isAOTCompiled(printExp)) {
127    // Replace standard builtin after call to standard builtin was profiled
128    Math.exp = replace
129}
130
131printExp(1); //pgo: 2.718281828459045
132//aot: [trace] Check Type: NotCallTarget1
133//aot: 1
134
135printExp(2); //pgo: 7.38905609893065
136//aot: [trace] Check Type: NotCallTarget1
137//aot: 2
138
139printExp("1"); //pgo: 2.718281828459045
140//aot: [trace] Check Type: NotCallTarget1
141//aot: 1
142
143printExp("2"); //pgo: 7.38905609893065
144//aot: [trace] Check Type: NotCallTarget1
145//aot: 2
146
147Math.exp = trueExp
148
149// Check IR correctness inside try-block
150try {
151    //aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
152    printExp(1); //: 2.718281828459045
153    //aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
154    printExp(1, 2); //: 2.718281828459045
155    //aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
156    printExp(1, 2); //: 2.718281828459045
157    //aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
158    //aot: [trace] Check Type: NotNumber1
159    printExp("abc", 3e3); //: NaN
160} catch (e) {
161}
162
163//aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
164//aot: [trace] Check Type: NotNumber1
165//: obj.valueOf
166printExp(obj); //: 1.026187963170189e-10
167//aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
168//aot: [trace] Check Type: NotNumber1
169printExp(doubleObj); //: 14.879731724872837
170//aot: [trace] aot inline builtin: Math.exp, caller function name:#*#printExp@builtinMathExp
171//aot: [trace] Check Type: NotNumber1
172printExp(nanObj); //: NaN
173