void initGlobalObject()

in lib/VM/JSLib/GlobalObject.cpp [262:779]


void initGlobalObject(Runtime &runtime, const JSLibFlags &jsLibFlags) {
  GCScope gcScope{runtime, "initGlobalObject", 310};

  // Not enumerable, not writable, not configurable.
  DefinePropertyFlags constantDPF =
      DefinePropertyFlags::getDefaultNewPropertyFlags();
  constantDPF.enumerable = 0;
  constantDPF.writable = 0;
  constantDPF.configurable = 0;

  // Not enumerable, but writable and configurable.
  DefinePropertyFlags normalDPF =
      DefinePropertyFlags::getNewNonEnumerableFlags();

  // Not enumerable, not writable but configurable.
  DefinePropertyFlags configurableOnlyPDF =
      DefinePropertyFlags::getDefaultNewPropertyFlags();
  configurableOnlyPDF.enumerable = 0;
  configurableOnlyPDF.writable = 0;

  /// Clear the configurable flag.
  DefinePropertyFlags clearConfigurableDPF{};
  clearConfigurableDPF.setConfigurable = 1;
  clearConfigurableDPF.configurable = 0;

  // Define a function on the global object with name \p name.
  // Allocates a NativeObject and puts it in the global object.
  auto defineGlobalFunc =
      [&](SymbolID name, NativeFunctionPtr functionPtr, unsigned paramCount) {
        gcScope.clearAllHandles();

        auto func = NativeFunction::createWithoutPrototype(
            runtime, nullptr, functionPtr, name, paramCount);
        runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
            runtime.getGlobal(), runtime, name, normalDPF, func));
        return func;
      };

  // 15.1.1.1 NaN.
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      Predefined::getSymbolID(Predefined::NaN),
      constantDPF,
      runtime.makeHandle(HermesValue::encodeNaNValue())));

  // 15.1.1.2 Infinity.
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      Predefined::getSymbolID(Predefined::Infinity),
      constantDPF,
      runtime.makeHandle(HermesValue::encodeDoubleValue(
          std::numeric_limits<double>::infinity()))));

  // 15.1.1.2 undefined.
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      Predefined::getSymbolID(Predefined::undefined),
      constantDPF,
      runtime.makeHandle(HermesValue::encodeUndefinedValue())));

  // "Forward declaration" of Object.prototype. Its properties will be populated
  // later.

  runtime.objectPrototype =
      JSObject::create(runtime, Runtime::makeNullHandle<JSObject>())
          .getHermesValue();
  runtime.objectPrototypeRawPtr = vmcast<JSObject>(runtime.objectPrototype);

  // "Forward declaration" of Error.prototype. Its properties will be populated
  // later.
  runtime.ErrorPrototype = JSObject::create(runtime).getHermesValue();

// "Forward declaration" of the prototype for native error types. Their
// properties will be populated later.
#define NATIVE_ERROR_TYPE(name)                                       \
  runtime.name##Prototype =                                           \
      JSObject::create(                                               \
          runtime, Handle<JSObject>::vmcast(&runtime.ErrorPrototype)) \
          .getHermesValue();
#include "hermes/VM/NativeErrorTypes.def"

  // "Forward declaration" of the internal CallSite prototype. Its properties
  // will be populated later.
  runtime.callSitePrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
          .getHermesValue();

  // "Forward declaration" of Function.prototype. Its properties will be
  // populated later.
  Handle<NativeFunction> funcRes = NativeFunction::create(
      runtime,
      Handle<JSObject>::vmcast(&runtime.objectPrototype),
      nullptr,
      emptyFunction,
      Predefined::getSymbolID(Predefined::emptyString),
      0,
      Runtime::makeNullHandle<JSObject>());
  runtime.functionPrototype = funcRes.getHermesValue();
  runtime.functionPrototypeRawPtr = funcRes.get();
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      Handle<JSObject>::vmcast(&runtime.functionPrototype),
      runtime,
      Predefined::getSymbolID(Predefined::length),
      configurableOnlyPDF,
      Runtime::getZeroValue()));

  // [[ThrowTypeError]].
  auto throwTypeErrorFunction = NativeFunction::create(
      runtime,
      Handle<JSObject>::vmcast(&runtime.functionPrototype),
      (void *)TypeErrorKind::NonStrictOnly,
      throwTypeError,
      Predefined::getSymbolID(Predefined::emptyString),
      0,
      Runtime::makeNullHandle<JSObject>());
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      throwTypeErrorFunction,
      runtime,
      Predefined::getSymbolID(Predefined::length),
      clearConfigurableDPF,
      Runtime::getUndefinedValue()));
  runtime.throwTypeErrorAccessor =
      runtime.ignoreAllocationFailure(PropertyAccessor::create(
          runtime, throwTypeErrorFunction, throwTypeErrorFunction));

  // Define the 'parseInt' function.
  runtime.parseIntFunction =
      defineGlobalFunc(
          Predefined::getSymbolID(Predefined::parseInt), parseInt, 2)
          .getHermesValue();

  // Define the 'parseFloat' function.
  runtime.parseFloatFunction =
      defineGlobalFunc(
          Predefined::getSymbolID(Predefined::parseFloat), parseFloat, 1)
          .getHermesValue();

  // "Forward declaration" of String.prototype. Its properties will be
  // populated later.
  runtime.stringPrototype =
      runtime
          .ignoreAllocationFailure(JSString::create(
              runtime,
              runtime.getPredefinedStringHandle(Predefined::emptyString),
              Handle<JSObject>::vmcast(&runtime.objectPrototype)))
          .getHermesValue();

  // "Forward declaration" of Number.prototype. Its properties will be
  // populated later.
  runtime.numberPrototype =
      JSNumber::create(
          runtime, +0.0, Handle<JSObject>::vmcast(&runtime.objectPrototype))
          .getHermesValue();

  // "Forward declaration" of Boolean.prototype. Its properties will be
  // populated later.
  runtime.booleanPrototype =
      JSBoolean::create(
          runtime, false, Handle<JSObject>::vmcast(&runtime.objectPrototype))
          .getHermesValue();

  // "Forward declaration" of Symbol.prototype. Its properties will be
  // populated later.
  runtime.symbolPrototype = JSObject::create(runtime).getHermesValue();

  // "Forward declaration" of Date.prototype. Its properties will be
  // populated later.
  runtime.datePrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
          .getHermesValue();

  // "Forward declaration" of %IteratorPrototype%.
  runtime.iteratorPrototype = JSObject::create(runtime).getHermesValue();

  // "Forward declaration" of Array.prototype. Its properties will be
  // populated later.
  runtime.arrayPrototype =
      runtime
          .ignoreAllocationFailure(JSArray::create(
              runtime,
              Handle<JSObject>::vmcast(&runtime.objectPrototype),
              JSArray::createClass(
                  runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype)),
              0,
              0))
          .getHermesValue();

  // Declare the array class.
  runtime.arrayClass =
      JSArray::createClass(
          runtime, Handle<JSObject>::vmcast(&runtime.arrayPrototype))
          .getHermesValue();

  // "Forward declaration" of ArrayBuffer.prototype. Its properties will be
  // populated later.
  runtime.arrayBufferPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
          .getHermesValue();

  // "Forward declaration" of DataView.prototype. Its properties will be
  // populated later.
  runtime.dataViewPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
          .getHermesValue();

  // "Forward declaration" of TypedArrayBase.prototype. Its properties will be
  // populated later.
  runtime.typedArrayBasePrototype = JSObject::create(runtime).getHermesValue();

// Typed arrays
// NOTE: a TypedArray's prototype is a normal object, not a TypedArray.
#define TYPED_ARRAY(name, type)                                                \
  runtime.name##ArrayPrototype =                                               \
      JSObject::create(                                                        \
          runtime, Handle<JSObject>::vmcast(&runtime.typedArrayBasePrototype)) \
          .getHermesValue();
#include "hermes/VM/TypedArrays.def"

  // "Forward declaration" of Set.prototype. Its properties will be
  // populated later.
  runtime.setPrototype = JSObject::create(runtime).getHermesValue();

  runtime.setIteratorPrototype =
      createSetIteratorPrototype(runtime).getHermesValue();

  // "Forward declaration" of Map.prototype. Its properties will be
  // populated later.
  runtime.mapPrototype = JSObject::create(runtime).getHermesValue();

  runtime.mapIteratorPrototype =
      createMapIteratorPrototype(runtime).getHermesValue();

  // "Forward declaration" of RegExp.prototype.
  // ES6: 21.2.5 "The RegExp prototype object is an ordinary object. It is not a
  // RegExp instance..."
  runtime.regExpPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.objectPrototype))
          .getHermesValue();

  // "Forward declaration" of WeakMap.prototype.
  runtime.weakMapPrototype = JSObject::create(runtime).getHermesValue();

  // "Forward declaration" of WeakSet.prototype.
  runtime.weakSetPrototype = JSObject::create(runtime).getHermesValue();

  // "Forward declaration" of %ArrayIteratorPrototype%.
  runtime.arrayIteratorPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
          .getHermesValue();

  // "Forward declaration" of %StringIteratorPrototype%.
  runtime.stringIteratorPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
          .getHermesValue();

  // "Forward declaration" of %RegExpStringIteratorPrototype%.
  runtime.regExpStringIteratorPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
          .getHermesValue();

  // "Forward declaration" of "Generator prototype object"
  runtime.generatorPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.iteratorPrototype))
          .getHermesValue();

  // "Forward declaration" of %GeneratorFunction.prototype%
  runtime.generatorFunctionPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.functionPrototype))
          .getHermesValue();

  // "Forward declaration" of %AsyncFunction.prototype%
  runtime.asyncFunctionPrototype =
      JSObject::create(
          runtime, Handle<JSObject>::vmcast(&runtime.functionPrototype))
          .getHermesValue();

  // Object constructor.
  createObjectConstructor(runtime);

  // JSError constructor.
  runtime.errorConstructor = createErrorConstructor(runtime).getHermesValue();

// All Native Error constructors.
#define NATIVE_ERROR_TYPE(name)       \
  create##name##Constructor(runtime); \
  gcScope.clearAllHandles();
#include "hermes/VM/NativeErrorTypes.def"

  // Populate the internal CallSite prototype.
  populateCallSitePrototype(runtime);

  // String constructor.
  createStringConstructor(runtime);

  // Function constructor.
  runtime.functionConstructor =
      createFunctionConstructor(runtime).getHermesValue();

  // Number constructor.
  createNumberConstructor(runtime);

  // Boolean constructor.
  createBooleanConstructor(runtime);

  // Date constructor.
  createDateConstructor(runtime);

  // RegExp constructor
  createRegExpConstructor(runtime);
  runtime.regExpLastInput = HermesValue::encodeUndefinedValue();
  runtime.regExpLastRegExp = HermesValue::encodeUndefinedValue();

  // Array constructor.
  createArrayConstructor(runtime);

  // ArrayBuffer constructor.
  createArrayBufferConstructor(runtime);

  // DataView constructor.
  createDataViewConstructor(runtime);

  // TypedArrayBase constructor.
  runtime.typedArrayBaseConstructor =
      createTypedArrayBaseConstructor(runtime).getHermesValue();

#define TYPED_ARRAY(name, type)                                 \
  runtime.name##ArrayConstructor =                              \
      create##name##ArrayConstructor(runtime).getHermesValue(); \
  gcScope.clearAllHandles();
#include "hermes/VM/TypedArrays.def"

  // Set constructor.
  createSetConstructor(runtime);

  // Map constructor.
  createMapConstructor(runtime);

  // WeakMap constructor.
  createWeakMapConstructor(runtime);

  // WeakSet constructor.
  createWeakSetConstructor(runtime);

  // Symbol constructor.
  createSymbolConstructor(runtime);

  /// %IteratorPrototype%.
  populateIteratorPrototype(runtime);

  /// Array Iterator.
  populateArrayIteratorPrototype(runtime);

  /// String Iterator.
  populateStringIteratorPrototype(runtime);

  /// RegExp String Iterator.
  populateRegExpStringIteratorPrototype(runtime);

  // GeneratorFunction constructor (not directly exposed in the global object).
  createGeneratorFunctionConstructor(runtime);

  // AsyncFunction constructor (not directly exposed in the global object).
  createAsyncFunctionConstructor(runtime);

  // %GeneratorPrototype%.
  populateGeneratorPrototype(runtime);

  // Proxy constructor.
  if (LLVM_UNLIKELY(runtime.hasES6Proxy())) {
    createProxyConstructor(runtime);
  }

  // Define the global Math object
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      Predefined::getSymbolID(Predefined::Math),
      normalDPF,
      createMathObject(runtime)));

  // Define the global JSON object
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      Predefined::getSymbolID(Predefined::JSON),
      normalDPF,
      createJSONObject(runtime)));

  if (LLVM_UNLIKELY(runtime.hasES6Proxy())) {
    // Define the global Reflect object
    runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
        runtime.getGlobal(),
        runtime,
        Predefined::getSymbolID(Predefined::Reflect),
        normalDPF,
        createReflectObject(runtime)));
  }

  // Define the global %HermesInternal object.
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      Predefined::getSymbolID(Predefined::HermesInternal),
      constantDPF,
      createHermesInternalObject(runtime, jsLibFlags)));

#ifdef HERMES_ENABLE_DEBUGGER

  // Define the global %DebuggerInternal object.
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      runtime.getIdentifierTable().registerLazyIdentifier(
          createASCIIRef("DebuggerInternal")),
      constantDPF,
      createDebuggerInternalObject(runtime)));

#endif // HERMES_ENABLE_DEBUGGER

  // Define the 'print' function.
  defineGlobalFunc(Predefined::getSymbolID(Predefined::print), print, 1);

  // Define the 'eval' function.
  defineGlobalFunc(Predefined::getSymbolID(Predefined::eval), eval, 1);

  // Define the 'isNaN' function.
  defineGlobalFunc(Predefined::getSymbolID(Predefined::isNaN), isNaN, 1);

  // Define the 'isFinite' function.
  defineGlobalFunc(Predefined::getSymbolID(Predefined::isFinite), isFinite, 1);

  // Define the 'escape' function.
  defineGlobalFunc(Predefined::getSymbolID(Predefined::escape), escape, 1);

  // Define the 'unescape' function.
  defineGlobalFunc(Predefined::getSymbolID(Predefined::unescape), unescape, 1);

  // Define the 'decodeURI' function.
  defineGlobalFunc(
      Predefined::getSymbolID(Predefined::decodeURI), decodeURI, 1);

  // Define the 'decodeURIComponent' function.
  defineGlobalFunc(
      Predefined::getSymbolID(Predefined::decodeURIComponent),
      decodeURIComponent,
      1);

  // Define the 'encodeURI' function.
  defineGlobalFunc(
      Predefined::getSymbolID(Predefined::encodeURI), encodeURI, 1);

  // Define the 'encodeURIComponent' function.
  defineGlobalFunc(
      Predefined::getSymbolID(Predefined::encodeURIComponent),
      encodeURIComponent,
      1);

  // Define the 'globalThis' property.
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      Predefined::getSymbolID(Predefined::globalThis),
      normalDPF,
      runtime.getGlobal()));

  // Define the 'require' function.
  runtime.requireFunction =
      NativeFunction::create(
          runtime,
          Handle<JSObject>::vmcast(&runtime.functionPrototype),
          nullptr,
          require,
          Predefined::getSymbolID(Predefined::require),
          1,
          Runtime::makeNullHandle<JSObject>())
          .getHermesValue();

  // Define the 'gc' function.
  defineGlobalFunc(Predefined::getSymbolID(Predefined::gc), gc, 0);

#ifdef HERMES_ENABLE_IR_INSTRUMENTATION
  // Define the global __instrument object
  runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
      runtime.getGlobal(),
      runtime,
      runtime.getIdentifierTable().registerLazyIdentifier(
          createASCIIRef("__instrument")),
      normalDPF,
      createInstrumentObject(runtime)));
#endif

#ifdef HERMES_ENABLE_INTL
  // Define the global Intl object
  // TODO T65916424: Consider how we can move this somewhere more modular.

  if (LLVM_UNLIKELY(runtime.hasIntl())) {
    runtime.ignoreAllocationFailure(JSObject::defineOwnProperty(
        runtime.getGlobal(),
        runtime,
        Predefined::getSymbolID(Predefined::Intl),
        normalDPF,
        intl::createIntlObject(runtime)));
  }
#endif
}