diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSGlobalObject.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/JSGlobalObject.h | 718 |
1 files changed, 507 insertions, 211 deletions
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h index b0cad3dc5..881eb0871 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.h +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2007 Eric Seidel <eric@webkit.org> - * Copyright (C) 2007, 2008, 2009, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2007-2009, 2014-2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,112 +19,187 @@ * */ -#ifndef JSGlobalObject_h -#define JSGlobalObject_h +#pragma once #include "ArrayAllocationProfile.h" -#include "ConstantMode.h" +#include "ArrayBufferSharingMode.h" +#include "InternalFunction.h" #include "JSArray.h" #include "JSArrayBufferPrototype.h" #include "JSClassRef.h" +#include "JSGlobalLexicalEnvironment.h" +#include "JSProxy.h" #include "JSSegmentedVariableObject.h" #include "JSWeakObjectMapRefInternal.h" +#include "LazyProperty.h" +#include "LazyClassStructure.h" #include "NumberPrototype.h" +#include "RuntimeFlags.h" #include "SpecialPointer.h" #include "StringPrototype.h" -#include "StructureChain.h" -#include "StructureRareDataInlines.h" +#include "SymbolPrototype.h" +#include "TemplateRegistry.h" #include "VM.h" #include "Watchpoint.h" #include <JavaScriptCore/JSBase.h> #include <array> #include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RandomNumber.h> struct OpaqueJSClass; struct OpaqueJSClassContextData; -namespace JSC { +namespace Inspector { +class JSGlobalObjectInspectorController; +} +namespace JSC { +class ArrayConstructor; class ArrayPrototype; +class ArrayIteratorAdaptiveWatchpoint; +class AsyncFunctionPrototype; class BooleanPrototype; +class ConsoleClient; class Debugger; class ErrorConstructor; class ErrorPrototype; class EvalCodeBlock; class EvalExecutable; -class FunctionCodeBlock; -class FunctionExecutable; +class FunctionConstructor; class FunctionPrototype; +class GeneratorPrototype; +class GeneratorFunctionPrototype; class GetterSetter; class GlobalCodeBlock; +class IndirectEvalExecutable; +class InputCursor; +class JSArrayBuffer; +class JSArrayBufferConstructor; +class JSArrayBufferPrototype; class JSGlobalObjectDebuggable; +class JSInternalPromise; +class JSModuleLoader; +class JSPromise; class JSPromiseConstructor; class JSPromisePrototype; -class JSStack; +class JSSharedArrayBuffer; +class JSSharedArrayBufferConstructor; +class JSSharedArrayBufferPrototype; +class JSTypedArrayViewConstructor; +class JSTypedArrayViewPrototype; +class DirectEvalExecutable; class LLIntOffsetsExtractor; class Microtask; +class ModuleLoaderPrototype; +class ModuleProgramExecutable; class NativeErrorConstructor; +class NullGetterFunction; +class NullSetterFunction; +class ObjectConstructor; class ProgramCodeBlock; class ProgramExecutable; class RegExpConstructor; class RegExpPrototype; class SourceCode; +class UnlinkedModuleProgramCodeBlock; +class VariableEnvironment; struct ActivationStackNode; struct HashTable; -#define DEFINE_STANDARD_BUILTIN(macro, upperName, lowerName) macro(upperName, lowerName, lowerName, JS ## upperName, upperName) - -#define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \ - macro(Set, set, set, JSSet, Set) \ - macro(Map, map, map, JSMap, Map) \ - macro(Date, date, date, DateInstance, Date) \ - macro(String, string, stringObject, StringObject, String) \ - macro(Boolean, boolean, booleanObject, BooleanObject, Boolean) \ - macro(Number, number, numberObject, NumberObject, Number) \ - macro(Error, error, error, ErrorInstance, Error) \ - macro(JSArrayBuffer, arrayBuffer, arrayBuffer, JSArrayBuffer, ArrayBuffer) \ - DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \ - DEFINE_STANDARD_BUILTIN(macro, ArrayIterator, arrayIterator) \ - DEFINE_STANDARD_BUILTIN(macro, ArgumentsIterator, argumentsIterator) \ +#define DEFINE_STANDARD_BUILTIN(macro, upperName, lowerName) macro(upperName, lowerName, lowerName, JS ## upperName, upperName, object) + +#define FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ + macro(String, string, stringObject, StringObject, String, object) \ + macro(Symbol, symbol, symbolObject, SymbolObject, Symbol, object) \ + macro(Number, number, numberObject, NumberObject, Number, object) \ + macro(Error, error, error, ErrorInstance, Error, object) \ + macro(Map, map, map, JSMap, Map, object) \ + macro(JSPromise, promise, promise, JSPromise, Promise, object) + +#define FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \ DEFINE_STANDARD_BUILTIN(macro, MapIterator, mapIterator) \ DEFINE_STANDARD_BUILTIN(macro, SetIterator, setIterator) \ + DEFINE_STANDARD_BUILTIN(macro, StringIterator, stringIterator) \ +#define FOR_EACH_BUILTIN_ITERATOR_TYPE(macro) \ + DEFINE_STANDARD_BUILTIN(macro, Iterator, iterator) \ + FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \ -#define DECLARE_SIMPLE_BUILTIN_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ +#define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \ + FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ + macro(JSInternalPromise, internalPromise, internalPromise, JSInternalPromise, InternalPromise, object) \ + +#define FOR_EACH_LAZY_BUILTIN_TYPE(macro) \ + macro(Set, set, set, JSSet, Set, object) \ + macro(Date, date, date, DateInstance, Date, object) \ + macro(Boolean, boolean, booleanObject, BooleanObject, Boolean, object) \ + DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \ + DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \ + +#if ENABLE(WEBASSEMBLY) +#define FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(macro) \ + macro(WebAssemblyCompileError, webAssemblyCompileError, WebAssemblyCompileError, WebAssemblyCompileError, CompileError, error) \ + macro(WebAssemblyInstance, webAssemblyInstance, WebAssemblyInstance, WebAssemblyInstance, Instance, object) \ + macro(WebAssemblyLinkError, webAssemblyLinkError, WebAssemblyLinkError, WebAssemblyLinkError, LinkError, error) \ + macro(WebAssemblyMemory, webAssemblyMemory, WebAssemblyMemory, WebAssemblyMemory, Memory, object) \ + macro(WebAssemblyModule, webAssemblyModule, WebAssemblyModule, WebAssemblyModule, Module, object) \ + macro(WebAssemblyRuntimeError, webAssemblyRuntimeError, WebAssemblyRuntimeError, WebAssemblyRuntimeError, RuntimeError, error) \ + macro(WebAssemblyTable, webAssemblyTable, WebAssemblyTable, WebAssemblyTable, Table, object) +#else +#define FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(macro) +#endif // ENABLE(WEBASSEMBLY) + +#define DECLARE_SIMPLE_BUILTIN_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \ class JS ## capitalName; \ class capitalName ## Prototype; \ class capitalName ## Constructor; +class IteratorPrototype; FOR_EACH_SIMPLE_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE) +FOR_EACH_LAZY_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE) +FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE) +FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE) #undef DECLARE_SIMPLE_BUILTIN_TYPE +class JSInternalPromise; +class InternalPromisePrototype; +class InternalPromiseConstructor; + typedef Vector<ExecState*, 16> ExecStateStack; struct GlobalObjectMethodTable { - typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*); - AllowsAccessFromFunctionPtr allowsAccessFrom; - - typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*); - SupportsProfilingFunctionPtr supportsProfiling; - typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*); SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo; typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*); ShouldInterruptScriptFunctionPtr shouldInterruptScript; - typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*); - JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled; + typedef RuntimeFlags (*JavaScriptRuntimeFlagsFunctionPtr)(const JSGlobalObject*); + JavaScriptRuntimeFlagsFunctionPtr javaScriptRuntimeFlags; - typedef void (*QueueTaskToEventLoopFunctionPtr)(const JSGlobalObject*, PassRefPtr<Microtask>); + typedef void (*QueueTaskToEventLoopFunctionPtr)(const JSGlobalObject*, Ref<Microtask>&&); QueueTaskToEventLoopFunctionPtr queueTaskToEventLoop; typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*); ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout; + + typedef JSInternalPromise* (*ModuleLoaderImportModulePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSString*, const SourceOrigin&); + ModuleLoaderImportModulePtr moduleLoaderImportModule; + + typedef JSInternalPromise* (*ModuleLoaderResolvePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue); + ModuleLoaderResolvePtr moduleLoaderResolve; + + typedef JSInternalPromise* (*ModuleLoaderFetchPtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue); + ModuleLoaderFetchPtr moduleLoaderFetch; + + typedef JSInternalPromise* (*ModuleLoaderInstantiatePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue); + ModuleLoaderInstantiatePtr moduleLoaderInstantiate; + + typedef JSValue (*ModuleLoaderEvaluatePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue); + ModuleLoaderEvaluatePtr moduleLoaderEvaluate; + + typedef String (*DefaultLanguageFunctionPtr)(); + DefaultLanguageFunctionPtr defaultLanguage; }; class JSGlobalObject : public JSSegmentedVariableObject { @@ -133,6 +208,8 @@ private: typedef HashMap<OpaqueJSClass*, std::unique_ptr<OpaqueJSClassContextData>> OpaqueJSClassDataMap; struct JSGlobalObjectRareData { + WTF_MAKE_FAST_ALLOCATED; + public: JSGlobalObjectRareData() : profileGroup(0) { @@ -144,102 +221,203 @@ private: OpaqueJSClassDataMap opaqueJSClassData; }; -protected: - Register m_globalCallFrame[JSStack::CallFrameHeaderSize]; +// Our hashtable code-generator tries to access these properties, so we make them public. +// However, we'd like it better if they could be protected. +public: + template<typename T> using Initializer = typename LazyProperty<JSGlobalObject, T>::Initializer; + + Register m_globalCallFrame[CallFrame::headerSizeInRegisters]; WriteBarrier<JSObject> m_globalThis; + WriteBarrier<JSGlobalLexicalEnvironment> m_globalLexicalEnvironment; + WriteBarrier<JSScope> m_globalScopeExtension; + WriteBarrier<JSObject> m_globalCallee; WriteBarrier<RegExpConstructor> m_regExpConstructor; WriteBarrier<ErrorConstructor> m_errorConstructor; - WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor; + WriteBarrier<Structure> m_nativeErrorPrototypeStructure; + WriteBarrier<Structure> m_nativeErrorStructure; + LazyProperty<JSGlobalObject, NativeErrorConstructor> m_evalErrorConstructor; WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor; - WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor; - WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor; + LazyProperty<JSGlobalObject, NativeErrorConstructor> m_referenceErrorConstructor; + LazyProperty<JSGlobalObject, NativeErrorConstructor> m_syntaxErrorConstructor; WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor; - WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor; + LazyProperty<JSGlobalObject, NativeErrorConstructor> m_URIErrorConstructor; + WriteBarrier<ObjectConstructor> m_objectConstructor; + WriteBarrier<ArrayConstructor> m_arrayConstructor; WriteBarrier<JSPromiseConstructor> m_promiseConstructor; + WriteBarrier<JSInternalPromiseConstructor> m_internalPromiseConstructor; + + WriteBarrier<NullGetterFunction> m_nullGetterFunction; + WriteBarrier<NullSetterFunction> m_nullSetterFunction; + + WriteBarrier<JSFunction> m_parseIntFunction; WriteBarrier<JSFunction> m_evalFunction; WriteBarrier<JSFunction> m_callFunction; WriteBarrier<JSFunction> m_applyFunction; - WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter; + WriteBarrier<JSFunction> m_throwTypeErrorFunction; + LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoToStringFunction; + LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoValuesFunction; + LazyProperty<JSGlobalObject, JSFunction> m_initializePromiseFunction; + LazyProperty<JSGlobalObject, JSFunction> m_iteratorProtocolFunction; + WriteBarrier<JSFunction> m_objectProtoValueOfFunction; + WriteBarrier<JSFunction> m_newPromiseCapabilityFunction; + WriteBarrier<JSFunction> m_functionProtoHasInstanceSymbolFunction; + LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorGetterSetter; + WriteBarrier<JSObject> m_regExpProtoExec; + WriteBarrier<JSObject> m_regExpProtoSymbolReplace; + WriteBarrier<JSObject> m_regExpProtoGlobalGetter; + WriteBarrier<JSObject> m_regExpProtoUnicodeGetter; + WriteBarrier<GetterSetter> m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter; + + WriteBarrier<JSModuleLoader> m_moduleLoader; WriteBarrier<ObjectPrototype> m_objectPrototype; WriteBarrier<FunctionPrototype> m_functionPrototype; WriteBarrier<ArrayPrototype> m_arrayPrototype; WriteBarrier<RegExpPrototype> m_regExpPrototype; - WriteBarrier<JSPromisePrototype> m_promisePrototype; + WriteBarrier<IteratorPrototype> m_iteratorPrototype; + WriteBarrier<GeneratorFunctionPrototype> m_generatorFunctionPrototype; + WriteBarrier<GeneratorPrototype> m_generatorPrototype; + WriteBarrier<ModuleLoaderPrototype> m_moduleLoaderPrototype; - WriteBarrier<Structure> m_withScopeStructure; + LazyProperty<JSGlobalObject, Structure> m_debuggerScopeStructure; + LazyProperty<JSGlobalObject, Structure> m_withScopeStructure; WriteBarrier<Structure> m_strictEvalActivationStructure; - WriteBarrier<Structure> m_activationStructure; - WriteBarrier<Structure> m_nameScopeStructure; - WriteBarrier<Structure> m_argumentsStructure; + WriteBarrier<Structure> m_lexicalEnvironmentStructure; + LazyProperty<JSGlobalObject, Structure> m_moduleEnvironmentStructure; + WriteBarrier<Structure> m_directArgumentsStructure; + WriteBarrier<Structure> m_scopedArgumentsStructure; + WriteBarrier<Structure> m_clonedArgumentsStructure; + + WriteBarrier<Structure> m_objectStructureForObjectConstructor; // Lists the actual structures used for having these particular indexing shapes. WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes]; // Lists the structures we should use during allocation for these particular indexing shapes. + // These structures will differ from the originals list above when we are having a bad time. WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes]; - WriteBarrier<Structure> m_callbackConstructorStructure; - WriteBarrier<Structure> m_callbackFunctionStructure; - WriteBarrier<Structure> m_callbackObjectStructure; + LazyProperty<JSGlobalObject, Structure> m_callbackConstructorStructure; + LazyProperty<JSGlobalObject, Structure> m_callbackFunctionStructure; + LazyProperty<JSGlobalObject, Structure> m_callbackObjectStructure; + WriteBarrier<Structure> m_propertyNameIteratorStructure; #if JSC_OBJC_API_ENABLED - WriteBarrier<Structure> m_objcCallbackFunctionStructure; - WriteBarrier<Structure> m_objcWrapperObjectStructure; + LazyProperty<JSGlobalObject, Structure> m_objcCallbackFunctionStructure; + LazyProperty<JSGlobalObject, Structure> m_objcWrapperObjectStructure; #endif - WriteBarrier<Structure> m_nullPrototypeObjectStructure; + LazyProperty<JSGlobalObject, Structure> m_nullPrototypeObjectStructure; + WriteBarrier<Structure> m_calleeStructure; WriteBarrier<Structure> m_functionStructure; - WriteBarrier<Structure> m_boundFunctionStructure; - WriteBarrier<Structure> m_namedFunctionStructure; + LazyProperty<JSGlobalObject, Structure> m_boundFunctionStructure; + LazyProperty<JSGlobalObject, Structure> m_customGetterSetterFunctionStructure; + WriteBarrier<Structure> m_getterSetterStructure; + LazyProperty<JSGlobalObject, Structure> m_nativeStdFunctionStructure; + LazyProperty<JSGlobalObject, Structure> m_namedFunctionStructure; PropertyOffset m_functionNameOffset; WriteBarrier<Structure> m_privateNameStructure; - WriteBarrier<Structure> m_regExpMatchesArrayStructure; WriteBarrier<Structure> m_regExpStructure; - WriteBarrier<Structure> m_internalFunctionStructure; - - WriteBarrier<Structure> m_iteratorResultStructure; - -#if ENABLE(PROMISES) - WriteBarrier<Structure> m_promiseStructure; -#endif // ENABLE(PROMISES) - -#define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ + WriteBarrier<AsyncFunctionPrototype> m_asyncFunctionPrototype; + WriteBarrier<Structure> m_asyncFunctionStructure; + WriteBarrier<Structure> m_generatorFunctionStructure; + WriteBarrier<Structure> m_dollarVMStructure; + WriteBarrier<Structure> m_iteratorResultObjectStructure; + WriteBarrier<Structure> m_regExpMatchesArrayStructure; + WriteBarrier<Structure> m_moduleRecordStructure; + WriteBarrier<Structure> m_moduleNamespaceObjectStructure; + WriteBarrier<Structure> m_proxyObjectStructure; + WriteBarrier<Structure> m_callableProxyObjectStructure; + WriteBarrier<Structure> m_proxyRevokeStructure; + WriteBarrier<Structure> m_moduleLoaderStructure; + WriteBarrier<JSArrayBufferPrototype> m_arrayBufferPrototype; + WriteBarrier<Structure> m_arrayBufferStructure; + WriteBarrier<JSArrayBufferPrototype> m_sharedArrayBufferPrototype; + WriteBarrier<Structure> m_sharedArrayBufferStructure; + +#define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \ WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; \ WriteBarrier<Structure> m_ ## properName ## Structure; FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE) + +#if ENABLE(WEBASSEMBLY) + WriteBarrier<Structure> m_webAssemblyStructure; + WriteBarrier<Structure> m_webAssemblyModuleRecordStructure; + WriteBarrier<Structure> m_webAssemblyFunctionStructure; + FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE) +#endif // ENABLE(WEBASSEMBLY) #undef DEFINE_STORAGE_FOR_SIMPLE_TYPE - struct TypedArrayData { - WriteBarrier<JSObject> prototype; - WriteBarrier<Structure> structure; - }; +#define DEFINE_STORAGE_FOR_ITERATOR_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \ + LazyProperty<JSGlobalObject, Structure> m_ ## properName ## Structure; + FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_ITERATOR_TYPE) +#undef DEFINE_STORAGE_FOR_ITERATOR_TYPE - std::array<TypedArrayData, NUMBER_OF_TYPED_ARRAY_TYPES> m_typedArrays; - - void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. +#define DEFINE_STORAGE_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \ + LazyClassStructure m_ ## properName ## Structure; + FOR_EACH_LAZY_BUILTIN_TYPE(DEFINE_STORAGE_FOR_LAZY_TYPE) +#undef DEFINE_STORAGE_FOR_LAZY_TYPE + + WriteBarrier<GetterSetter> m_speciesGetterSetter; + + LazyProperty<JSGlobalObject, JSTypedArrayViewPrototype> m_typedArrayProto; + LazyProperty<JSGlobalObject, JSTypedArrayViewConstructor> m_typedArraySuperConstructor; + +#define DECLARE_TYPED_ARRAY_TYPE_STRUCTURE(name) LazyClassStructure m_typedArray ## name; + FOR_EACH_TYPED_ARRAY_TYPE(DECLARE_TYPED_ARRAY_TYPE_STRUCTURE) +#undef DECLARE_TYPED_ARRAY_TYPE_STRUCTURE + + JSCell* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. + JSCell* m_linkTimeConstants[LinkTimeConstantCount]; String m_name; Debugger* m_debugger; + VM& m_vm; + +#if ENABLE(WEB_REPLAY) + Ref<InputCursor> m_inputCursor; +#endif + #if ENABLE(REMOTE_INSPECTOR) + std::unique_ptr<Inspector::JSGlobalObjectInspectorController> m_inspectorController; std::unique_ptr<JSGlobalObjectDebuggable> m_inspectorDebuggable; #endif +#if ENABLE(INTL) + HashSet<String> m_intlCollatorAvailableLocales; + HashSet<String> m_intlDateTimeFormatAvailableLocales; + HashSet<String> m_intlNumberFormatAvailableLocales; +#endif // ENABLE(INTL) + RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint; RefPtr<WatchpointSet> m_havingABadTimeWatchpoint; RefPtr<WatchpointSet> m_varInjectionWatchpoint; - OwnPtr<JSGlobalObjectRareData> m_rareData; + std::unique_ptr<JSGlobalObjectRareData> m_rareData; WeakRandom m_weakRandom; + InlineWatchpointSet& arrayIteratorProtocolWatchpoint() { return m_arrayIteratorProtocolWatchpoint; } + InlineWatchpointSet& arraySpeciesWatchpoint() { return m_arraySpeciesWatchpoint; } + // If this hasn't been invalidated, it means the array iterator protocol + // is not observable to user code yet. + InlineWatchpointSet m_arrayIteratorProtocolWatchpoint; + InlineWatchpointSet m_arraySpeciesWatchpoint; + std::unique_ptr<ArrayIteratorAdaptiveWatchpoint> m_arrayPrototypeSymbolIteratorWatchpoint; + std::unique_ptr<ArrayIteratorAdaptiveWatchpoint> m_arrayIteratorPrototypeNext; + + bool isArrayIteratorProtocolFastAndNonObservable(); + + TemplateRegistry m_templateRegistry; + bool m_evalEnabled; String m_evalDisabledErrorMessage; - bool m_experimentsEnabled; + RuntimeFlags m_runtimeFlags; + ConsoleClient* m_consoleClient; static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable; const GlobalObjectMethodTable* m_globalObjectMethodTable; @@ -248,122 +426,127 @@ protected: { if (m_rareData) return; - m_rareData = adoptPtr(new JSGlobalObjectRareData); + m_rareData = std::make_unique<JSGlobalObjectRareData>(); } public: typedef JSSegmentedVariableObject Base; + static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | OverridesToThis; - static JSGlobalObject* create(VM& vm, Structure* structure) - { - JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure); - globalObject->finishCreation(vm); - vm.heap.addFinalizer(globalObject, destroy); - return globalObject; - } + JS_EXPORT_PRIVATE static JSGlobalObject* create(VM&, Structure*); DECLARE_EXPORT_INFO; - bool hasDebugger() const { return m_debugger; } - bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); } + bool hasDebugger() const; + bool hasInteractiveDebugger() const; + const RuntimeFlags& runtimeFlags() const { return m_runtimeFlags; } protected: JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0); - void finishCreation(VM& vm) - { - Base::finishCreation(vm); - structure()->setGlobalObject(vm, this); - m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); - init(this); - } + JS_EXPORT_PRIVATE void finishCreation(VM&); - void finishCreation(VM& vm, JSObject* thisValue) - { - Base::finishCreation(vm); - structure()->setGlobalObject(vm, this); - m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); - init(thisValue); - } + JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject*); - struct NewGlobalVar { - int registerNumber; - VariableWatchpointSet* set; - }; - NewGlobalVar addGlobalVar(const Identifier&, ConstantMode); + void addGlobalVar(const Identifier&); public: JS_EXPORT_PRIVATE ~JSGlobalObject(); JS_EXPORT_PRIVATE static void destroy(JSCell*); - // We don't need a destructor because we use a finalizer instead. - static const bool needsDestruction = false; JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); - bool hasOwnPropertyForWrite(ExecState*, PropertyName); - JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + JS_EXPORT_PRIVATE static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes); JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes); JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); - // We use this in the code generator as we perform symbol table - // lookups prior to initializing the properties - bool symbolTableHasProperty(PropertyName); - void addVar(ExecState* exec, const Identifier& propertyName) { if (!hasProperty(exec, propertyName)) - addGlobalVar(propertyName, IsVariable); + addGlobalVar(propertyName); } - void addConst(ExecState* exec, const Identifier& propertyName) - { - if (!hasProperty(exec, propertyName)) - addGlobalVar(propertyName, IsConstant); - } - void addFunction(ExecState*, const Identifier&, JSValue); + void addFunction(ExecState*, const Identifier&); + + JSScope* globalScope() { return m_globalLexicalEnvironment.get(); } + JSGlobalLexicalEnvironment* globalLexicalEnvironment() { return m_globalLexicalEnvironment.get(); } + + JSScope* globalScopeExtension() { return m_globalScopeExtension.get(); } + void setGlobalScopeExtension(JSScope*); + void clearGlobalScopeExtension(); // The following accessors return pristine values, even if a script // replaces the global object's associated property. + GetterSetter* speciesGetterSetter() const { return m_speciesGetterSetter.get(); } + RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); } ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); } - NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); } + ArrayConstructor* arrayConstructor() const { return m_arrayConstructor.get(); } + ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); } + JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); } + JSInternalPromiseConstructor* internalPromiseConstructor() const { return m_internalPromiseConstructor.get(); } + NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(this); } NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); } - NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); } - NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); } + NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(this); } + NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(this); } NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); } - NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); } - JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); } + NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(this); } + + NullGetterFunction* nullGetterFunction() const { return m_nullGetterFunction.get(); } + NullSetterFunction* nullSetterFunction() const { return m_nullSetterFunction.get(); } + + JSFunction* parseIntFunction() const { return m_parseIntFunction.get(); } JSFunction* evalFunction() const { return m_evalFunction.get(); } JSFunction* callFunction() const { return m_callFunction.get(); } JSFunction* applyFunction() const { return m_applyFunction.get(); } - GetterSetter* throwTypeErrorGetterSetter(VM& vm) + JSFunction* throwTypeErrorFunction() const { return m_throwTypeErrorFunction.get(); } + JSFunction* arrayProtoToStringFunction() const { return m_arrayProtoToStringFunction.get(this); } + JSFunction* arrayProtoValuesFunction() const { return m_arrayProtoValuesFunction.get(this); } + JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(this); } + JSFunction* iteratorProtocolFunction() const { return m_iteratorProtocolFunction.get(this); } + JSFunction* objectProtoValueOfFunction() const { return m_objectProtoValueOfFunction.get(); } + JSFunction* newPromiseCapabilityFunction() const { return m_newPromiseCapabilityFunction.get(); } + JSFunction* functionProtoHasInstanceSymbolFunction() const { return m_functionProtoHasInstanceSymbolFunction.get(); } + JSObject* regExpProtoExecFunction() const { return m_regExpProtoExec.get(); } + JSObject* regExpProtoSymbolReplaceFunction() const { return m_regExpProtoSymbolReplace.get(); } + JSObject* regExpProtoGlobalGetter() const { return m_regExpProtoGlobalGetter.get(); } + JSObject* regExpProtoUnicodeGetter() const { return m_regExpProtoUnicodeGetter.get(); } + GetterSetter* throwTypeErrorArgumentsCalleeAndCallerGetterSetter() { - if (!m_throwTypeErrorGetterSetter) - createThrowTypeError(vm); - return m_throwTypeErrorGetterSetter.get(); + return m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.get(); } + + JSModuleLoader* moduleLoader() const { return m_moduleLoader.get(); } ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); } FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); } ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); } - BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); } + JSObject* booleanPrototype() const { return m_booleanObjectStructure.prototype(this); } StringPrototype* stringPrototype() const { return m_stringPrototype.get(); } - NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); } - DatePrototype* datePrototype() const { return m_datePrototype.get(); } + SymbolPrototype* symbolPrototype() const { return m_symbolPrototype.get(); } + JSObject* numberPrototype() const { return m_numberPrototype.get(); } + JSObject* datePrototype() const { return m_dateStructure.prototype(this); } RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); } ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); } - JSPromisePrototype* promisePrototype() const { return m_promisePrototype.get(); } + IteratorPrototype* iteratorPrototype() const { return m_iteratorPrototype.get(); } + GeneratorFunctionPrototype* generatorFunctionPrototype() const { return m_generatorFunctionPrototype.get(); } + GeneratorPrototype* generatorPrototype() const { return m_generatorPrototype.get(); } + AsyncFunctionPrototype* asyncFunctionPrototype() const { return m_asyncFunctionPrototype.get(); } - Structure* withScopeStructure() const { return m_withScopeStructure.get(); } + Structure* debuggerScopeStructure() const { return m_debuggerScopeStructure.get(this); } + Structure* withScopeStructure() const { return m_withScopeStructure.get(this); } Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } - Structure* activationStructure() const { return m_activationStructure.get(); } - Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } - Structure* argumentsStructure() const { return m_argumentsStructure.get(); } + Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); } + Structure* moduleEnvironmentStructure() const { return m_moduleEnvironmentStructure.get(this); } + Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); } + Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); } + Structure* clonedArgumentsStructure() const { return m_clonedArgumentsStructure.get(); } + Structure* objectStructureForObjectConstructor() const { return m_objectStructureForObjectConstructor.get(); } Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const { ASSERT(indexingType & IsArray); @@ -374,9 +557,13 @@ public: ASSERT(indexingType & IsArray); return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); } - Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const + Structure* arrayStructureForIndexingTypeDuringAllocation(ExecState* exec, IndexingType indexingType, JSValue newTarget) const + { + return InternalFunction::createSubclassStructure(exec, newTarget, arrayStructureForIndexingTypeDuringAllocation(indexingType)); + } + Structure* arrayStructureForProfileDuringAllocation(ExecState* exec, ArrayAllocationProfile* profile, JSValue newTarget) const { - return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile)); + return arrayStructureForIndexingTypeDuringAllocation(exec, ArrayAllocationProfile::selectIndexingTypeFor(profile), newTarget); } bool isOriginalArrayStructure(Structure* structure) @@ -384,68 +571,167 @@ public: return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure; } - Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } - Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } - Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } - Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); } + Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(this); } + Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(this); } + Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(this); } + Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(this); } + Structure* propertyNameIteratorStructure() const { return m_propertyNameIteratorStructure.get(); } #if JSC_OBJC_API_ENABLED - Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(); } - Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(); } + Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(this); } + Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(this); } #endif - Structure* dateStructure() const { return m_dateStructure.get(); } - Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); } + Structure* dateStructure() const { return m_dateStructure.get(this); } + Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(this); } Structure* errorStructure() const { return m_errorStructure.get(); } + Structure* calleeStructure() const { return m_calleeStructure.get(); } Structure* functionStructure() const { return m_functionStructure.get(); } - Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); } - Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); } + Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(this); } + Structure* customGetterSetterFunctionStructure() const { return m_customGetterSetterFunctionStructure.get(this); } + Structure* getterSetterStructure() const { return m_getterSetterStructure.get(); } + Structure* nativeStdFunctionStructure() const { return m_nativeStdFunctionStructure.get(this); } + Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(this); } PropertyOffset functionNameOffset() const { return m_functionNameOffset; } Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); } Structure* privateNameStructure() const { return m_privateNameStructure.get(); } - Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); } Structure* mapStructure() const { return m_mapStructure.get(); } - Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } Structure* regExpStructure() const { return m_regExpStructure.get(); } - Structure* setStructure() const { return m_setStructure.get(); } + Structure* generatorFunctionStructure() const { return m_generatorFunctionStructure.get(); } + Structure* asyncFunctionStructure() const { return m_asyncFunctionStructure.get(); } + Structure* setStructure() const { return m_setStructure.get(this); } Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } - Structure* iteratorResultStructure() const { return m_iteratorResultStructure.get(); } - static ptrdiff_t iteratorResultStructureOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_iteratorResultStructure); } - -#if ENABLE(PROMISES) - Structure* promiseStructure() const { return m_promiseStructure.get(); } -#endif // ENABLE(PROMISES) + Structure* symbolObjectStructure() const { return m_symbolObjectStructure.get(); } + Structure* iteratorResultObjectStructure() const { return m_iteratorResultObjectStructure.get(); } + Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } + Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(); } + Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(); } + Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(); } + Structure* callableProxyObjectStructure() const { return m_callableProxyObjectStructure.get(); } + Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); } + Structure* moduleLoaderStructure() const { return m_moduleLoaderStructure.get(); } + Structure* restParameterStructure() const { return arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous); } +#if ENABLE(WEBASSEMBLY) + Structure* webAssemblyModuleRecordStructure() const { return m_webAssemblyModuleRecordStructure.get(); } + Structure* webAssemblyFunctionStructure() const { return m_webAssemblyFunctionStructure.get(); } +#endif // ENABLE(WEBASSEMBLY) JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool); JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const; +#if ENABLE(WEB_REPLAY) + JS_EXPORT_PRIVATE void setInputCursor(Ref<InputCursor>&&); + InputCursor& inputCursor() const { return m_inputCursor.get(); } +#endif + +#if ENABLE(REMOTE_INSPECTOR) + Inspector::JSGlobalObjectInspectorController& inspectorController() const { return *m_inspectorController.get(); } + JSGlobalObjectDebuggable& inspectorDebuggable() { return *m_inspectorDebuggable.get(); } +#endif + +#if ENABLE(INTL) + const HashSet<String>& intlCollatorAvailableLocales(); + const HashSet<String>& intlDateTimeFormatAvailableLocales(); + const HashSet<String>& intlNumberFormatAvailableLocales(); +#endif // ENABLE(INTL) + + void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; } + ConsoleClient* consoleClient() const { return m_consoleClient; } + void setName(const String&); const String& name() const { return m_name; } - JSArrayBufferPrototype* arrayBufferPrototype() const { return m_arrayBufferPrototype.get(); } + JSArrayBufferPrototype* arrayBufferPrototype(ArrayBufferSharingMode sharingMode) const + { + switch (sharingMode) { + case ArrayBufferSharingMode::Default: + return m_arrayBufferPrototype.get(); + case ArrayBufferSharingMode::Shared: + return m_sharedArrayBufferPrototype.get(); + } + } + Structure* arrayBufferStructure(ArrayBufferSharingMode sharingMode) const + { + switch (sharingMode) { + case ArrayBufferSharingMode::Default: + return m_arrayBufferStructure.get(); + case ArrayBufferSharingMode::Shared: + return m_sharedArrayBufferStructure.get(); + } + RELEASE_ASSERT_NOT_REACHED(); + return nullptr; + } -#define DEFINE_ACCESSORS_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ +#define DEFINE_ACCESSORS_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \ Structure* properName ## Structure() { return m_ ## properName ## Structure.get(); } FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE) + FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE) #undef DEFINE_ACCESSORS_FOR_SIMPLE_TYPE +#define DEFINE_ACCESSORS_FOR_ITERATOR_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \ + Structure* properName ## Structure() { return m_ ## properName ## Structure.get(this); } + + FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_ACCESSORS_FOR_ITERATOR_TYPE) + +#undef DEFINE_ACCESSORS_FOR_ITERATOR_TYPE + +#define DEFINE_ACCESSORS_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \ + Structure* properName ## Structure() { return m_ ## properName ## Structure.get(this); } + + FOR_EACH_LAZY_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_LAZY_TYPE) + +#undef DEFINE_ACCESSORS_FOR_LAZY_TYPE + + LazyClassStructure& lazyTypedArrayStructure(TypedArrayType type) + { + switch (type) { + case NotTypedArray: + RELEASE_ASSERT_NOT_REACHED(); + return m_typedArrayInt8; +#define TYPED_ARRAY_TYPE_CASE(name) case Type ## name: return m_typedArray ## name; + FOR_EACH_TYPED_ARRAY_TYPE(TYPED_ARRAY_TYPE_CASE) +#undef TYPED_ARRAY_TYPE_CASE + } + RELEASE_ASSERT_NOT_REACHED(); + return m_typedArrayInt8; + } + const LazyClassStructure& lazyTypedArrayStructure(TypedArrayType type) const + { + return const_cast<const LazyClassStructure&>(const_cast<JSGlobalObject*>(this)->lazyTypedArrayStructure(type)); + } + Structure* typedArrayStructure(TypedArrayType type) const { - return m_typedArrays[toIndex(type)].structure.get(); + return lazyTypedArrayStructure(type).get(this); + } + Structure* typedArrayStructureConcurrently(TypedArrayType type) const + { + return lazyTypedArrayStructure(type).getConcurrently(); } bool isOriginalTypedArrayStructure(Structure* structure) { TypedArrayType type = structure->classInfo()->typedArrayStorageType; if (type == NotTypedArray) return false; - return typedArrayStructure(type) == structure; + return typedArrayStructureConcurrently(type) == structure; + } + + JSObject* typedArrayConstructor(TypedArrayType type) const + { + return lazyTypedArrayStructure(type).constructor(this); } - void* actualPointerFor(Special::Pointer pointer) + JSCell* actualPointerFor(Special::Pointer pointer) { ASSERT(pointer < Special::TableSize); return m_specialPointers[pointer]; } + JSCell* jsCellForLinkTimeConstant(LinkTimeConstant type) + { + unsigned index = static_cast<unsigned>(type); + ASSERT(index < LinkTimeConstantCount); + return m_linkTimeConstants[index]; + } WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); } WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); } @@ -475,17 +761,15 @@ public: const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; } - static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; } - static bool supportsProfiling(const JSGlobalObject*) { return false; } static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } JS_EXPORT_PRIVATE ExecState* globalExec(); static bool shouldInterruptScript(const JSGlobalObject*) { return true; } static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; } - static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; } + static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags(); } - void queueMicrotask(PassRefPtr<Microtask>); + void queueMicrotask(Ref<Microtask>&&); bool evalEnabled() const { return m_evalEnabled; } const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } @@ -497,13 +781,14 @@ public: void resetPrototype(VM&, JSValue prototype); - VM& vm() const { return *Heap::heap(this)->vm(); } + VM& vm() const { return m_vm; } JSObject* globalThis() const; - JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis); static Structure* createStructure(VM& vm, JSValue prototype) { - return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); + Structure* result = Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); + result->setTransitionWatchpointIsLikelyToBeFired(true); + return result; } void registerWeakMap(OpaqueJSWeakObjectMap* map) @@ -524,16 +809,16 @@ public: return m_rareData->opaqueJSClassData; } + TemplateRegistry& templateRegistry() { return m_templateRegistry; } + + static ptrdiff_t weakRandomOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_weakRandom); } double weakRandomNumber() { return m_weakRandom.get(); } unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } + WeakRandom& weakRandom() { return m_weakRandom; } - UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); - UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*); + bool needsSiteSpecificQuirks() const { return m_needsSiteSpecificQuirks; } protected: - - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; - struct GlobalPropertyInfo { GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) : identifier(i) @@ -550,16 +835,18 @@ protected: JS_EXPORT_PRIVATE static JSC::JSValue toThis(JSC::JSCell*, JSC::ExecState*, ECMAMode); + void setNeedsSiteSpecificQuirks(bool needQuirks) { m_needsSiteSpecificQuirks = needQuirks; } + private: friend class LLIntOffsetsExtractor; - - // FIXME: Fold reset into init. - JS_EXPORT_PRIVATE void init(JSObject* thisValue); - void reset(JSValue prototype); - void createThrowTypeError(VM&); + JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis); + + JS_EXPORT_PRIVATE void init(VM&); JS_EXPORT_PRIVATE static void clearRareData(JSCell*); + + bool m_needsSiteSpecificQuirks { false }; }; JSGlobalObject* asGlobalObject(JSValue); @@ -570,59 +857,70 @@ inline JSGlobalObject* asGlobalObject(JSValue value) return jsCast<JSGlobalObject*>(asObject(value)); } -inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) +inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0, JSValue newTarget = JSValue()) { - PropertySlot slot(this); - if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) - return true; - bool slotIsWriteable; - return symbolTableGet(this, propertyName, slot, slotIsWriteable); + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + Structure* structure; + if (initialLength >= MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH) + structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(exec, ArrayWithArrayStorage, newTarget); + else + structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget); + RETURN_IF_EXCEPTION(scope, nullptr); + + return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), structure, initialLength)); } -inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName) +inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0, JSValue newTarget = JSValue()) { - SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); - return !entry.isNull(); + return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength, newTarget); } - -inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0) + +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values, JSValue newTarget = JSValue()) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength)); + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget); + RETURN_IF_EXCEPTION(scope, nullptr); + return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, structure, values)); } -inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0) +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values, JSValue newTarget = JSValue()) { - return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength); -} - -inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values) -{ - return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values)); + return constructArray(exec, profile, exec->lexicalGlobalObject(), values, newTarget); } -inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values) +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length, JSValue newTarget = JSValue()) { - return constructArray(exec, profile, exec->lexicalGlobalObject(), values); + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget); + RETURN_IF_EXCEPTION(scope, nullptr); + return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, structure, values, length)); } -inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length, JSValue newTarget = JSValue()) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); + return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length, newTarget); } -inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) +inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length, JSValue newTarget = JSValue()) { - return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length); + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget); + RETURN_IF_EXCEPTION(scope, nullptr); + return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArrayNegativeIndexed(exec, structure, values, length)); } -inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) +inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length, JSValue newTarget = JSValue()) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArrayNegativeIndexed(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); + return constructArrayNegativeIndexed(exec, profile, exec->lexicalGlobalObject(), values, length, newTarget); } -inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) +inline JSObject* ExecState::globalThisValue() const { - return constructArrayNegativeIndexed(exec, profile, exec->lexicalGlobalObject(), values, length); + return lexicalGlobalObject()->globalThis(); } inline JSObject* JSScope::globalThis() @@ -636,5 +934,3 @@ inline JSObject* JSGlobalObject::globalThis() const } } // namespace JSC - -#endif // JSGlobalObject_h |