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, b : number) 21{ 22 return a; 23} 24 25function doImul(x: any, y: any): number { 26 return Math.imul(x, y); 27} 28 29function printImul(x: any, y: any) { 30 try { 31 print(doImul(x, y)); 32 } finally { 33 } 34} 35 36let len:number = 1; 37 38len = Math.imul(2, 3) 39//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 40print(len) //: 6 41 42// Check without params 43len = Math.imul(); 44//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 45print(len); //: 0 46 47// Check with single param 48len = Math.imul(0); 49//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 50print(len); //: 0 51 52// Check with three param 53len = Math.imul(2, 4, 6); 54//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 55print(len); //: 8 56 57// If an input is NaN, return 0 58len = Math.imul(2, NaN) 59//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 60print(len) //: 0 61 62// Check with 0 63len = Math.imul(3, +0.0); 64//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 65print(len); //: 0 66 67len = Math.imul(3, -0.0); 68//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 69print(len); //: 0 70 71// If an input is Infinity or -Infinity, return 0 72len = Math.imul(-Infinity, 5); 73//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 74print(len); //: 0 75len = Math.imul(Infinity, 6); 76//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 77print(len); //: 0 78len = Math.imul(3, -Infinity); 79//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 80print(len); //: 0 81len = Math.imul(5, Infinity); 82//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 83print(len); //: 0 84 85// Check int 86len = Math.imul(-2, -10); 87//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 88print(len); //: 20 89len = Math.imul(5, 10000); 90//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 91print(len); //: 50000 92len = Math.imul(-600, -20); 93//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 94print(len); //: 12000 95 96// Check double 97len = Math.imul(5.3, 2.7); 98//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 99print(len); //: 10 100len = Math.imul(-2.4, -4.7); 101//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 102print(len); //: 8 103 104len = Math.imul(-7.3, 6.2); 105//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 106print(len); //: -42 107 108//big double 109len = Math.imul(2, 1.9e80); 110//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 111print(len); //: 0 112 113//small double 114len = Math.imul(2, 1.9e-80); 115//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 116print(len); //: 0 117 118 119// Check edge cases 120const INT_MAX: number = 2147483647; 121const INT_MIN: number = -INT_MAX - 1; 122//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 123print(Math.imul(INT_MAX, 1)); //: 2147483647 124//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 125print(Math.imul(2147483648 , 2)); //: 0 126//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 127print(Math.imul(-INT_MAX, 2)); //: 2 128//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 129print(Math.imul(INT_MIN, 2)); //: 0 130//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 131print(Math.imul(INT_MIN - 1, 2)); //: -2 132 133len = Math.imul(2, "three"); 134//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul 135//aot: [trace] Check Type: NotNumber1 136print(len); //: 0 137 138// Replace standard builtin 139let true_imul = Math.imul 140Math.imul= replace 141print(Math.imul(2, 40)); //: 2 142Math.imul = true_imul 143 144len = Math.imul(3, 3) 145print(len) //: 9 146//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul 147printImul(-12, 2); //: -24 148// Call standard builtin with non-number param 149//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul 150//aot: [trace] Check Type: NotNumber1 151printImul("abc", 2); //: 0 152//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul 153//aot: [trace] Check Type: NotNumber1 154printImul("-12", 2); //: -24 155 156if (ArkTools.isAOTCompiled(printImul)) { 157 // Replace standard builtin after call to standard builtin was profiled 158 Math.imul= replace 159} 160printImul(-12, 2); //pgo: -24 161//aot: [trace] Check Type: NotCallTarget1 162//aot: -12 163printImul("abc", 2); //pgo: 0 164//aot: [trace] Check Type: NotCallTarget1 165//aot: abc 166 167Math.imul = true_imul 168 169// Check IR correctness inside try-block 170try { 171 //aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul 172 printImul(-12, 2); //: -24 173 //aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul 174 //aot: [trace] Check Type: NotNumber1 175 printImul("abc", 2); //: 0 176} catch (e) { 177} 178 179let obj = {}; 180obj.valueOf = (() => { return -23; }) 181//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul 182//aot: [trace] Check Type: NotNumber1 183printImul(obj, -2); //: 46 184 185function Throwing() { 186 this.value = -14; 187} 188Throwing.prototype.valueOf = function() { 189 if (this.value > 0) { 190 throw new Error("already positive"); 191 } 192 return this.value; 193} 194let throwingObj = new Throwing(); 195 196try { 197 print(Math.imul(throwingObj, 2)); //: -28 198 throwingObj.value = 10; 199 print(Math.imul(throwingObj), 2); //: Error: already positive 200} catch(e) { 201 print(e); 202} finally { 203 print(Math.imul(obj, 2)); //: -46 204} 205