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 doIsFinite(x: any): any {
26    return isFinite(x);
27}
28
29function printIsFinite(x: any) {
30    try {
31        print(doIsFinite(x));
32    } finally {
33    }
34}
35// Check with single int param
36//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
37print(isFinite(0)); //: true
38//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
39print(isFinite(3)); //: true
40//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
41print(isFinite(-5)); //: true
42
43// Check with single float param
44//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
45print(isFinite(-1.5)); //: true
46//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
47print(isFinite(1.5)); //: true
48
49// Check with special float params
50//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
51print(isFinite(Infinity)); //: false
52//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
53print(isFinite(-Infinity)); //: false
54//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
55print(isFinite(NaN)); //: false
56//aot: [trace] aot inline builtin: Math.exp, caller function name:func_main_0@builtinGlobalIsFinite
57//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
58print(isFinite(Math.exp(800))); //: false
59
60// Check with 2 params
61//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
62print(isFinite(3, Infinity)); //: true
63
64// Check with 3 params
65//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
66print(isFinite(-3, NaN, Infinity)); //: true
67
68
69// Replace standard builtin
70let true_is_finite = isFinite
71isFinite = replace
72print(isFinite(NaN)); //: NaN
73isFinite = true_is_finite
74
75
76//aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
77printIsFinite(-3);    //: true
78//aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
79//aot: [trace] Check Type: NotNumber1
80printIsFinite("abc"); //: false
81//aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
82//aot: [trace] Check Type: NotNumber1
83printIsFinite("abc"); //: false
84
85//aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
86printIsFinite(-12); //: true
87// Call standard builtin with non-number param
88//aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
89//aot: [trace] Check Type: NotNumber1
90printIsFinite("abc"); //: false
91//aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
92//aot: [trace] Check Type: NotNumber1
93printIsFinite("-12"); //: true
94
95if (ArkTools.isAOTCompiled(doIsFinite)) {
96    // Replace standard builtin after call to standard builtin was profiled
97    isFinite = replace
98}
99printIsFinite(-12);   //pgo: true
100                      //aot: [trace] Check Type: NotCallTarget1
101                      //aot: -12
102printIsFinite("abc"); //pgo: false
103                      //aot: [trace] Check Type: NotCallTarget1
104                      //aot: abc
105
106isFinite = true_is_finite
107
108// Check IR correctness inside try-block
109try {
110    //aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
111    printIsFinite(-12); //: true
112    //aot: [trace] aot inline builtin: isFinite, caller function name:#*#doIsFinite@builtinGlobalIsFinite
113    //aot: [trace] Check Type: NotNumber1
114    printIsFinite("abc"); //: false
115} catch (e) {
116}
117
118let obj = {};
119obj.valueOf = (() => { return -23; })
120//aot: [trace] aot inline builtin: isFinite, caller function name:func_main_0@builtinGlobalIsFinite
121//aot: [trace] Check Type: NotNumber1
122print(isFinite(obj)); //: true
123
124function Throwing() {
125    this.value = -14;
126}
127Throwing.prototype.valueOf = function() {
128    if (this.value > 0) {
129        throw new Error("already positive");
130    }
131    return this.value;
132}
133let throwingObj = new Throwing();
134
135try {
136    print(isFinite(throwingObj)); //: true
137    throwingObj.value = 10;
138    print(isFinite(throwingObj)); //: Error: already positive
139} catch(e) {
140    print(e);
141} finally {
142    print(isFinite(obj)); //: true
143}