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 printZero(x: any) {
26    if (Object.is(x, -0)) {
27        print("-0");
28    } else {
29        print(x);
30    }
31}
32
33function doRound(x: any): number {
34    return Math.round(x);
35}
36
37function printRound(x: any) {
38    try {
39        print(doRound(x));
40    } finally {
41    }
42}
43
44// Check without params
45//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
46print(Math.round()); //: NaN
47
48// Check with single int param
49//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
50print(Math.round(0)); //: 0
51//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
52print(Math.round(3)); //: 3
53//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
54print(Math.round(-5)); //: -5
55
56// Test large ints
57//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
58print(Math.round(1073741824)) //: 1073741824
59//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
60print(Math.round(1073741804)) //: 1073741804
61//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
62print(Math.round(1073741784)) //: 1073741784
63//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
64print(Math.round(-1073741804)) //: -1073741804
65
66// Check with single float param
67//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
68print(Math.round(1.9e80)); //: 1.9e+80
69//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
70//aot: [trace] aot inline function name: #*#printZero@builtinMathRound caller function name: func_main_0@builtinMathRound
71//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
72printZero(Math.round(2.5)); //: 3
73//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
74//aot: [trace] aot inline function name: #*#printZero@builtinMathRound caller function name: func_main_0@builtinMathRound
75//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
76printZero(Math.round(1.5)); //: 2
77//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
78//aot: [trace] aot inline function name: #*#printZero@builtinMathRound caller function name: func_main_0@builtinMathRound
79//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
80printZero(Math.round(0.5)); //: 1
81//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
82//aot: [trace] aot inline function name: #*#printZero@builtinMathRound caller function name: func_main_0@builtinMathRound
83//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
84printZero(Math.round(0.2)); //: 0
85//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
86//aot: [trace] aot inline function name: #*#printZero@builtinMathRound caller function name: func_main_0@builtinMathRound
87//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
88printZero(Math.round(-0)); //: -0
89//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
90//aot: [trace] aot inline function name: #*#printZero@builtinMathRound caller function name: func_main_0@builtinMathRound
91//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
92printZero(Math.round(-1.9e-80)); //: -0
93//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
94//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
95printZero(Math.round(-0.1)); //: -0
96//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
97//aot: [trace] aot inline builtin: Object.is, caller function name:#*#printZero@builtinMathRound
98printZero(Math.round(-0.5)); //: -0
99//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
100print(Math.round(-0.7)); //: -1
101//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
102print(Math.round(-1.2)); //: -1
103//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
104print(Math.round(-1.5)); //: -1
105//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
106print(Math.round(-2.1)); //: -2
107//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
108print(Math.round(-2.49)); //: -2
109//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
110print(Math.round(-2.5)); //: -2
111//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
112print(Math.round(-2.7)); //: -3
113//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
114print(Math.round(-1.9e80)); //: -1.9e+80
115//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
116print(Math.round(1.9e-80)); //: 0
117//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
118print(Math.round(0.5 - Number.EPSILON / 4)); //: 0
119
120
121// Check with special float params
122//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
123print(Math.round(Infinity)); //: Infinity
124//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
125print(Math.round(-Infinity)); //: -Infinity
126//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
127print(Math.round(NaN)); //: NaN
128
129// Check with 2 params
130//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
131print(Math.round(3, 0)); //: 3
132
133// Check with 3 params
134//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
135print(Math.round(-3.5, 0, 0)); //: -3
136
137// Check with 4 params
138//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
139print(Math.round(4.1, 0, 0, 0)); //: 4
140
141// Check with 5 params
142//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
143print(Math.round(-4.1, 0, 0, 0, 0)); //: -4
144
145// Replace standard builtin
146let true_round = Math.round
147Math.round = replace
148
149// no deopt
150print(Math.round(-1.001)); //: -1.001
151Math.round = true_round
152
153//aot: [trace] aot inline builtin: Math.round, caller function name:#*#doRound@builtinMathRound
154printRound(12.3); //: 12
155// Call standard builtin with non-number param
156//aot: [trace] aot inline builtin: Math.round, caller function name:#*#doRound@builtinMathRound
157//aot: [trace] Check Type: NotNumber2
158printRound("abc"); //: NaN
159//aot: [trace] aot inline builtin: Math.round, caller function name:#*#doRound@builtinMathRound
160//aot: [trace] Check Type: NotNumber2
161printRound("-12.9"); //: -13
162
163if (ArkTools.isAOTCompiled(printRound)) {
164    // Replace standard builtin after call to standard builtin was profiled
165    Math.round = replace
166}
167printRound(-12.2); //pgo: -12
168//aot: [trace] Check Type: NotCallTarget1
169//aot: -12.2
170
171printRound("abc"); //pgo: NaN
172//aot: [trace] Check Type: NotCallTarget1
173//aot: abc
174
175Math.round = true_round
176
177// Check IR correctness inside try-block
178try {
179    //aot: [trace] aot inline builtin: Math.round, caller function name:#*#doRound@builtinMathRound
180    printRound(0.3) //: 0
181    //aot: [trace] aot inline builtin: Math.round, caller function name:#*#doRound@builtinMathRound
182    printRound(-12); //: -12
183    //aot: [trace] aot inline builtin: Math.round, caller function name:#*#doRound@builtinMathRound
184    //aot: [trace] Check Type: NotNumber2
185    printRound("abc"); //: NaN
186} catch (e) {
187}
188
189let obj = {
190    valueOf: () => { return -22.5; }
191};
192//aot: [trace] aot inline builtin: Math.round, caller function name:func_main_0@builtinMathRound
193//aot: [trace] Check Type: NotNumber2
194print(Math.round(obj)); //: -22
195