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 function print(arg:any):string;
17declare interface ArkTools {
18    isAOTCompiled(args: any): boolean;
19}
20function replace(a : number)
21{
22    return a;
23}
24
25function doCbrt(x: any): number {
26    return Math.cbrt(x);
27}
28
29function printCbrt(x: any) {
30    try {
31        print(doCbrt(x));
32    } finally {
33    }
34}
35
36let res:number = 1;
37
38// Check without params
39//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
40print(Math.cbrt()); //: NaN
41
42// Check with single param
43//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
44print(Math.cbrt(-0.027)); //: -0.29999999999999993
45//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
46print(Math.cbrt(0.125)); //: 0.49999999999999994
47//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
48print(Math.cbrt(1)); //: 1
49//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
50print(Math.cbrt(8)); //: 2
51//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
52print(Math.cbrt(2146689000)); //: 1290.0000000000002
53//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
54print(Math.cbrt(1_0000_0000_0000)); //: 10000
55//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
56print(Math.cbrt(-1_0000_0000_0000)); //: -10000
57//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
58print(Math.cbrt(10e80)); //: 1.0000000000000002e+27
59
60// Check with three param
61//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
62print(Math.cbrt(64, 4, 6)); //: 4
63
64// If n is NaN, +0.0f or -0.0f, return n
65res = Math.cbrt(+0.0);
66//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
67print(res); //: 0
68print("1/x: " + 1.0/res); //: 1/x: Infinity
69
70res = Math.cbrt(-0.0);
71//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
72print(res); //: 0
73print("1/x: " + 1.0/res); //: 1/x: -Infinity
74
75//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
76print(Math.cbrt(NaN)); //: NaN
77
78// Replace standard builtin
79let true_cbrt = Math.cbrt;
80Math.cbrt = replace;
81
82// no deopt
83print(Math.cbrt(0.001)); //: 0.001
84Math.cbrt = true_cbrt;
85
86//aot: [trace] aot inline builtin: Math.cbrt, caller function name:#*#doCbrt@builtinMathCbrt
87//aot: [trace] Check Type: NotNumber1
88printCbrt("abcd"); //: NaN
89
90//aot: [trace] aot inline builtin: Math.cbrt, caller function name:#*#doCbrt@builtinMathCbrt
91//aot: [trace] Check Type: NotNumber1
92printCbrt("-125"); //: -5
93
94//aot: [trace] aot inline builtin: Math.cbrt, caller function name:#*#doCbrt@builtinMathCbrt
95//aot: [trace] Check Type: NotNumber1
96printCbrt("abcdef"); //: NaN
97
98if (ArkTools.isAOTCompiled(printCbrt)) {
99    // Replace standard builtin after call to standard builtin was profiled
100    Math.cbrt = replace
101}
102
103printCbrt(-216); //pgo: -6.000000000000001
104//aot: [trace] Check Type: NotCallTarget1
105//aot: -216
106
107printCbrt("abcd"); //pgo: NaN
108//aot: [trace] Check Type: NotCallTarget1
109//aot: abcd
110
111Math.cbrt = true_cbrt;
112
113// Check IR correctness inside try-block
114try {
115    //aot: [trace] aot inline builtin: Math.cbrt, caller function name:#*#doCbrt@builtinMathCbrt
116    printCbrt(10); //: 2.1544346900318834
117    //aot: [trace] aot inline builtin: Math.cbrt, caller function name:#*#doCbrt@builtinMathCbrt
118    //aot: [trace] Check Type: NotNumber1
119    printCbrt("abc"); //: NaN
120} catch (e) {
121}
122
123let obj = {};
124obj.valueOf = (() => { return -64; })
125//aot: [trace] aot inline builtin: Math.cbrt, caller function name:func_main_0@builtinMathCbrt
126//aot: [trace] Check Type: NotNumber1
127print(Math.cbrt(obj)); //: -4
128
129function Throwing() {
130    this.value = 100;
131}
132
133Throwing.prototype.valueOf = function() {
134    if (this.value > 999) {
135        throw new Error("big value")
136    }
137    return this.value;
138}
139let throwingObj = new Throwing();
140
141try {
142    print(Math.cbrt(throwingObj)); //: 4.641588833612778
143    throwingObj.value = 1000;
144    print(Math.cbrt(throwingObj)); //: Error: big value
145} catch(e) {
146    print(e);
147} finally {
148    print(Math.cbrt(obj)); //: -4
149}
150