blob: 99a29bd5cb6651631508ded59e9a71c26e802c2f [file] [log] [blame]
// 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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, y));
const xValue = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<int32>(s);
}
case (h: HeapNumber): {
value = TruncateHeapNumberValueToWord32(h);
}
}
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(Float64Expm1(value));
}
// ES6 #sec-math.fround
transitioning javascript builtin
MathFround(js-implicit context: Context)(x: JSAny): Number {
const x32 = Convert<float32>(ToNumber_Inline(context, x));
const x64 = Convert<float64>(x32);
return Convert<Number>(x64);
}
// ES6 #sec-math.log
extern macro Float64Log(float64): float64;
transitioning javascript builtin
MathLog(js-implicit context: Context)(x: JSAny): Number {
const value = Convert<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(ToNumber_Inline(context, x));
return Convert<Number>(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<float64>(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<Number>(Float64Sqrt(sum) * max);
}
}