Handle createMathObject()

in lib/VM/JSLib/Math.cpp [370:543]


Handle<JSObject> createMathObject(Runtime &runtime) {
  auto objRes = JSMath::create(
      runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype));
  assert(objRes != ExecutionStatus::EXCEPTION && "unable to define Math");
  auto math = runtime.makeHandle<JSMath>(*objRes);

  DefinePropertyFlags constantDPF =
      DefinePropertyFlags::getDefaultNewPropertyFlags();
  constantDPF.enumerable = 0;
  constantDPF.writable = 0;
  constantDPF.configurable = 0;

  MutableHandle<> numberHandle{runtime};

  // ES5.1 15.8.1, Math value properties
  auto setMathValueProperty = [&](SymbolID name, double value) {
    numberHandle = HermesValue::encodeNumberValue(value);
    auto result = JSObject::defineOwnProperty(
        math, runtime, name, constantDPF, numberHandle);
    assert(
        result != ExecutionStatus::EXCEPTION &&
        "defineOwnProperty() failed on a new object");
    (void)result;
  };
  setMathValueProperty(Predefined::getSymbolID(Predefined::E), M_E);
  setMathValueProperty(Predefined::getSymbolID(Predefined::LN10), M_LN10);
  setMathValueProperty(Predefined::getSymbolID(Predefined::LN2), M_LN2);
  setMathValueProperty(Predefined::getSymbolID(Predefined::LOG2E), M_LOG2E);
  setMathValueProperty(Predefined::getSymbolID(Predefined::LOG10E), M_LOG10E);
  setMathValueProperty(Predefined::getSymbolID(Predefined::PI), M_PI);
  setMathValueProperty(Predefined::getSymbolID(Predefined::SQRT1_2), M_SQRT1_2);
  setMathValueProperty(Predefined::getSymbolID(Predefined::SQRT2), M_SQRT2);

  // ES5.1 15.8.2, Math function properties
  auto setMathFunctionProperty1Arg = [&runtime, math](
                                         SymbolID name, MathKind kind) {
    defineMethod(runtime, math, name, (void *)kind, runContextFunc1Arg, 1);
  };

  auto setMathFunctionProperty2Arg = [&runtime, math](
                                         SymbolID name, MathKind kind) {
    defineMethod(runtime, math, name, (void *)kind, runContextFunc2Arg, 2);
  };

  // We use the C versions of some of these functions from <math.h>
  // because on Android, the C++ <cmath> library doesn't have them.
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::abs), MathKind::abs);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::acos), MathKind::acos);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::acosh), MathKind::acosh);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::asin), MathKind::asin);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::asinh), MathKind::asinh);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::atan), MathKind::atan);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::atanh), MathKind::atanh);
  setMathFunctionProperty2Arg(
      Predefined::getSymbolID(Predefined::atan2), MathKind::atan2);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::cbrt), MathKind::cbrt);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::ceil), MathKind::ceil);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::clz32),
      nullptr,
      mathClz32,
      1);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::cos), MathKind::cos);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::cosh), MathKind::cosh);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::exp), MathKind::exp);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::expm1), MathKind::expm1);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::floor), MathKind::floor);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::fround),
      nullptr,
      mathFround,
      1);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::hypot),
      nullptr,
      mathHypot,
      2);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::log), MathKind::log);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::log10), MathKind::log10);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::log1p), MathKind::log1p);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::log2), MathKind::log2);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::trunc), MathKind::trunc);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::max),
      nullptr,
      mathMax,
      2);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::min),
      nullptr,
      mathMin,
      2);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::imul),
      nullptr,
      mathImul,
      2);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::pow),
      nullptr,
      mathPow,
      2);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::random),
      nullptr,
      mathRandom,
      0);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::round), MathKind::round);
  defineMethod(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::sign),
      nullptr,
      mathSign,
      1);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::sin), MathKind::sin);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::sinh), MathKind::sinh);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::sqrt), MathKind::sqrt);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::tan), MathKind::tan);
  setMathFunctionProperty1Arg(
      Predefined::getSymbolID(Predefined::tanh), MathKind::tanh);

  auto dpf = DefinePropertyFlags::getDefaultNewPropertyFlags();
  dpf.writable = 0;
  dpf.enumerable = 0;
  defineProperty(
      runtime,
      math,
      Predefined::getSymbolID(Predefined::SymbolToStringTag),
      runtime.getPredefinedStringHandle(Predefined::Math),
      dpf);

  return math;
}