Speed up JSGlobalObject initialization by making some properties lazy
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSGlobalObject.h
1 /*
2  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3  *  Copyright (C) 2007, 2008, 2009, 2014-2016 Apple Inc. All rights reserved.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Library General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Library General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Library General Public License
16  *  along with this library; see the file COPYING.LIB.  If not, write to
17  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  *  Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef JSGlobalObject_h
23 #define JSGlobalObject_h
24
25 #include "ArrayAllocationProfile.h"
26 #include "InternalFunction.h"
27 #include "JSArray.h"
28 #include "JSArrayBufferPrototype.h"
29 #include "JSClassRef.h"
30 #include "JSGlobalLexicalEnvironment.h"
31 #include "JSProxy.h"
32 #include "JSSegmentedVariableObject.h"
33 #include "JSWeakObjectMapRefInternal.h"
34 #include "LazyProperty.h"
35 #include "LazyClassStructure.h"
36 #include "NumberPrototype.h"
37 #include "RuntimeFlags.h"
38 #include "SpecialPointer.h"
39 #include "StringPrototype.h"
40 #include "SymbolPrototype.h"
41 #include "TemplateRegistry.h"
42 #include "VM.h"
43 #include "Watchpoint.h"
44 #include <JavaScriptCore/JSBase.h>
45 #include <array>
46 #include <wtf/HashSet.h>
47 #include <wtf/PassRefPtr.h>
48
49 struct OpaqueJSClass;
50 struct OpaqueJSClassContextData;
51
52 namespace Inspector {
53 class JSGlobalObjectInspectorController;
54 }
55
56 namespace JSC {
57
58 class ArrayPrototype;
59 class BooleanPrototype;
60 class ConsoleClient;
61 class Debugger;
62 class ErrorConstructor;
63 class ErrorPrototype;
64 class EvalCodeBlock;
65 class EvalExecutable;
66 class FunctionCodeBlock;
67 class FunctionExecutable;
68 class FunctionPrototype;
69 class GeneratorPrototype;
70 class GeneratorFunctionPrototype;
71 class GetterSetter;
72 class GlobalCodeBlock;
73 class InputCursor;
74 class JSGlobalObjectDebuggable;
75 class JSInternalPromise;
76 class JSPromise;
77 class JSPromiseConstructor;
78 class JSPromisePrototype;
79 class JSStack;
80 class JSTypedArrayViewConstructor;
81 class JSTypedArrayViewPrototype;
82 class LLIntOffsetsExtractor;
83 class Microtask;
84 class ModuleLoaderObject;
85 class ModuleProgramExecutable;
86 class NativeErrorConstructor;
87 class NullGetterFunction;
88 class NullSetterFunction;
89 class ObjectConstructor;
90 class ProgramCodeBlock;
91 class ProgramExecutable;
92 class RegExpConstructor;
93 class RegExpPrototype;
94 class SourceCode;
95 class UnlinkedModuleProgramCodeBlock;
96 class VariableEnvironment;
97 enum class ThisTDZMode;
98 struct ActivationStackNode;
99 struct HashTable;
100
101 #define DEFINE_STANDARD_BUILTIN(macro, upperName, lowerName) macro(upperName, lowerName, lowerName, JS ## upperName, upperName)
102
103 #define FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
104     macro(String, string, stringObject, StringObject, String) \
105     macro(Symbol, symbol, symbolObject, SymbolObject, Symbol) \
106     macro(Number, number, numberObject, NumberObject, Number) \
107     macro(Error, error, error, ErrorInstance, Error) \
108     macro(Map, map, map, JSMap, Map) \
109     macro(JSPromise, promise, promise, JSPromise, Promise) \
110     macro(JSArrayBuffer, arrayBuffer, arrayBuffer, JSArrayBuffer, ArrayBuffer) \
111
112 #define FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \
113     DEFINE_STANDARD_BUILTIN(macro, ArrayIterator, arrayIterator) \
114     DEFINE_STANDARD_BUILTIN(macro, MapIterator, mapIterator) \
115     DEFINE_STANDARD_BUILTIN(macro, SetIterator, setIterator) \
116     DEFINE_STANDARD_BUILTIN(macro, StringIterator, stringIterator) \
117
118 #define FOR_EACH_BUILTIN_ITERATOR_TYPE(macro) \
119     DEFINE_STANDARD_BUILTIN(macro, Iterator, iterator) \
120     FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \
121
122 #define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \
123     FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
124     macro(JSInternalPromise, internalPromise, internalPromise, JSInternalPromise, InternalPromise) \
125
126 #define FOR_EACH_LAZY_BUILTIN_TYPE(macro) \
127     macro(Set, set, set, JSSet, Set) \
128     macro(Date, date, date, DateInstance, Date) \
129     macro(Boolean, boolean, booleanObject, BooleanObject, Boolean) \
130     DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \
131     DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \
132
133 #define DECLARE_SIMPLE_BUILTIN_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
134     class JS ## capitalName; \
135     class capitalName ## Prototype; \
136     class capitalName ## Constructor;
137
138 class IteratorPrototype;
139 FOR_EACH_SIMPLE_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
140 FOR_EACH_LAZY_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
141 FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
142
143 #undef DECLARE_SIMPLE_BUILTIN_TYPE
144
145 class JSInternalPromise;
146 class InternalPromisePrototype;
147 class InternalPromiseConstructor;
148
149 typedef Vector<ExecState*, 16> ExecStateStack;
150
151 struct GlobalObjectMethodTable {
152     typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*);
153     AllowsAccessFromFunctionPtr allowsAccessFrom;
154
155     typedef bool (*SupportsLegacyProfilingFunctionPtr)(const JSGlobalObject*);
156     SupportsLegacyProfilingFunctionPtr supportsLegacyProfiling;
157
158     typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*);
159     SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo;
160
161     typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*);
162     ShouldInterruptScriptFunctionPtr shouldInterruptScript;
163
164     typedef RuntimeFlags (*JavaScriptRuntimeFlagsFunctionPtr)(const JSGlobalObject*);
165     JavaScriptRuntimeFlagsFunctionPtr javaScriptRuntimeFlags;
166
167     typedef void (*QueueTaskToEventLoopFunctionPtr)(const JSGlobalObject*, PassRefPtr<Microtask>);
168     QueueTaskToEventLoopFunctionPtr queueTaskToEventLoop;
169
170     typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*);
171     ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout;
172
173     typedef JSInternalPromise* (*ModuleLoaderResolvePtr)(JSGlobalObject*, ExecState*, JSValue, JSValue);
174     ModuleLoaderResolvePtr moduleLoaderResolve;
175
176     typedef JSInternalPromise* (*ModuleLoaderFetchPtr)(JSGlobalObject*, ExecState*, JSValue);
177     ModuleLoaderFetchPtr moduleLoaderFetch;
178
179     typedef JSInternalPromise* (*ModuleLoaderTranslatePtr)(JSGlobalObject*, ExecState*, JSValue, JSValue);
180     ModuleLoaderTranslatePtr moduleLoaderTranslate;
181
182     typedef JSInternalPromise* (*ModuleLoaderInstantiatePtr)(JSGlobalObject*, ExecState*, JSValue, JSValue);
183     ModuleLoaderInstantiatePtr moduleLoaderInstantiate;
184
185     typedef JSValue (*ModuleLoaderEvaluatePtr)(JSGlobalObject*, ExecState*, JSValue, JSValue);
186     ModuleLoaderEvaluatePtr moduleLoaderEvaluate;
187
188     typedef String (*DefaultLanguageFunctionPtr)();
189     DefaultLanguageFunctionPtr defaultLanguage;
190 };
191
192 class JSGlobalObject : public JSSegmentedVariableObject {
193 private:
194     typedef HashSet<RefPtr<OpaqueJSWeakObjectMap>> WeakMapSet;
195     typedef HashMap<OpaqueJSClass*, std::unique_ptr<OpaqueJSClassContextData>> OpaqueJSClassDataMap;
196
197     struct JSGlobalObjectRareData {
198         WTF_MAKE_FAST_ALLOCATED;
199     public:
200         JSGlobalObjectRareData()
201             : profileGroup(0)
202         {
203         }
204
205         WeakMapSet weakMaps;
206         unsigned profileGroup;
207         
208         OpaqueJSClassDataMap opaqueJSClassData;
209     };
210
211 // Our hashtable code-generator tries to access these properties, so we make them public.
212 // However, we'd like it better if they could be protected.
213 public:
214     template<typename T> using Initializer = typename LazyProperty<JSGlobalObject, T>::Initializer;
215     
216     Register m_globalCallFrame[JSStack::CallFrameHeaderSize];
217
218     WriteBarrier<JSObject> m_globalThis;
219
220     WriteBarrier<JSGlobalLexicalEnvironment> m_globalLexicalEnvironment;
221     WriteBarrier<JSObject> m_globalCallee;
222     WriteBarrier<RegExpConstructor> m_regExpConstructor;
223     WriteBarrier<ErrorConstructor> m_errorConstructor;
224     WriteBarrier<Structure> m_nativeErrorPrototypeStructure;
225     WriteBarrier<Structure> m_nativeErrorStructure;
226     LazyProperty<JSGlobalObject, NativeErrorConstructor> m_evalErrorConstructor;
227     WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor;
228     LazyProperty<JSGlobalObject, NativeErrorConstructor> m_referenceErrorConstructor;
229     LazyProperty<JSGlobalObject, NativeErrorConstructor> m_syntaxErrorConstructor;
230     WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor;
231     LazyProperty<JSGlobalObject, NativeErrorConstructor> m_URIErrorConstructor;
232     WriteBarrier<ObjectConstructor> m_objectConstructor;
233     WriteBarrier<JSPromiseConstructor> m_promiseConstructor;
234     WriteBarrier<JSInternalPromiseConstructor> m_internalPromiseConstructor;
235
236     WriteBarrier<NullGetterFunction> m_nullGetterFunction;
237     WriteBarrier<NullSetterFunction> m_nullSetterFunction;
238
239     WriteBarrier<JSFunction> m_parseIntFunction;
240
241     WriteBarrier<JSFunction> m_evalFunction;
242     WriteBarrier<JSFunction> m_callFunction;
243     WriteBarrier<JSFunction> m_applyFunction;
244     WriteBarrier<JSFunction> m_definePropertyFunction;
245     LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoValuesFunction;
246     LazyProperty<JSGlobalObject, JSFunction> m_initializePromiseFunction;
247     WriteBarrier<JSFunction> m_newPromiseCapabilityFunction;
248     WriteBarrier<JSFunction> m_functionProtoHasInstanceSymbolFunction;
249     LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorGetterSetter;
250     WriteBarrier<JSObject> m_regExpProtoExec;
251     WriteBarrier<JSObject> m_regExpProtoSymbolReplace;
252     WriteBarrier<JSObject> m_regExpProtoGlobalGetter;
253     WriteBarrier<JSObject> m_regExpProtoUnicodeGetter;
254     LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorArgumentsAndCallerGetterSetter;
255
256     WriteBarrier<ModuleLoaderObject> m_moduleLoader;
257
258     WriteBarrier<ObjectPrototype> m_objectPrototype;
259     WriteBarrier<FunctionPrototype> m_functionPrototype;
260     WriteBarrier<ArrayPrototype> m_arrayPrototype;
261     WriteBarrier<RegExpPrototype> m_regExpPrototype;
262     WriteBarrier<IteratorPrototype> m_iteratorPrototype;
263     WriteBarrier<GeneratorFunctionPrototype> m_generatorFunctionPrototype;
264     WriteBarrier<GeneratorPrototype> m_generatorPrototype;
265
266     LazyProperty<JSGlobalObject, Structure> m_debuggerScopeStructure;
267     LazyProperty<JSGlobalObject, Structure> m_withScopeStructure;
268     WriteBarrier<Structure> m_strictEvalActivationStructure;
269     WriteBarrier<Structure> m_lexicalEnvironmentStructure;
270     LazyProperty<JSGlobalObject, Structure> m_moduleEnvironmentStructure;
271     WriteBarrier<Structure> m_directArgumentsStructure;
272     WriteBarrier<Structure> m_scopedArgumentsStructure;
273     WriteBarrier<Structure> m_clonedArgumentsStructure;
274         
275     // Lists the actual structures used for having these particular indexing shapes.
276     WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes];
277     // Lists the structures we should use during allocation for these particular indexing shapes.
278     // These structures will differ from the originals list above when we are having a bad time.
279     WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes];
280
281     LazyProperty<JSGlobalObject, Structure> m_callbackConstructorStructure;
282     LazyProperty<JSGlobalObject, Structure> m_callbackFunctionStructure;
283     LazyProperty<JSGlobalObject, Structure> m_callbackObjectStructure;
284     WriteBarrier<Structure> m_propertyNameIteratorStructure;
285 #if JSC_OBJC_API_ENABLED
286     LazyProperty<JSGlobalObject, Structure> m_objcCallbackFunctionStructure;
287     LazyProperty<JSGlobalObject, Structure> m_objcWrapperObjectStructure;
288 #endif
289     LazyProperty<JSGlobalObject, Structure> m_nullPrototypeObjectStructure;
290     WriteBarrier<Structure> m_calleeStructure;
291     WriteBarrier<Structure> m_functionStructure;
292     LazyProperty<JSGlobalObject, Structure> m_boundFunctionStructure;
293     LazyProperty<JSGlobalObject, Structure> m_boundSlotBaseFunctionStructure;
294     WriteBarrier<Structure> m_getterSetterStructure;
295     LazyProperty<JSGlobalObject, Structure> m_nativeStdFunctionStructure;
296     LazyProperty<JSGlobalObject, Structure> m_namedFunctionStructure;
297     PropertyOffset m_functionNameOffset;
298     WriteBarrier<Structure> m_privateNameStructure;
299     WriteBarrier<Structure> m_regExpStructure;
300     WriteBarrier<Structure> m_generatorFunctionStructure;
301     WriteBarrier<Structure> m_dollarVMStructure;
302     WriteBarrier<Structure> m_iteratorResultObjectStructure;
303     WriteBarrier<Structure> m_regExpMatchesArrayStructure;
304     WriteBarrier<Structure> m_regExpMatchesArraySlowPutStructure;
305     WriteBarrier<Structure> m_moduleRecordStructure;
306     WriteBarrier<Structure> m_moduleNamespaceObjectStructure;
307     WriteBarrier<Structure> m_proxyObjectStructure;
308     WriteBarrier<Structure> m_callableProxyObjectStructure;
309     WriteBarrier<Structure> m_proxyRevokeStructure;
310 #if ENABLE(WEBASSEMBLY)
311     WriteBarrier<Structure> m_wasmModuleStructure;
312 #endif
313
314 #define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
315     WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; \
316     WriteBarrier<Structure> m_ ## properName ## Structure;
317
318     FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE)
319
320 #undef DEFINE_STORAGE_FOR_SIMPLE_TYPE
321
322 #define DEFINE_STORAGE_FOR_ITERATOR_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
323     LazyProperty<JSGlobalObject, Structure> m_ ## properName ## Structure;
324     FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_ITERATOR_TYPE)
325 #undef DEFINE_STORAGE_FOR_ITERATOR_TYPE
326     
327 #define DEFINE_STORAGE_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
328     LazyClassStructure m_ ## properName ## Structure;
329     FOR_EACH_LAZY_BUILTIN_TYPE(DEFINE_STORAGE_FOR_LAZY_TYPE)
330 #undef DEFINE_STORAGE_FOR_LAZY_TYPE
331
332     WriteBarrier<GetterSetter> m_speciesGetterSetter;
333     
334     LazyProperty<JSGlobalObject, JSTypedArrayViewPrototype> m_typedArrayProto;
335     LazyProperty<JSGlobalObject, JSTypedArrayViewConstructor> m_typedArraySuperConstructor;
336     
337 #define DECLARE_TYPED_ARRAY_TYPE_STRUCTURE(name) LazyClassStructure m_typedArray ## name;
338     FOR_EACH_TYPED_ARRAY_TYPE(DECLARE_TYPED_ARRAY_TYPE_STRUCTURE)
339 #undef DECLARE_TYPED_ARRAY_TYPE_STRUCTURE
340
341     JSCell* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT.
342     JSCell* m_linkTimeConstants[LinkTimeConstantCount];
343
344     String m_name;
345
346     Debugger* m_debugger;
347
348     VM& m_vm;
349
350 #if ENABLE(WEB_REPLAY)
351     RefPtr<InputCursor> m_inputCursor;
352 #endif
353
354 #if ENABLE(REMOTE_INSPECTOR)
355     std::unique_ptr<Inspector::JSGlobalObjectInspectorController> m_inspectorController;
356     std::unique_ptr<JSGlobalObjectDebuggable> m_inspectorDebuggable;
357 #endif
358
359 #if ENABLE(INTL)
360     HashSet<String> m_intlCollatorAvailableLocales;
361     HashSet<String> m_intlDateTimeFormatAvailableLocales;
362     HashSet<String> m_intlNumberFormatAvailableLocales;
363 #endif // ENABLE(INTL)
364
365     RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint;
366     RefPtr<WatchpointSet> m_havingABadTimeWatchpoint;
367     RefPtr<WatchpointSet> m_varInjectionWatchpoint;
368
369     std::unique_ptr<JSGlobalObjectRareData> m_rareData;
370
371     WeakRandom m_weakRandom;
372
373     TemplateRegistry m_templateRegistry;
374
375     bool m_evalEnabled;
376     String m_evalDisabledErrorMessage;
377     RuntimeFlags m_runtimeFlags;
378     ConsoleClient* m_consoleClient;
379
380     static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable;
381     const GlobalObjectMethodTable* m_globalObjectMethodTable;
382
383     void createRareDataIfNeeded()
384     {
385         if (m_rareData)
386             return;
387         m_rareData = std::make_unique<JSGlobalObjectRareData>();
388     }
389         
390 public:
391     typedef JSSegmentedVariableObject Base;
392     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | OverridesToThis;
393
394     static JSGlobalObject* create(VM& vm, Structure* structure)
395     {
396         JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure);
397         globalObject->finishCreation(vm);
398         vm.heap.addFinalizer(globalObject, destroy);
399         return globalObject;
400     }
401
402     DECLARE_EXPORT_INFO;
403
404     bool hasDebugger() const;
405     bool hasInteractiveDebugger() const;
406     bool hasLegacyProfiler() const;
407     const RuntimeFlags& runtimeFlags() const { return m_runtimeFlags; }
408
409 protected:
410     JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0);
411
412     void finishCreation(VM& vm)
413     {
414         Base::finishCreation(vm);
415         structure()->setGlobalObject(vm, this);
416         m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
417         init(vm);
418         setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(), PureForwardingProxyType), this));
419     }
420
421     void finishCreation(VM& vm, JSObject* thisValue)
422     {
423         Base::finishCreation(vm);
424         structure()->setGlobalObject(vm, this);
425         m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
426         init(vm);
427         setGlobalThis(vm, thisValue);
428     }
429
430     void addGlobalVar(const Identifier&);
431
432 public:
433     JS_EXPORT_PRIVATE ~JSGlobalObject();
434     JS_EXPORT_PRIVATE static void destroy(JSCell*);
435     // We don't need a destructor because we use a finalizer instead.
436     static const bool needsDestruction = false;
437
438     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
439
440     JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
441     JS_EXPORT_PRIVATE static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
442
443     JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes);
444     JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes);
445     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
446
447     void addVar(ExecState* exec, const Identifier& propertyName)
448     {
449         if (!hasProperty(exec, propertyName))
450             addGlobalVar(propertyName);
451     }
452     void addFunction(ExecState*, const Identifier&);
453
454     JSScope* globalScope() { return m_globalLexicalEnvironment.get(); }
455     JSGlobalLexicalEnvironment* globalLexicalEnvironment() { return m_globalLexicalEnvironment.get(); }
456
457     // The following accessors return pristine values, even if a script 
458     // replaces the global object's associated property.
459
460     RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
461
462     ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); }
463     ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); }
464     JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); }
465     JSInternalPromiseConstructor* internalPromiseConstructor() const { return m_internalPromiseConstructor.get(); }
466     NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(this); }
467     NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); }
468     NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(this); }
469     NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(this); }
470     NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); }
471     NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(this); }
472
473     NullGetterFunction* nullGetterFunction() const { return m_nullGetterFunction.get(); }
474     NullSetterFunction* nullSetterFunction() const { return m_nullSetterFunction.get(); }
475
476     JSFunction* parseIntFunction() const { return m_parseIntFunction.get(); }
477
478     JSFunction* evalFunction() const { return m_evalFunction.get(); }
479     JSFunction* callFunction() const { return m_callFunction.get(); }
480     JSFunction* applyFunction() const { return m_applyFunction.get(); }
481     JSFunction* definePropertyFunction() const { return m_definePropertyFunction.get(); }
482     JSFunction* arrayProtoValuesFunction() const { return m_arrayProtoValuesFunction.get(this); }
483     JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(this); }
484     JSFunction* newPromiseCapabilityFunction() const { return m_newPromiseCapabilityFunction.get(); }
485     JSFunction* functionProtoHasInstanceSymbolFunction() const { return m_functionProtoHasInstanceSymbolFunction.get(); }
486     JSObject* regExpProtoExecFunction() const { return m_regExpProtoExec.get(); }
487     JSObject* regExpProtoSymbolReplaceFunction() const { return m_regExpProtoSymbolReplace.get(); }
488     JSObject* regExpProtoGlobalGetter() const { return m_regExpProtoGlobalGetter.get(); }
489     JSObject* regExpProtoUnicodeGetter() const { return m_regExpProtoUnicodeGetter.get(); }
490     GetterSetter* throwTypeErrorGetterSetter()
491     {
492         return m_throwTypeErrorGetterSetter.get(this);
493     }
494
495     GetterSetter* throwTypeErrorArgumentsAndCallerGetterSetter()
496     {
497         return m_throwTypeErrorArgumentsAndCallerGetterSetter.get(this);
498     }
499     
500     ModuleLoaderObject* moduleLoader() const { return m_moduleLoader.get(); }
501
502     ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
503     FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
504     ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
505     JSObject* booleanPrototype() const { return m_booleanObjectStructure.prototype(this); }
506     StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
507     SymbolPrototype* symbolPrototype() const { return m_symbolPrototype.get(); }
508     JSObject* numberPrototype() const { return m_numberPrototype.get(); }
509     JSObject* datePrototype() const { return m_dateStructure.prototype(this); }
510     RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
511     ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); }
512     IteratorPrototype* iteratorPrototype() const { return m_iteratorPrototype.get(); }
513     GeneratorFunctionPrototype* generatorFunctionPrototype() const { return m_generatorFunctionPrototype.get(); }
514     GeneratorPrototype* generatorPrototype() const { return m_generatorPrototype.get(); }
515
516     Structure* debuggerScopeStructure() const { return m_debuggerScopeStructure.get(this); }
517     Structure* withScopeStructure() const { return m_withScopeStructure.get(this); }
518     Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); }
519     Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); }
520     Structure* moduleEnvironmentStructure() const { return m_moduleEnvironmentStructure.get(this); }
521     Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); }
522     Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); }
523     Structure* clonedArgumentsStructure() const { return m_clonedArgumentsStructure.get(); }
524     Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
525     {
526         ASSERT(indexingType & IsArray);
527         return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
528     }
529     Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const
530     {
531         ASSERT(indexingType & IsArray);
532         return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get();
533     }
534     Structure* arrayStructureForIndexingTypeDuringAllocation(ExecState* exec, IndexingType indexingType, JSValue newTarget) const
535     {
536         return InternalFunction::createSubclassStructure(exec, newTarget, arrayStructureForIndexingTypeDuringAllocation(indexingType));
537     }
538     Structure* arrayStructureForProfileDuringAllocation(ExecState* exec, ArrayAllocationProfile* profile, JSValue newTarget) const
539     {
540         return arrayStructureForIndexingTypeDuringAllocation(exec, ArrayAllocationProfile::selectIndexingTypeFor(profile), newTarget);
541     }
542         
543     bool isOriginalArrayStructure(Structure* structure)
544     {
545         return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure;
546     }
547         
548     Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(this); }
549     Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(this); }
550     Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(this); }
551     Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(this); }
552     Structure* propertyNameIteratorStructure() const { return m_propertyNameIteratorStructure.get(); }
553 #if JSC_OBJC_API_ENABLED
554     Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(this); }
555     Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(this); }
556 #endif
557     Structure* dateStructure() const { return m_dateStructure.get(this); }
558     Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(this); }
559     Structure* errorStructure() const { return m_errorStructure.get(); }
560     Structure* calleeStructure() const { return m_calleeStructure.get(); }
561     Structure* functionStructure() const { return m_functionStructure.get(); }
562     Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(this); }
563     Structure* boundSlotBaseFunctionStructure() const { return m_boundSlotBaseFunctionStructure.get(this); }
564     Structure* getterSetterStructure() const { return m_getterSetterStructure.get(); }
565     Structure* nativeStdFunctionStructure() const { return m_nativeStdFunctionStructure.get(this); }
566     Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(this); }
567     PropertyOffset functionNameOffset() const { return m_functionNameOffset; }
568     Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
569     Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
570     Structure* mapStructure() const { return m_mapStructure.get(); }
571     Structure* regExpStructure() const { return m_regExpStructure.get(); }
572     Structure* generatorFunctionStructure() const { return m_generatorFunctionStructure.get(); }
573     Structure* setStructure() const { return m_setStructure.get(this); }
574     Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
575     Structure* symbolObjectStructure() const { return m_symbolObjectStructure.get(); }
576     Structure* iteratorResultObjectStructure() const { return m_iteratorResultObjectStructure.get(); }
577     Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
578     Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(); }
579     Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(); }
580     Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(); }
581     Structure* callableProxyObjectStructure() const { return m_callableProxyObjectStructure.get(); }
582     Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); }
583 #if ENABLE(WEBASSEMBLY)
584     Structure* wasmModuleStructure() const { return m_wasmModuleStructure.get(); }
585 #endif
586
587     JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
588     JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const;
589
590 #if ENABLE(WEB_REPLAY)
591     JS_EXPORT_PRIVATE void setInputCursor(PassRefPtr<InputCursor>);
592     InputCursor& inputCursor() const { return *m_inputCursor; }
593 #endif
594
595 #if ENABLE(REMOTE_INSPECTOR)
596     Inspector::JSGlobalObjectInspectorController& inspectorController() const { return *m_inspectorController.get(); }
597     JSGlobalObjectDebuggable& inspectorDebuggable() { return *m_inspectorDebuggable.get(); }
598 #endif
599
600 #if ENABLE(INTL)
601     const HashSet<String>& intlCollatorAvailableLocales();
602     const HashSet<String>& intlDateTimeFormatAvailableLocales();
603     const HashSet<String>& intlNumberFormatAvailableLocales();
604 #endif // ENABLE(INTL)
605
606     void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; }
607     ConsoleClient* consoleClient() const { return m_consoleClient; }
608
609     void setName(const String&);
610     const String& name() const { return m_name; }
611
612     JSArrayBufferPrototype* arrayBufferPrototype() const { return m_arrayBufferPrototype.get(); }
613
614 #define DEFINE_ACCESSORS_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
615     Structure* properName ## Structure() { return m_ ## properName ## Structure.get(); }
616
617     FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE)
618
619 #undef DEFINE_ACCESSORS_FOR_SIMPLE_TYPE
620
621 #define DEFINE_ACCESSORS_FOR_ITERATOR_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
622     Structure* properName ## Structure() { return m_ ## properName ## Structure.get(this); }
623
624     FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_ACCESSORS_FOR_ITERATOR_TYPE)
625
626 #undef DEFINE_ACCESSORS_FOR_ITERATOR_TYPE
627
628 #define DEFINE_ACCESSORS_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName) \
629     Structure* properName ## Structure() { return m_ ## properName ## Structure.get(this); }
630
631     FOR_EACH_LAZY_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_LAZY_TYPE)
632
633 #undef DEFINE_ACCESSORS_FOR_LAZY_TYPE
634
635     LazyClassStructure& lazyTypedArrayStructure(TypedArrayType type)
636     {
637         switch (type) {
638         case NotTypedArray:
639             RELEASE_ASSERT_NOT_REACHED();
640             return m_typedArrayInt8;
641 #define TYPED_ARRAY_TYPE_CASE(name) case Type ## name: return m_typedArray ## name;
642             FOR_EACH_TYPED_ARRAY_TYPE(TYPED_ARRAY_TYPE_CASE)
643 #undef TYPED_ARRAY_TYPE_CASE
644         }
645         RELEASE_ASSERT_NOT_REACHED();
646         return m_typedArrayInt8;
647     }
648     const LazyClassStructure& lazyTypedArrayStructure(TypedArrayType type) const
649     {
650         return const_cast<const LazyClassStructure&>(const_cast<JSGlobalObject*>(this)->lazyTypedArrayStructure(type));
651     }
652     
653     Structure* typedArrayStructure(TypedArrayType type) const
654     {
655         return lazyTypedArrayStructure(type).get(this);
656     }
657     Structure* typedArrayStructureConcurrently(TypedArrayType type) const
658     {
659         return lazyTypedArrayStructure(type).getConcurrently();
660     }
661     bool isOriginalTypedArrayStructure(Structure* structure)
662     {
663         TypedArrayType type = structure->classInfo()->typedArrayStorageType;
664         if (type == NotTypedArray)
665             return false;
666         return typedArrayStructureConcurrently(type) == structure;
667     }
668
669     JSObject* typedArrayConstructor(TypedArrayType type) const
670     {
671         return lazyTypedArrayStructure(type).constructor(this);
672     }
673
674     JSCell* actualPointerFor(Special::Pointer pointer)
675     {
676         ASSERT(pointer < Special::TableSize);
677         return m_specialPointers[pointer];
678     }
679     JSCell* jsCellForLinkTimeConstant(LinkTimeConstant type)
680     {
681         unsigned index = static_cast<unsigned>(type);
682         ASSERT(index < LinkTimeConstantCount);
683         return m_linkTimeConstants[index];
684     }
685
686     WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
687     WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); }
688     WatchpointSet* varInjectionWatchpoint() { return m_varInjectionWatchpoint.get(); }
689         
690     bool isHavingABadTime() const
691     {
692         return m_havingABadTimeWatchpoint->hasBeenInvalidated();
693     }
694         
695     void haveABadTime(VM&);
696         
697     bool objectPrototypeIsSane();
698     bool arrayPrototypeChainIsSane();
699     bool stringPrototypeChainIsSane();
700
701     void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
702     unsigned profileGroup() const
703     { 
704         if (!m_rareData)
705             return 0;
706         return m_rareData->profileGroup;
707     }
708
709     Debugger* debugger() const { return m_debugger; }
710     void setDebugger(Debugger* debugger) { m_debugger = debugger; }
711
712     const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; }
713
714     static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; }
715     static bool supportsLegacyProfiling(const JSGlobalObject*) { return false; }
716     static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; }
717
718     JS_EXPORT_PRIVATE ExecState* globalExec();
719
720     static bool shouldInterruptScript(const JSGlobalObject*) { return true; }
721     static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; }
722     static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags(); }
723
724     void queueMicrotask(PassRefPtr<Microtask>);
725
726     bool evalEnabled() const { return m_evalEnabled; }
727     const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
728     void setEvalEnabled(bool enabled, const String& errorMessage = String())
729     {
730         m_evalEnabled = enabled;
731         m_evalDisabledErrorMessage = errorMessage;
732     }
733
734     void resetPrototype(VM&, JSValue prototype);
735
736     VM& vm() const { return m_vm; }
737     JSObject* globalThis() const;
738
739     static Structure* createStructure(VM& vm, JSValue prototype)
740     {
741         Structure* result = Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info());
742         result->setTransitionWatchpointIsLikelyToBeFired(true);
743         return result;
744     }
745
746     void registerWeakMap(OpaqueJSWeakObjectMap* map)
747     {
748         createRareDataIfNeeded();
749         m_rareData->weakMaps.add(map);
750     }
751
752     void unregisterWeakMap(OpaqueJSWeakObjectMap* map)
753     {
754         if (m_rareData)
755             m_rareData->weakMaps.remove(map);
756     }
757
758     OpaqueJSClassDataMap& opaqueJSClassData()
759     {
760         createRareDataIfNeeded();
761         return m_rareData->opaqueJSClassData;
762     }
763
764     TemplateRegistry& templateRegistry() { return m_templateRegistry; }
765
766     static ptrdiff_t weakRandomOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_weakRandom); }
767     double weakRandomNumber() { return m_weakRandom.get(); }
768     unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
769
770     UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception);
771     UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, const VariableEnvironment*);
772     UnlinkedModuleProgramCodeBlock* createModuleProgramCodeBlock(CallFrame*, ModuleProgramExecutable*);
773
774 protected:
775     struct GlobalPropertyInfo {
776         GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
777             : identifier(i)
778             , value(v)
779             , attributes(a)
780         {
781         }
782
783         const Identifier identifier;
784         JSValue value;
785         unsigned attributes;
786     };
787     JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
788
789     JS_EXPORT_PRIVATE static JSC::JSValue toThis(JSC::JSCell*, JSC::ExecState*, ECMAMode);
790
791 private:
792     friend class LLIntOffsetsExtractor;
793
794     JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis);
795
796     JS_EXPORT_PRIVATE void init(VM&);
797
798     JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
799 };
800
801 JSGlobalObject* asGlobalObject(JSValue);
802
803 inline JSGlobalObject* asGlobalObject(JSValue value)
804 {
805     ASSERT(asObject(value)->isGlobalObject());
806     return jsCast<JSGlobalObject*>(asObject(value));
807 }
808
809 inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0, JSValue newTarget = JSValue())
810 {
811     Structure* structure;
812     if (initialLength >= MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)
813         structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(exec, ArrayWithArrayStorage, newTarget);
814     else
815         structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
816     if (exec->hadException())
817         return nullptr;
818
819     return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), structure, initialLength));
820 }
821
822 inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0, JSValue newTarget = JSValue())
823 {
824     return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength, newTarget);
825 }
826  
827 inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values, JSValue newTarget = JSValue())
828 {
829     Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
830     if (exec->hadException())
831         return nullptr;
832     return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, structure, values));
833 }
834
835 inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values, JSValue newTarget = JSValue())
836 {
837     return constructArray(exec, profile, exec->lexicalGlobalObject(), values, newTarget);
838 }
839
840 inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
841 {
842     Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
843     if (exec->hadException())
844         return nullptr;
845     return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, structure, values, length));
846 }
847
848 inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
849 {
850     return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length, newTarget);
851 }
852
853 inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
854 {
855     Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
856     if (exec->hadException())
857         return nullptr;
858     return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArrayNegativeIndexed(exec, structure, values, length));
859 }
860
861 inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
862 {
863     return constructArrayNegativeIndexed(exec, profile, exec->lexicalGlobalObject(), values, length, newTarget);
864 }
865
866 inline JSObject* ExecState::globalThisValue() const
867 {
868     return lexicalGlobalObject()->globalThis();
869 }
870
871 inline JSObject* JSScope::globalThis()
872
873     return globalObject()->globalThis();
874 }
875
876 inline JSObject* JSGlobalObject::globalThis() const
877
878     return m_globalThis.get();
879 }
880
881 } // namespace JSC
882
883 #endif // JSGlobalObject_h