/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare function print(arg:any):string;
declare interface ArkTools {
isAOTCompiled(args: any): boolean;
}
function replace(a : number, b : number)
{
return a;
}
function doImul(x: any, y: any): number {
return Math.imul(x, y);
}
function printImul(x: any, y: any) {
try {
print(doImul(x, y));
} finally {
}
}
let len:number = 1;
len = Math.imul(2, 3)
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len) //: 6
// Check without params
len = Math.imul();
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
// Check with single param
len = Math.imul(0);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
// Check with three param
len = Math.imul(2, 4, 6);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 8
// If an input is NaN, return 0
len = Math.imul(2, NaN)
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len) //: 0
// Check with 0
len = Math.imul(3, +0.0);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
len = Math.imul(3, -0.0);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
// If an input is Infinity or -Infinity, return 0
len = Math.imul(-Infinity, 5);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
len = Math.imul(Infinity, 6);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
len = Math.imul(3, -Infinity);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
len = Math.imul(5, Infinity);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
// Check int
len = Math.imul(-2, -10);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 20
len = Math.imul(5, 10000);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 50000
len = Math.imul(-600, -20);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 12000
// Check double
len = Math.imul(5.3, 2.7);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 10
len = Math.imul(-2.4, -4.7);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 8
len = Math.imul(-7.3, 6.2);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: -42
//big double
len = Math.imul(2, 1.9e80);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
//small double
len = Math.imul(2, 1.9e-80);
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(len); //: 0
// Check edge cases
const INT_MAX: number = 2147483647;
const INT_MIN: number = -INT_MAX - 1;
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(Math.imul(INT_MAX, 1)); //: 2147483647
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(Math.imul(2147483648 , 2)); //: 0
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(Math.imul(-INT_MAX, 2)); //: 2
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(Math.imul(INT_MIN, 2)); //: 0
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
print(Math.imul(INT_MIN - 1, 2)); //: -2
len = Math.imul(2, "three");
//aot: [trace] aot inline builtin: Math.imul, caller function name:func_main_0@builtinMathImul
//aot: [trace] Check Type: NotNumber1
print(len); //: 0
// Replace standard builtin
let true_imul = Math.imul
Math.imul= replace
print(Math.imul(2, 40)); //: 2
Math.imul = true_imul
len = Math.imul(3, 3)
print(len) //: 9
//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul
printImul(-12, 2); //: -24
// Call standard builtin with non-number param
//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul
//aot: [trace] Check Type: NotNumber1
printImul("abc", 2); //: 0
//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul
//aot: [trace] Check Type: NotNumber1
printImul("-12", 2); //: -24
if (ArkTools.isAOTCompiled(printImul)) {
// Replace standard builtin after call to standard builtin was profiled
Math.imul= replace
}
printImul(-12, 2); //pgo: -24
//aot: [trace] Check Type: NotCallTarget1
//aot: -12
printImul("abc", 2); //pgo: 0
//aot: [trace] Check Type: NotCallTarget1
//aot: abc
Math.imul = true_imul
// Check IR correctness inside try-block
try {
//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul
printImul(-12, 2); //: -24
//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul
//aot: [trace] Check Type: NotNumber1
printImul("abc", 2); //: 0
} catch (e) {
}
let obj = {};
obj.valueOf = (() => { return -23; })
//aot: [trace] aot inline builtin: Math.imul, caller function name:#*#doImul@builtinMathImul
//aot: [trace] Check Type: NotNumber1
printImul(obj, -2); //: 46
function Throwing() {
this.value = -14;
}
Throwing.prototype.valueOf = function() {
if (this.value > 0) {
throw new Error("already positive");
}
return this.value;
}
let throwingObj = new Throwing();
try {
print(Math.imul(throwingObj, 2)); //: -28
throwingObj.value = 10;
print(Math.imul(throwingObj), 2); //: Error: already positive
} catch(e) {
print(e);
} finally {
print(Math.imul(obj, 2)); //: -46
}