Handle createTypedArrayBaseConstructor()

in lib/VM/JSLib/TypedArray.cpp [1621:1930]


Handle<JSObject> createTypedArrayBaseConstructor(Runtime &runtime) {
  auto proto = Handle<JSObject>::vmcast(&runtime.typedArrayBasePrototype);

  // Create NativeConstructor manually to avoid global object assignment.
  // Use NativeConstructor because %TypedArray% is supposed to be
  // a constructor function object, but must not be called directly with "new".
  auto cons = runtime.makeHandle(NativeConstructor::create(
      runtime,
      Handle<JSObject>::vmcast(&runtime.functionPrototype),
      nullptr,
      typedArrayBaseConstructor,
      0,
      NativeConstructor::creatorFunction<JSObject>,
      CellKind::JSObjectKind));

  // Define %TypedArray%.prototype to be proto.
  auto st = Callable::defineNameLengthAndPrototype(
      cons,
      runtime,
      Predefined::getSymbolID(Predefined::TypedArray),
      0,
      proto,
      Callable::WritablePrototype::No,
      false);
  (void)st;
  assert(
      st != ExecutionStatus::EXCEPTION &&
      "defineNameLengthAndPrototype() failed");

  // TypedArrayBase.prototype.xxx().
  // Accessors.
  defineAccessor(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::buffer),
      nullptr,
      typedArrayPrototypeBuffer,
      nullptr,
      false,
      true);
  defineAccessor(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::byteLength),
      nullptr,
      typedArrayPrototypeByteLength,
      nullptr,
      false,
      true);
  defineAccessor(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::byteOffset),
      nullptr,
      typedArrayPrototypeByteOffset,
      nullptr,
      false,
      true);
  defineAccessor(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::length),
      nullptr,
      typedArrayPrototypeLength,
      nullptr,
      false,
      true);
  defineAccessor(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::SymbolToStringTag),
      Predefined::getSymbolID(Predefined::squareSymbolToStringTag),
      nullptr,
      typedArrayPrototypeSymbolToStringTag,
      nullptr,
      false,
      true);
  // Methods.
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::copyWithin),
      nullptr,
      typedArrayPrototypeCopyWithin,
      2);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::every),
      (void *)true,
      typedArrayPrototypeEverySome,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::some),
      (void *)false,
      typedArrayPrototypeEverySome,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::fill),
      nullptr,
      typedArrayPrototypeFill,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::filter),
      (void *)false,
      typedArrayPrototypeMapFilter,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::find),
      (void *)false,
      typedArrayPrototypeFind,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::findIndex),
      (void *)true,
      typedArrayPrototypeFind,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::findLast),
      (void *)false,
      typedArrayPrototypeFindLast,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::findLastIndex),
      (void *)true,
      typedArrayPrototypeFindLast,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::forEach),
      nullptr,
      typedArrayPrototypeForEach,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::includes),
      (void *)IndexOfMode::includes,
      typedArrayPrototypeIndexOf,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::indexOf),
      (void *)IndexOfMode::indexOf,
      typedArrayPrototypeIndexOf,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::lastIndexOf),
      (void *)IndexOfMode::lastIndexOf,
      typedArrayPrototypeIndexOf,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::join),
      nullptr,
      typedArrayPrototypeJoin,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::map),
      (void *)true,
      typedArrayPrototypeMapFilter,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::reduce),
      (void *)false,
      typedArrayPrototypeReduce,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::reduceRight),
      (void *)true,
      typedArrayPrototypeReduce,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::reverse),
      nullptr,
      typedArrayPrototypeReverse,
      0);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::set),
      nullptr,
      typedArrayPrototypeSet,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::slice),
      nullptr,
      typedArrayPrototypeSlice,
      2);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::sort),
      nullptr,
      typedArrayPrototypeSort,
      1);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::subarray),
      nullptr,
      typedArrayPrototypeSubarray,
      2);

  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::keys),
      (void *)IterationKind::Key,
      typedArrayPrototypeIterator,
      0);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::values),
      (void *)IterationKind::Value,
      typedArrayPrototypeIterator,
      0);
  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::entries),
      (void *)IterationKind::Entry,
      typedArrayPrototypeIterator,
      0);

  DefinePropertyFlags dpf = DefinePropertyFlags::getNewNonEnumerableFlags();

  // Use the same valuesMethod for Symbol.iterator.
  {
    auto propValue = runtime.ignoreAllocationFailure(JSObject::getNamed_RJS(
        proto, runtime, Predefined::getSymbolID(Predefined::values)));
    runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
        proto,
        runtime,
        Predefined::getSymbolID(Predefined::SymbolIterator),
        dpf,
        runtime.makeHandle<NativeFunction>(propValue.getHermesValue())));
  }

  {
    auto propValue = runtime.ignoreAllocationFailure(JSObject::getNamed_RJS(
        Handle<JSArray>::vmcast(&runtime.arrayPrototype),
        runtime,
        Predefined::getSymbolID(Predefined::toString)));
    runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
        proto,
        runtime,
        Predefined::getSymbolID(Predefined::toString),
        dpf,
        Handle<NativeFunction>::vmcast(
            runtime.makeHandle(std::move(propValue)))));
  }

  defineMethod(
      runtime,
      proto,
      Predefined::getSymbolID(Predefined::toLocaleString),
      nullptr,
      typedArrayPrototypeToLocaleString,
      0);

  // TypedArrayBase.xxx
  defineMethod(
      runtime,
      cons,
      Predefined::getSymbolID(Predefined::from),
      nullptr,
      typedArrayFrom,
      1);

  defineMethod(
      runtime,
      cons,
      Predefined::getSymbolID(Predefined::of),
      nullptr,
      typedArrayOf,
      0);

  return cons;
}