// Copyright 2019 the V8 project authors. All rights reserved. Use of this // source code is governed by a BSD-style license that can be found in the // LICENSE file. namespace math { // ES6 #sec-math.acos extern macro Float64Acos(float64): float64; transitioning javascript builtin MathAcos(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Acos(value)); } // ES6 #sec-math.acosh extern macro Float64Acosh(float64): float64; transitioning javascript builtin MathAcosh(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Acosh(value)); } // ES6 #sec-math.asin extern macro Float64Asin(float64): float64; transitioning javascript builtin MathAsin(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Asin(value)); } // ES6 #sec-math.asinh extern macro Float64Asinh(float64): float64; transitioning javascript builtin MathAsinh(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Asinh(value)); } // ES6 #sec-math.atan extern macro Float64Atan(float64): float64; transitioning javascript builtin MathAtan(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Atan(value)); } // ES6 #sec-math.atan2 extern macro Float64Atan2(float64, float64): float64; transitioning javascript builtin MathAtan2(js-implicit context: Context)(y: JSAny, x: JSAny): Number { const yValue = Convert(ToNumber_Inline(context, y)); const xValue = Convert(ToNumber_Inline(context, x)); return Convert(Float64Atan2(yValue, xValue)); } // ES6 #sec-math.atanh extern macro Float64Atanh(float64): float64; transitioning javascript builtin MathAtanh(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Atanh(value)); } // ES6 #sec-math.cbrt extern macro Float64Cbrt(float64): float64; transitioning javascript builtin MathCbrt(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Cbrt(value)); } // ES6 #sec-math.clz32 extern macro Word32Clz(int32): int32; transitioning javascript builtin MathClz32(js-implicit context: Context)(x: JSAny): Number { const num = ToNumber_Inline(context, x); let value: int32; typeswitch (num) { case (s: Smi): { value = Convert(s); } case (h: HeapNumber): { value = TruncateHeapNumberValueToWord32(h); } } return Convert(Word32Clz(value)); } // ES6 #sec-math.cos extern macro Float64Cos(float64): float64; transitioning javascript builtin MathCos(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Cos(value)); } // ES6 #sec-math.cosh extern macro Float64Cosh(float64): float64; transitioning javascript builtin MathCosh(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Cosh(value)); } // ES6 #sec-math.exp extern macro Float64Exp(float64): float64; transitioning javascript builtin MathExp(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Exp(value)); } // ES6 #sec-math.expm1 extern macro Float64Expm1(float64): float64; transitioning javascript builtin MathExpm1(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Expm1(value)); } // ES6 #sec-math.fround transitioning javascript builtin MathFround(js-implicit context: Context)(x: JSAny): Number { const x32 = Convert(ToNumber_Inline(context, x)); const x64 = Convert(x32); return Convert(x64); } // ES6 #sec-math.log extern macro Float64Log(float64): float64; transitioning javascript builtin MathLog(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Log(value)); } // ES6 #sec-math.log1p extern macro Float64Log1p(float64): float64; transitioning javascript builtin MathLog1p(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Log1p(value)); } // ES6 #sec-math.log10 extern macro Float64Log10(float64): float64; transitioning javascript builtin MathLog10(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Log10(value)); } // ES6 #sec-math.log2 extern macro Float64Log2(float64): float64; transitioning javascript builtin MathLog2(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Log2(value)); } // ES6 #sec-math.sin extern macro Float64Sin(float64): float64; transitioning javascript builtin MathSin(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Sin(value)); } // ES6 #sec-math.sign transitioning javascript builtin MathSign(js-implicit context: Context)(x: JSAny): Number { const num = ToNumber_Inline(context, x); const value = Convert(num); if (value < 0) { return -1; } else if (value > 0) { return 1; } else { return num; } } // ES6 #sec-math.sinh extern macro Float64Sinh(float64): float64; transitioning javascript builtin MathSinh(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Sinh(value)); } // ES6 #sec-math.sqrt extern macro Float64Sqrt(float64): float64; transitioning javascript builtin MathSqrt(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Sqrt(value)); } // ES6 #sec-math.tan extern macro Float64Tan(float64): float64; transitioning javascript builtin MathTan(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Tan(value)); } // ES6 #sec-math.tanh extern macro Float64Tanh(float64): float64; transitioning javascript builtin MathTanh(js-implicit context: Context)(x: JSAny): Number { const value = Convert(ToNumber_Inline(context, x)); return Convert(Float64Tanh(value)); } extern macro Float64Abs(float64): float64; // ES6 #sec-math.hypot transitioning javascript builtin MathHypot(js-implicit context: Context, receiver: JSAny)(...arguments): Number { const length = arguments.length; if (length == 0) { return 0; } const absValues = AllocateZeroedFixedDoubleArray(length); let oneArgIsNaN: bool = false; let max: float64 = 0; for (let i: intptr = 0; i < length; ++i) { const value = Convert(ToNumber_Inline(context, arguments[i])); if (Float64IsNaN(value)) { oneArgIsNaN = true; } else { const absValue = Float64Abs(value); absValues.floats[i] = absValue; if (absValue > max) { max = absValue; } } } if (max == V8_INFINITY) { return V8_INFINITY; } else if (oneArgIsNaN) { return kNaN; } else if (max == 0) { return 0; } assert(max > 0); // Kahan summation to avoid rounding errors. // Normalize the numbers to the largest one to avoid overflow. let sum: float64 = 0; let compensation: float64 = 0; for (let i: intptr = 0; i < length; ++i) { const n = absValues.floats[i] / max; const summand = n * n - compensation; const preliminary = sum + summand; compensation = (preliminary - sum) - summand; sum = preliminary; } return Convert(Float64Sqrt(sum) * max); } }