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
}