1/*
2 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3 * Copyright (C) 2007-2019 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#pragma once
23
24#include "ArrayAllocationProfile.h"
25#include "ArrayBufferSharingMode.h"
26#include "BigIntPrototype.h"
27#include "BooleanPrototype.h"
28#include "ErrorType.h"
29#include "ExceptionHelpers.h"
30#include "InternalFunction.h"
31#include "JSArray.h"
32#include "JSArrayBufferPrototype.h"
33#include "JSClassRef.h"
34#include "JSGlobalLexicalEnvironment.h"
35#include "JSPromiseDeferred.h"
36#include "JSSegmentedVariableObject.h"
37#include "JSWeakObjectMapRefInternal.h"
38#include "LazyProperty.h"
39#include "LazyClassStructure.h"
40#include "NumberPrototype.h"
41#include "RegExpGlobalData.h"
42#include "RuntimeFlags.h"
43#include "SpecialPointer.h"
44#include "StringPrototype.h"
45#include "SymbolPrototype.h"
46#include "VM.h"
47#include "Watchpoint.h"
48#include <JavaScriptCore/JSBase.h>
49#include <array>
50#include <wtf/HashSet.h>
51#include <wtf/RetainPtr.h>
52
53struct OpaqueJSClass;
54struct OpaqueJSClassContextData;
55OBJC_CLASS JSWrapperMap;
56
57namespace Inspector {
58class JSGlobalObjectInspectorController;
59}
60
61namespace JSC {
62class ArrayConstructor;
63class ArrayPrototype;
64class AsyncIteratorPrototype;
65class AsyncFunctionPrototype;
66class AsyncGeneratorPrototype;
67class AsyncGeneratorFunctionPrototype;
68class BooleanPrototype;
69class ConsoleClient;
70class Debugger;
71class ErrorConstructor;
72class ErrorPrototype;
73class EvalCodeBlock;
74class EvalExecutable;
75class FunctionConstructor;
76class FunctionPrototype;
77class GeneratorPrototype;
78class GeneratorFunctionPrototype;
79class GetterSetter;
80class GlobalCodeBlock;
81class IndirectEvalExecutable;
82class InputCursor;
83class IntlObject;
84class IntlCollator;
85class JSArrayBuffer;
86class JSArrayBufferPrototype;
87class JSCallee;
88class JSGlobalObjectDebuggable;
89class JSInternalPromise;
90class JSModuleLoader;
91class JSModuleRecord;
92class JSPromise;
93class JSPromiseConstructor;
94class JSPromisePrototype;
95class JSSharedArrayBuffer;
96class JSSharedArrayBufferPrototype;
97class JSTypedArrayViewConstructor;
98class JSTypedArrayViewPrototype;
99class DirectEvalExecutable;
100class LLIntOffsetsExtractor;
101class MapPrototype;
102class Microtask;
103class ModuleLoader;
104class ModuleProgramExecutable;
105class NativeErrorConstructorBase;
106class NullGetterFunction;
107class NullSetterFunction;
108class ObjectConstructor;
109class ProgramCodeBlock;
110class ProgramExecutable;
111class RegExpConstructor;
112class RegExpPrototype;
113class SetPrototype;
114class SourceCode;
115class SourceOrigin;
116class UnlinkedModuleProgramCodeBlock;
117class VariableEnvironment;
118struct ActivationStackNode;
119struct HashTable;
120
121#ifdef JSC_GLIB_API_ENABLED
122class WrapperMap;
123#endif
124
125template<typename Watchpoint> class ObjectPropertyChangeAdaptiveWatchpoint;
126
127#define DEFINE_STANDARD_BUILTIN(macro, upperName, lowerName) macro(upperName, lowerName, lowerName, JS ## upperName, upperName, object)
128
129#define FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
130 macro(String, string, stringObject, StringObject, String, object) \
131 macro(Map, map, map, JSMap, Map, object) \
132 macro(Set, set, set, JSSet, Set, object) \
133 macro(JSPromise, promise, promise, JSPromise, Promise, object)
134
135#define FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
136 macro(BigInt, bigInt, bigIntObject, BigIntObject, BigInt, object)
137
138#define FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \
139 macro(StringIterator, stringIterator, stringIterator, JSStringIterator, StringIterator, iterator) \
140
141#define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \
142 FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \
143 macro(JSInternalPromise, internalPromise, internalPromise, JSInternalPromise, InternalPromise, object) \
144
145#define FOR_EACH_LAZY_BUILTIN_TYPE_WITH_DECLARATION(macro) \
146 macro(Boolean, boolean, booleanObject, BooleanObject, Boolean, object) \
147 macro(Date, date, date, DateInstance, Date, object) \
148 macro(Error, error, error, ErrorInstance, Error, object) \
149 macro(Number, number, numberObject, NumberObject, Number, object) \
150 macro(Symbol, symbol, symbolObject, SymbolObject, Symbol, object) \
151 DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \
152 DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \
153
154#define FOR_EACH_LAZY_BUILTIN_TYPE(macro) \
155 FOR_EACH_LAZY_BUILTIN_TYPE_WITH_DECLARATION(macro) \
156 macro(JSArrayBuffer, arrayBuffer, arrayBuffer, JSArrayBuffer, ArrayBuffer, object) \
157
158#if ENABLE(WEBASSEMBLY)
159#define FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(macro) \
160 macro(WebAssemblyCompileError, webAssemblyCompileError, webAssemblyCompileError, JSWebAssemblyCompileError, CompileError, error) \
161 macro(WebAssemblyInstance, webAssemblyInstance, webAssemblyInstance, JSWebAssemblyInstance, Instance, object) \
162 macro(WebAssemblyLinkError, webAssemblyLinkError, webAssemblyLinkError, JSWebAssemblyLinkError, LinkError, error) \
163 macro(WebAssemblyMemory, webAssemblyMemory, webAssemblyMemory, JSWebAssemblyMemory, Memory, object) \
164 macro(WebAssemblyModule, webAssemblyModule, webAssemblyModule, JSWebAssemblyModule, Module, object) \
165 macro(WebAssemblyRuntimeError, webAssemblyRuntimeError, webAssemblyRuntimeError, JSWebAssemblyRuntimeError, RuntimeError, error) \
166 macro(WebAssemblyTable, webAssemblyTable, webAssemblyTable, JSWebAssemblyTable, Table, object)
167#else
168#define FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(macro)
169#endif // ENABLE(WEBASSEMBLY)
170
171#define DECLARE_SIMPLE_BUILTIN_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
172 class JS ## capitalName; \
173 class capitalName ## Prototype; \
174 class capitalName ## Constructor;
175
176class IteratorPrototype;
177FOR_EACH_SIMPLE_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
178FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(DECLARE_SIMPLE_BUILTIN_TYPE)
179FOR_EACH_LAZY_BUILTIN_TYPE_WITH_DECLARATION(DECLARE_SIMPLE_BUILTIN_TYPE)
180FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
181FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE)
182
183#undef DECLARE_SIMPLE_BUILTIN_TYPE
184
185enum class JSPromiseRejectionOperation : unsigned {
186 Reject, // When a promise is rejected without any handlers.
187 Handle, // When a handler is added to a rejected promise for the first time.
188};
189
190struct GlobalObjectMethodTable {
191 typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*);
192 SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo;
193
194 typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*);
195 ShouldInterruptScriptFunctionPtr shouldInterruptScript;
196
197 typedef RuntimeFlags (*JavaScriptRuntimeFlagsFunctionPtr)(const JSGlobalObject*);
198 JavaScriptRuntimeFlagsFunctionPtr javaScriptRuntimeFlags;
199
200 typedef void (*QueueTaskToEventLoopFunctionPtr)(JSGlobalObject&, Ref<Microtask>&&);
201 QueueTaskToEventLoopFunctionPtr queueTaskToEventLoop;
202
203 typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*);
204 ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout;
205
206 typedef JSInternalPromise* (*ModuleLoaderImportModulePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSString*, JSValue, const SourceOrigin&);
207 ModuleLoaderImportModulePtr moduleLoaderImportModule;
208
209 typedef Identifier (*ModuleLoaderResolvePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
210 ModuleLoaderResolvePtr moduleLoaderResolve;
211
212 typedef JSInternalPromise* (*ModuleLoaderFetchPtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
213 ModuleLoaderFetchPtr moduleLoaderFetch;
214
215 typedef JSObject* (*ModuleLoaderCreateImportMetaPropertiesPtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue);
216 ModuleLoaderCreateImportMetaPropertiesPtr moduleLoaderCreateImportMetaProperties;
217
218 typedef JSValue (*ModuleLoaderEvaluatePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
219 ModuleLoaderEvaluatePtr moduleLoaderEvaluate;
220
221 typedef void (*PromiseRejectionTrackerPtr)(JSGlobalObject*, ExecState*, JSPromise*, JSPromiseRejectionOperation);
222 PromiseRejectionTrackerPtr promiseRejectionTracker;
223
224 typedef String (*DefaultLanguageFunctionPtr)();
225 DefaultLanguageFunctionPtr defaultLanguage;
226
227 typedef void (*CompileStreamingPtr)(JSGlobalObject*, ExecState*, JSPromiseDeferred*, JSValue);
228 CompileStreamingPtr compileStreaming;
229
230 typedef void (*InstantiateStreamingPtr)(JSGlobalObject*, ExecState*, JSPromiseDeferred*, JSValue, JSObject*);
231 InstantiateStreamingPtr instantiateStreaming;
232};
233
234class JSGlobalObject : public JSSegmentedVariableObject {
235private:
236 typedef HashSet<RefPtr<OpaqueJSWeakObjectMap>> WeakMapSet;
237 typedef HashMap<OpaqueJSClass*, std::unique_ptr<OpaqueJSClassContextData>> OpaqueJSClassDataMap;
238
239 struct JSGlobalObjectRareData {
240 WTF_MAKE_FAST_ALLOCATED;
241 public:
242 JSGlobalObjectRareData()
243 : profileGroup(0)
244 {
245 }
246
247 WeakMapSet weakMaps;
248 unsigned profileGroup;
249
250 OpaqueJSClassDataMap opaqueJSClassData;
251 };
252
253// Our hashtable code-generator tries to access these properties, so we make them public.
254// However, we'd like it better if they could be protected.
255public:
256 template<typename T> using Initializer = typename LazyProperty<JSGlobalObject, T>::Initializer;
257
258 Register m_globalCallFrame[CallFrame::headerSizeInRegisters];
259
260 WriteBarrier<JSObject> m_globalThis;
261
262 WriteBarrier<JSGlobalLexicalEnvironment> m_globalLexicalEnvironment;
263 WriteBarrier<JSScope> m_globalScopeExtension;
264 WriteBarrier<JSCallee> m_globalCallee;
265 WriteBarrier<JSCallee> m_stackOverflowFrameCallee;
266
267 LazyClassStructure m_evalErrorStructure;
268 LazyClassStructure m_rangeErrorStructure;
269 LazyClassStructure m_referenceErrorStructure;
270 LazyClassStructure m_syntaxErrorStructure;
271 LazyClassStructure m_typeErrorStructure;
272 LazyClassStructure m_URIErrorStructure;
273
274 WriteBarrier<ObjectConstructor> m_objectConstructor;
275 WriteBarrier<ArrayConstructor> m_arrayConstructor;
276 WriteBarrier<JSPromiseConstructor> m_promiseConstructor;
277 WriteBarrier<JSInternalPromiseConstructor> m_internalPromiseConstructor;
278
279#if ENABLE(INTL)
280 WriteBarrier<IntlCollator> m_defaultCollator;
281 LazyProperty<JSGlobalObject, Structure> m_collatorStructure;
282 LazyProperty<JSGlobalObject, Structure> m_numberFormatStructure;
283 LazyProperty<JSGlobalObject, Structure> m_dateTimeFormatStructure;
284 LazyProperty<JSGlobalObject, Structure> m_pluralRulesStructure;
285#endif
286 WriteBarrier<NullGetterFunction> m_nullGetterFunction;
287 WriteBarrier<NullSetterFunction> m_nullSetterFunction;
288
289 LazyProperty<JSGlobalObject, JSFunction> m_parseIntFunction;
290 LazyProperty<JSGlobalObject, JSFunction> m_parseFloatFunction;
291
292 WriteBarrier<JSFunction> m_callFunction;
293 WriteBarrier<JSFunction> m_applyFunction;
294 WriteBarrier<JSFunction> m_throwTypeErrorFunction;
295 LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoToStringFunction;
296 LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoValuesFunction;
297 LazyProperty<JSGlobalObject, JSFunction> m_evalFunction;
298 LazyProperty<JSGlobalObject, JSFunction> m_initializePromiseFunction;
299 LazyProperty<JSGlobalObject, JSFunction> m_iteratorProtocolFunction;
300 LazyProperty<JSGlobalObject, JSFunction> m_promiseResolveFunction;
301 WriteBarrier<JSFunction> m_objectProtoValueOfFunction;
302 WriteBarrier<JSFunction> m_numberProtoToStringFunction;
303 WriteBarrier<JSFunction> m_newPromiseCapabilityFunction;
304 WriteBarrier<JSFunction> m_functionProtoHasInstanceSymbolFunction;
305 LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorGetterSetter;
306 WriteBarrier<JSObject> m_regExpProtoExec;
307 WriteBarrier<JSObject> m_regExpProtoSymbolReplace;
308 WriteBarrier<JSObject> m_regExpProtoGlobalGetter;
309 WriteBarrier<JSObject> m_regExpProtoUnicodeGetter;
310 WriteBarrier<GetterSetter> m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter;
311
312 LazyProperty<JSGlobalObject, JSModuleLoader> m_moduleLoader;
313
314 WriteBarrier<ObjectPrototype> m_objectPrototype;
315 WriteBarrier<FunctionPrototype> m_functionPrototype;
316 WriteBarrier<ArrayPrototype> m_arrayPrototype;
317 WriteBarrier<RegExpPrototype> m_regExpPrototype;
318 WriteBarrier<IteratorPrototype> m_iteratorPrototype;
319 WriteBarrier<AsyncIteratorPrototype> m_asyncIteratorPrototype;
320 WriteBarrier<GeneratorFunctionPrototype> m_generatorFunctionPrototype;
321 WriteBarrier<GeneratorPrototype> m_generatorPrototype;
322 WriteBarrier<AsyncGeneratorPrototype> m_asyncGeneratorPrototype;
323
324 LazyProperty<JSGlobalObject, Structure> m_debuggerScopeStructure;
325 LazyProperty<JSGlobalObject, Structure> m_withScopeStructure;
326 LazyProperty<JSGlobalObject, Structure> m_strictEvalActivationStructure;
327 WriteBarrier<Structure> m_lexicalEnvironmentStructure;
328 LazyProperty<JSGlobalObject, Structure> m_moduleEnvironmentStructure;
329 WriteBarrier<Structure> m_directArgumentsStructure;
330 WriteBarrier<Structure> m_scopedArgumentsStructure;
331 WriteBarrier<Structure> m_clonedArgumentsStructure;
332
333 WriteBarrier<Structure> m_objectStructureForObjectConstructor;
334
335 // Lists the actual structures used for having these particular indexing shapes.
336 WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfArrayIndexingModes];
337 // Lists the structures we should use during allocation for these particular indexing shapes.
338 // These structures will differ from the originals list above when we are having a bad time.
339 WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfArrayIndexingModes];
340
341 LazyProperty<JSGlobalObject, Structure> m_callbackConstructorStructure;
342 LazyProperty<JSGlobalObject, Structure> m_callbackFunctionStructure;
343 LazyProperty<JSGlobalObject, Structure> m_callbackObjectStructure;
344#if JSC_OBJC_API_ENABLED
345 LazyProperty<JSGlobalObject, Structure> m_objcCallbackFunctionStructure;
346 LazyProperty<JSGlobalObject, Structure> m_objcWrapperObjectStructure;
347#endif
348#ifdef JSC_GLIB_API_ENABLED
349 LazyProperty<JSGlobalObject, Structure> m_glibCallbackFunctionStructure;
350 LazyProperty<JSGlobalObject, Structure> m_glibWrapperObjectStructure;
351#endif
352 WriteBarrier<Structure> m_nullPrototypeObjectStructure;
353 WriteBarrier<Structure> m_calleeStructure;
354
355 WriteBarrier<Structure> m_hostFunctionStructure;
356
357 struct FunctionStructures {
358 WriteBarrier<Structure> arrowFunctionStructure;
359 WriteBarrier<Structure> sloppyFunctionStructure;
360 WriteBarrier<Structure> strictFunctionStructure;
361 };
362 FunctionStructures m_builtinFunctions;
363 FunctionStructures m_ordinaryFunctions;
364
365 LazyProperty<JSGlobalObject, Structure> m_boundFunctionStructure;
366 LazyProperty<JSGlobalObject, Structure> m_customGetterSetterFunctionStructure;
367 WriteBarrier<Structure> m_getterSetterStructure;
368 LazyProperty<JSGlobalObject, Structure> m_nativeStdFunctionStructure;
369 PropertyOffset m_functionNameOffset;
370 WriteBarrier<Structure> m_regExpStructure;
371 WriteBarrier<AsyncFunctionPrototype> m_asyncFunctionPrototype;
372 WriteBarrier<AsyncGeneratorFunctionPrototype> m_asyncGeneratorFunctionPrototype;
373 WriteBarrier<Structure> m_asyncFunctionStructure;
374 WriteBarrier<Structure> m_asyncGeneratorFunctionStructure;
375 WriteBarrier<Structure> m_generatorFunctionStructure;
376 LazyProperty<JSGlobalObject, Structure> m_iteratorResultObjectStructure;
377 WriteBarrier<Structure> m_regExpMatchesArrayStructure;
378 WriteBarrier<Structure> m_regExpMatchesArrayWithGroupsStructure;
379 LazyProperty<JSGlobalObject, Structure> m_moduleRecordStructure;
380 LazyProperty<JSGlobalObject, Structure> m_moduleNamespaceObjectStructure;
381 LazyProperty<JSGlobalObject, Structure> m_proxyObjectStructure;
382 LazyProperty<JSGlobalObject, Structure> m_callableProxyObjectStructure;
383 LazyProperty<JSGlobalObject, Structure> m_proxyRevokeStructure;
384#if ENABLE(SHARED_ARRAY_BUFFER)
385 WriteBarrier<JSArrayBufferPrototype> m_sharedArrayBufferPrototype;
386 WriteBarrier<Structure> m_sharedArrayBufferStructure;
387#endif
388
389#define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
390 WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; \
391 WriteBarrier<Structure> m_ ## properName ## Structure;
392
393#define DEFINE_STORAGE_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
394 LazyClassStructure m_ ## properName ## Structure;
395
396 FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE)
397 FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(DEFINE_STORAGE_FOR_SIMPLE_TYPE)
398 FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE)
399
400#if ENABLE(WEBASSEMBLY)
401 LazyProperty<JSGlobalObject, Structure> m_webAssemblyModuleRecordStructure;
402 LazyProperty<JSGlobalObject, Structure> m_webAssemblyFunctionStructure;
403 LazyProperty<JSGlobalObject, Structure> m_jsToWasmICCalleeStructure;
404 LazyProperty<JSGlobalObject, Structure> m_webAssemblyWrapperFunctionStructure;
405 LazyProperty<JSGlobalObject, Structure> m_webAssemblyToJSCalleeStructure;
406 FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DEFINE_STORAGE_FOR_LAZY_TYPE)
407#endif // ENABLE(WEBASSEMBLY)
408
409 FOR_EACH_LAZY_BUILTIN_TYPE(DEFINE_STORAGE_FOR_LAZY_TYPE)
410
411#undef DEFINE_STORAGE_FOR_SIMPLE_TYPE
412#undef DEFINE_STORAGE_FOR_LAZY_TYPE
413
414 WriteBarrier<GetterSetter> m_speciesGetterSetter;
415
416 LazyProperty<JSGlobalObject, JSTypedArrayViewPrototype> m_typedArrayProto;
417 LazyProperty<JSGlobalObject, JSTypedArrayViewConstructor> m_typedArraySuperConstructor;
418
419#define DECLARE_TYPED_ARRAY_TYPE_STRUCTURE(name) LazyClassStructure m_typedArray ## name;
420 FOR_EACH_TYPED_ARRAY_TYPE(DECLARE_TYPED_ARRAY_TYPE_STRUCTURE)
421#undef DECLARE_TYPED_ARRAY_TYPE_STRUCTURE
422
423 JSCell* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT.
424 JSCell* m_linkTimeConstants[LinkTimeConstantCount];
425
426 String m_name;
427
428 Debugger* m_debugger;
429
430 VM& m_vm;
431
432#if ENABLE(REMOTE_INSPECTOR)
433 std::unique_ptr<Inspector::JSGlobalObjectInspectorController> m_inspectorController;
434 std::unique_ptr<JSGlobalObjectDebuggable> m_inspectorDebuggable;
435#endif
436
437#if ENABLE(INTL)
438 HashSet<String> m_intlCollatorAvailableLocales;
439 HashSet<String> m_intlDateTimeFormatAvailableLocales;
440 HashSet<String> m_intlNumberFormatAvailableLocales;
441 HashSet<String> m_intlPluralRulesAvailableLocales;
442#endif // ENABLE(INTL)
443
444 RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint;
445 RefPtr<WatchpointSet> m_havingABadTimeWatchpoint;
446 RefPtr<WatchpointSet> m_varInjectionWatchpoint;
447
448 std::unique_ptr<JSGlobalObjectRareData> m_rareData;
449
450 WeakRandom m_weakRandom;
451 RegExpGlobalData m_regExpGlobalData;
452
453 JSCallee* stackOverflowFrameCallee() const { return m_stackOverflowFrameCallee.get(); }
454
455 InlineWatchpointSet& arrayIteratorProtocolWatchpoint() { return m_arrayIteratorProtocolWatchpoint; }
456 InlineWatchpointSet& mapIteratorProtocolWatchpoint() { return m_mapIteratorProtocolWatchpoint; }
457 InlineWatchpointSet& setIteratorProtocolWatchpoint() { return m_setIteratorProtocolWatchpoint; }
458 InlineWatchpointSet& stringIteratorProtocolWatchpoint() { return m_stringIteratorProtocolWatchpoint; }
459 InlineWatchpointSet& mapSetWatchpoint() { return m_mapSetWatchpoint; }
460 InlineWatchpointSet& setAddWatchpoint() { return m_setAddWatchpoint; }
461 InlineWatchpointSet& arraySpeciesWatchpoint() { return m_arraySpeciesWatchpoint; }
462 InlineWatchpointSet& numberToStringWatchpoint()
463 {
464 RELEASE_ASSERT(VM::canUseJIT());
465 return m_numberToStringWatchpoint;
466 }
467 // If this hasn't been invalidated, it means the array iterator protocol
468 // is not observable to user code yet.
469 InlineWatchpointSet m_arrayIteratorProtocolWatchpoint;
470 InlineWatchpointSet m_mapIteratorProtocolWatchpoint;
471 InlineWatchpointSet m_setIteratorProtocolWatchpoint;
472 InlineWatchpointSet m_stringIteratorProtocolWatchpoint;
473 InlineWatchpointSet m_mapSetWatchpoint;
474 InlineWatchpointSet m_setAddWatchpoint;
475 InlineWatchpointSet m_arraySpeciesWatchpoint;
476 InlineWatchpointSet m_numberToStringWatchpoint;
477 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayConstructorSpeciesWatchpoint;
478 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayPrototypeConstructorWatchpoint;
479 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayPrototypeSymbolIteratorWatchpoint;
480 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayIteratorPrototypeNext;
481 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapPrototypeSymbolIteratorWatchpoint;
482 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapIteratorPrototypeNextWatchpoint;
483 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeSymbolIteratorWatchpoint;
484 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setIteratorPrototypeNextWatchpoint;
485 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringPrototypeSymbolIteratorWatchpoint;
486 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringIteratorPrototypeNextWatchpoint;
487 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapPrototypeSetWatchpoint;
488 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeAddWatchpoint;
489 std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_numberPrototypeToStringWatchpoint;
490
491 bool isArrayPrototypeIteratorProtocolFastAndNonObservable();
492 bool isMapPrototypeIteratorProtocolFastAndNonObservable();
493 bool isSetPrototypeIteratorProtocolFastAndNonObservable();
494 bool isStringPrototypeIteratorProtocolFastAndNonObservable();
495 bool isMapPrototypeSetFastAndNonObservable();
496 bool isSetPrototypeAddFastAndNonObservable();
497
498#if ENABLE(DFG_JIT)
499 using ReferencedGlobalPropertyWatchpointSets = HashMap<RefPtr<UniquedStringImpl>, Ref<WatchpointSet>, IdentifierRepHash>;
500 ReferencedGlobalPropertyWatchpointSets m_referencedGlobalPropertyWatchpointSets;
501 ConcurrentJSLock m_referencedGlobalPropertyWatchpointSetsLock;
502#endif
503
504 bool m_evalEnabled { true };
505 bool m_webAssemblyEnabled { true };
506 unsigned m_globalLexicalBindingEpoch { 1 };
507 String m_evalDisabledErrorMessage;
508 String m_webAssemblyDisabledErrorMessage;
509 RuntimeFlags m_runtimeFlags;
510 ConsoleClient* m_consoleClient { nullptr };
511 Optional<unsigned> m_stackTraceLimit;
512
513#if !ASSERT_DISABLED
514 const ExecState* m_callFrameAtDebuggerEntry { nullptr };
515#endif
516
517 static JS_EXPORT_PRIVATE const GlobalObjectMethodTable s_globalObjectMethodTable;
518 const GlobalObjectMethodTable* m_globalObjectMethodTable;
519
520 void createRareDataIfNeeded()
521 {
522 if (m_rareData)
523 return;
524 m_rareData = std::make_unique<JSGlobalObjectRareData>();
525 }
526
527public:
528 typedef JSSegmentedVariableObject Base;
529 static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | IsImmutablePrototypeExoticObject;
530
531 JS_EXPORT_PRIVATE static JSGlobalObject* create(VM&, Structure*);
532
533 DECLARE_EXPORT_INFO;
534
535 bool hasDebugger() const;
536 bool hasInteractiveDebugger() const;
537 const RuntimeFlags& runtimeFlags() const { return m_runtimeFlags; }
538
539#if ENABLE(DFG_JIT)
540 WatchpointSet* getReferencedPropertyWatchpointSet(UniquedStringImpl*);
541 WatchpointSet& ensureReferencedPropertyWatchpointSet(UniquedStringImpl*);
542#endif
543
544 Optional<unsigned> stackTraceLimit() const { return m_stackTraceLimit; }
545 void setStackTraceLimit(Optional<unsigned> value) { m_stackTraceLimit = value; }
546
547protected:
548 JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = nullptr);
549
550 JS_EXPORT_PRIVATE void finishCreation(VM&);
551
552 JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject*);
553
554 void addGlobalVar(const Identifier&);
555
556public:
557 JS_EXPORT_PRIVATE ~JSGlobalObject();
558 JS_EXPORT_PRIVATE static void destroy(JSCell*);
559
560 JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
561
562 JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
563 JS_EXPORT_PRIVATE static bool put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
564
565 JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes);
566 JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes);
567 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
568
569 void addVar(ExecState* exec, const Identifier& propertyName)
570 {
571 if (!hasOwnProperty(exec, propertyName))
572 addGlobalVar(propertyName);
573 }
574 void addFunction(ExecState*, const Identifier&);
575
576 JSScope* globalScope() { return m_globalLexicalEnvironment.get(); }
577 JSGlobalLexicalEnvironment* globalLexicalEnvironment() { return m_globalLexicalEnvironment.get(); }
578
579 JSScope* globalScopeExtension() { return m_globalScopeExtension.get(); }
580 void setGlobalScopeExtension(JSScope*);
581 void clearGlobalScopeExtension();
582
583 // The following accessors return pristine values, even if a script
584 // replaces the global object's associated property.
585
586 GetterSetter* speciesGetterSetter() const { return m_speciesGetterSetter.get(); }
587
588 ArrayConstructor* arrayConstructor() const { return m_arrayConstructor.get(); }
589 ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); }
590 JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); }
591 JSInternalPromiseConstructor* internalPromiseConstructor() const { return m_internalPromiseConstructor.get(); }
592
593#if ENABLE(INTL)
594 IntlCollator* defaultCollator(ExecState*);
595#endif
596
597 NullGetterFunction* nullGetterFunction() const { return m_nullGetterFunction.get(); }
598 NullSetterFunction* nullSetterFunction() const { return m_nullSetterFunction.get(); }
599
600 JSFunction* parseIntFunction() const { return m_parseIntFunction.get(this); }
601 JSFunction* parseFloatFunction() const { return m_parseFloatFunction.get(this); }
602
603 JSFunction* evalFunction() const { return m_evalFunction.get(this); }
604 JSFunction* callFunction() const { return m_callFunction.get(); }
605 JSFunction* applyFunction() const { return m_applyFunction.get(); }
606 JSFunction* throwTypeErrorFunction() const { return m_throwTypeErrorFunction.get(); }
607 JSFunction* arrayProtoToStringFunction() const { return m_arrayProtoToStringFunction.get(this); }
608 JSFunction* arrayProtoValuesFunction() const { return m_arrayProtoValuesFunction.get(this); }
609 JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(this); }
610 JSFunction* iteratorProtocolFunction() const { return m_iteratorProtocolFunction.get(this); }
611 JSFunction* promiseResolveFunction() const { return m_promiseResolveFunction.get(this); }
612 JSFunction* objectProtoValueOfFunction() const { return m_objectProtoValueOfFunction.get(); }
613 JSFunction* numberProtoToStringFunction() const { return m_numberProtoToStringFunction.get(); }
614 JSFunction* newPromiseCapabilityFunction() const { return m_newPromiseCapabilityFunction.get(); }
615 JSFunction* functionProtoHasInstanceSymbolFunction() const { return m_functionProtoHasInstanceSymbolFunction.get(); }
616 JSObject* regExpProtoExecFunction() const { return m_regExpProtoExec.get(); }
617 JSObject* regExpProtoSymbolReplaceFunction() const { return m_regExpProtoSymbolReplace.get(); }
618 JSObject* regExpProtoGlobalGetter() const { return m_regExpProtoGlobalGetter.get(); }
619 JSObject* regExpProtoUnicodeGetter() const { return m_regExpProtoUnicodeGetter.get(); }
620 GetterSetter* throwTypeErrorArgumentsCalleeAndCallerGetterSetter()
621 {
622 return m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.get();
623 }
624
625 JSModuleLoader* moduleLoader() const { return m_moduleLoader.get(this); }
626
627 ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
628 FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
629 ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
630 JSObject* booleanPrototype() const { return m_booleanObjectStructure.prototypeInitializedOnMainThread(this); }
631 StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
632 JSObject* numberPrototype() const { return m_numberObjectStructure.prototypeInitializedOnMainThread(this); }
633 BigIntPrototype* bigIntPrototype() const { return m_bigIntPrototype.get(); }
634 JSObject* datePrototype() const { return m_dateStructure.prototype(this); }
635 JSObject* symbolPrototype() const { return m_symbolObjectStructure.prototypeInitializedOnMainThread(this); }
636 RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); }
637 JSObject* errorPrototype() const { return m_errorStructure.prototype(this); }
638 IteratorPrototype* iteratorPrototype() const { return m_iteratorPrototype.get(); }
639 AsyncIteratorPrototype* asyncIteratorPrototype() const { return m_asyncIteratorPrototype.get(); }
640 GeneratorFunctionPrototype* generatorFunctionPrototype() const { return m_generatorFunctionPrototype.get(); }
641 GeneratorPrototype* generatorPrototype() const { return m_generatorPrototype.get(); }
642 AsyncFunctionPrototype* asyncFunctionPrototype() const { return m_asyncFunctionPrototype.get(); }
643 MapPrototype* mapPrototype() const { return m_mapPrototype.get(); }
644 // Workaround for the name conflict between JSCell::setPrototype.
645 SetPrototype* jsSetPrototype() const { return m_setPrototype.get(); }
646 JSPromisePrototype* promisePrototype() const { return m_promisePrototype.get(); }
647 AsyncGeneratorPrototype* asyncGeneratorPrototype() const { return m_asyncGeneratorPrototype.get(); }
648 AsyncGeneratorFunctionPrototype* asyncGeneratorFunctionPrototype() const { return m_asyncGeneratorFunctionPrototype.get(); }
649
650 Structure* debuggerScopeStructure() const { return m_debuggerScopeStructure.get(this); }
651 Structure* withScopeStructure() const { return m_withScopeStructure.get(this); }
652 Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(this); }
653 Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); }
654 Structure* moduleEnvironmentStructure() const { return m_moduleEnvironmentStructure.get(this); }
655 Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); }
656 Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); }
657 Structure* clonedArgumentsStructure() const { return m_clonedArgumentsStructure.get(); }
658 Structure* objectStructureForObjectConstructor() const { return m_objectStructureForObjectConstructor.get(); }
659 Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const
660 {
661 ASSERT(indexingType & IsArray);
662 return m_originalArrayStructureForIndexingShape[arrayIndexFromIndexingType(indexingType)].get();
663 }
664 Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const
665 {
666 ASSERT(indexingType & IsArray);
667 return m_arrayStructureForIndexingShapeDuringAllocation[arrayIndexFromIndexingType(indexingType)].get();
668 }
669 Structure* arrayStructureForIndexingTypeDuringAllocation(ExecState* exec, IndexingType indexingType, JSValue newTarget) const
670 {
671 return InternalFunction::createSubclassStructure(exec, newTarget, arrayStructureForIndexingTypeDuringAllocation(indexingType));
672 }
673 Structure* arrayStructureForProfileDuringAllocation(ExecState* exec, ArrayAllocationProfile* profile, JSValue newTarget) const
674 {
675 return arrayStructureForIndexingTypeDuringAllocation(exec, ArrayAllocationProfile::selectIndexingTypeFor(profile), newTarget);
676 }
677
678 bool isOriginalArrayStructure(Structure* structure)
679 {
680 return originalArrayStructureForIndexingType(structure->indexingMode() | IsArray) == structure;
681 }
682
683 Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(this); }
684 Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(this); }
685 Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(this); }
686 Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(this); }
687#if JSC_OBJC_API_ENABLED
688 Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(this); }
689 Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(this); }
690#endif
691#ifdef JSC_GLIB_API_ENABLED
692 Structure* glibCallbackFunctionStructure() const { return m_glibCallbackFunctionStructure.get(this); }
693 Structure* glibWrapperObjectStructure() const { return m_glibWrapperObjectStructure.get(this); }
694#endif
695 Structure* dateStructure() const { return m_dateStructure.get(this); }
696 Structure* symbolObjectStructure() const { return m_symbolObjectStructure.get(this); }
697 Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
698 Structure* errorStructure() const { return m_errorStructure.get(this); }
699 Structure* errorStructure(ErrorType errorType) const
700 {
701 switch (errorType) {
702 case ErrorType::Error:
703 return errorStructure();
704 case ErrorType::EvalError:
705 return m_evalErrorStructure.get(this);
706 case ErrorType::RangeError:
707 return m_rangeErrorStructure.get(this);
708 case ErrorType::ReferenceError:
709 return m_referenceErrorStructure.get(this);
710 case ErrorType::SyntaxError:
711 return m_syntaxErrorStructure.get(this);
712 case ErrorType::TypeError:
713 return m_typeErrorStructure.get(this);
714 case ErrorType::URIError:
715 return m_URIErrorStructure.get(this);
716 }
717 ASSERT_NOT_REACHED();
718 return nullptr;
719 }
720 Structure* calleeStructure() const { return m_calleeStructure.get(); }
721 Structure* hostFunctionStructure() const { return m_hostFunctionStructure.get(); }
722
723 Structure* arrowFunctionStructure(bool isBuiltin) const
724 {
725 if (isBuiltin)
726 return m_builtinFunctions.arrowFunctionStructure.get();
727 return m_ordinaryFunctions.arrowFunctionStructure.get();
728 }
729 Structure* sloppyFunctionStructure(bool isBuiltin) const
730 {
731 if (isBuiltin)
732 return m_builtinFunctions.sloppyFunctionStructure.get();
733 return m_ordinaryFunctions.sloppyFunctionStructure.get();
734 }
735 Structure* strictFunctionStructure(bool isBuiltin) const
736 {
737 if (isBuiltin)
738 return m_builtinFunctions.strictFunctionStructure.get();
739 return m_ordinaryFunctions.strictFunctionStructure.get();
740 }
741
742 Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(this); }
743 Structure* customGetterSetterFunctionStructure() const { return m_customGetterSetterFunctionStructure.get(this); }
744 Structure* getterSetterStructure() const { return m_getterSetterStructure.get(); }
745 Structure* nativeStdFunctionStructure() const { return m_nativeStdFunctionStructure.get(this); }
746 PropertyOffset functionNameOffset() const { return m_functionNameOffset; }
747 Structure* numberObjectStructure() const { return m_numberObjectStructure.get(this); }
748 Structure* mapStructure() const { return m_mapStructure.get(); }
749 Structure* regExpStructure() const { return m_regExpStructure.get(); }
750 Structure* generatorFunctionStructure() const { return m_generatorFunctionStructure.get(); }
751 Structure* asyncFunctionStructure() const { return m_asyncFunctionStructure.get(); }
752 Structure* asyncGeneratorFunctionStructure() const { return m_asyncGeneratorFunctionStructure.get(); }
753 Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
754 Structure* bigIntObjectStructure() const { return m_bigIntObjectStructure.get(); }
755 Structure* iteratorResultObjectStructure() const { return m_iteratorResultObjectStructure.get(this); }
756 Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
757 Structure* regExpMatchesArrayWithGroupsStructure() const { return m_regExpMatchesArrayWithGroupsStructure.get(); }
758 Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(this); }
759 Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(this); }
760 Structure* proxyObjectStructure() const { return m_proxyObjectStructure.get(this); }
761 Structure* callableProxyObjectStructure() const { return m_callableProxyObjectStructure.get(this); }
762 Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(this); }
763 Structure* restParameterStructure() const { return arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous); }
764 Structure* originalRestParameterStructure() const { return originalArrayStructureForIndexingType(ArrayWithContiguous); }
765#if ENABLE(WEBASSEMBLY)
766 Structure* webAssemblyModuleRecordStructure() const { return m_webAssemblyModuleRecordStructure.get(this); }
767 Structure* webAssemblyFunctionStructure() const { return m_webAssemblyFunctionStructure.get(this); }
768 Structure* jsToWasmICCalleeStructure() const { return m_jsToWasmICCalleeStructure.get(this); }
769 Structure* webAssemblyWrapperFunctionStructure() const { return m_webAssemblyWrapperFunctionStructure.get(this); }
770 Structure* webAssemblyToJSCalleeStructure() const { return m_webAssemblyToJSCalleeStructure.get(this); }
771#endif // ENABLE(WEBASSEMBLY)
772#if ENABLE(INTL)
773 Structure* collatorStructure() { return m_collatorStructure.get(this); }
774 Structure* numberFormatStructure() { return m_numberFormatStructure.get(this); }
775 Structure* dateTimeFormatStructure() { return m_dateTimeFormatStructure.get(this); }
776 Structure* pluralRulesStructure() { return m_pluralRulesStructure.get(this); }
777#endif // ENABLE(INTL)
778
779 JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
780 JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const;
781
782 RegExpGlobalData& regExpGlobalData() { return m_regExpGlobalData; }
783 static ptrdiff_t regExpGlobalDataOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_regExpGlobalData); }
784
785#if ENABLE(REMOTE_INSPECTOR)
786 Inspector::JSGlobalObjectInspectorController& inspectorController() const { return *m_inspectorController.get(); }
787 JSGlobalObjectDebuggable& inspectorDebuggable() { return *m_inspectorDebuggable.get(); }
788#endif
789
790#if ENABLE(INTL)
791 const HashSet<String>& intlCollatorAvailableLocales();
792 const HashSet<String>& intlDateTimeFormatAvailableLocales();
793 const HashSet<String>& intlNumberFormatAvailableLocales();
794 const HashSet<String>& intlPluralRulesAvailableLocales();
795#endif // ENABLE(INTL)
796
797 void bumpGlobalLexicalBindingEpoch(VM&);
798 unsigned globalLexicalBindingEpoch() const { return m_globalLexicalBindingEpoch; }
799 static ptrdiff_t globalLexicalBindingEpochOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_globalLexicalBindingEpoch); }
800 unsigned* addressOfGlobalLexicalBindingEpoch() { return &m_globalLexicalBindingEpoch; }
801
802 void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; }
803 ConsoleClient* consoleClient() const { return m_consoleClient; }
804
805 void setName(const String&);
806 const String& name() const { return m_name; }
807
808 JSObject* arrayBufferConstructor() const { return m_arrayBufferStructure.constructor(this); }
809
810 JSObject* arrayBufferPrototype(ArrayBufferSharingMode sharingMode) const
811 {
812 switch (sharingMode) {
813 case ArrayBufferSharingMode::Default:
814 return m_arrayBufferStructure.prototype(this);
815#if ENABLE(SHARED_ARRAY_BUFFER)
816 case ArrayBufferSharingMode::Shared:
817 return m_sharedArrayBufferPrototype.get();
818#else
819 default:
820 return m_arrayBufferStructure.prototype(this);
821#endif
822 }
823 }
824 Structure* arrayBufferStructure(ArrayBufferSharingMode sharingMode) const
825 {
826 switch (sharingMode) {
827 case ArrayBufferSharingMode::Default:
828 return m_arrayBufferStructure.get(this);
829#if ENABLE(SHARED_ARRAY_BUFFER)
830 case ArrayBufferSharingMode::Shared:
831 return m_sharedArrayBufferStructure.get();
832#else
833 default:
834 return m_arrayBufferStructure.get(this);
835#endif
836 }
837 RELEASE_ASSERT_NOT_REACHED();
838 return nullptr;
839 }
840
841#define DEFINE_ACCESSORS_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
842 Structure* properName ## Structure() { return m_ ## properName ## Structure.get(); }
843
844 FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE)
845 FOR_BIG_INT_BUILTIN_TYPE_WITH_CONSTRUCTOR(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE)
846 FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE)
847
848#undef DEFINE_ACCESSORS_FOR_SIMPLE_TYPE
849
850#define DEFINE_ACCESSORS_FOR_LAZY_TYPE(capitalName, lowerName, properName, instanceType, jsName, prototypeBase) \
851 Structure* properName ## Structure() { return m_ ## properName ## Structure.get(this); } \
852 JSObject* properName ## Constructor() { return m_ ## properName ## Structure.constructor(this); }
853
854 FOR_EACH_LAZY_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_LAZY_TYPE)
855 FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DEFINE_ACCESSORS_FOR_LAZY_TYPE)
856
857#undef DEFINE_ACCESSORS_FOR_LAZY_TYPE
858
859 LazyClassStructure& lazyTypedArrayStructure(TypedArrayType type)
860 {
861 switch (type) {
862 case NotTypedArray:
863 RELEASE_ASSERT_NOT_REACHED();
864 return m_typedArrayInt8;
865#define TYPED_ARRAY_TYPE_CASE(name) case Type ## name: return m_typedArray ## name;
866 FOR_EACH_TYPED_ARRAY_TYPE(TYPED_ARRAY_TYPE_CASE)
867#undef TYPED_ARRAY_TYPE_CASE
868 }
869 RELEASE_ASSERT_NOT_REACHED();
870 return m_typedArrayInt8;
871 }
872 const LazyClassStructure& lazyTypedArrayStructure(TypedArrayType type) const
873 {
874 return const_cast<const LazyClassStructure&>(const_cast<JSGlobalObject*>(this)->lazyTypedArrayStructure(type));
875 }
876
877 Structure* typedArrayStructure(TypedArrayType type) const
878 {
879 return lazyTypedArrayStructure(type).get(this);
880 }
881 Structure* typedArrayStructureConcurrently(TypedArrayType type) const
882 {
883 return lazyTypedArrayStructure(type).getConcurrently();
884 }
885 bool isOriginalTypedArrayStructure(Structure* structure)
886 {
887 TypedArrayType type = structure->classInfo()->typedArrayStorageType;
888 if (type == NotTypedArray)
889 return false;
890 return typedArrayStructureConcurrently(type) == structure;
891 }
892
893 JSObject* typedArrayConstructor(TypedArrayType type) const
894 {
895 return lazyTypedArrayStructure(type).constructor(this);
896 }
897
898 JSCell* actualPointerFor(Special::Pointer pointer)
899 {
900 ASSERT(pointer < Special::TableSize);
901 return m_specialPointers[pointer];
902 }
903 JSCell* jsCellForLinkTimeConstant(LinkTimeConstant type)
904 {
905 unsigned index = static_cast<unsigned>(type);
906 ASSERT(index < LinkTimeConstantCount);
907 return m_linkTimeConstants[index];
908 }
909
910 WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
911 WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); }
912 WatchpointSet* varInjectionWatchpoint() { return m_varInjectionWatchpoint.get(); }
913
914 bool isHavingABadTime() const
915 {
916 return m_havingABadTimeWatchpoint->hasBeenInvalidated();
917 }
918
919 void haveABadTime(VM&);
920
921 bool objectPrototypeIsSane();
922 bool arrayPrototypeChainIsSane();
923 bool stringPrototypeChainIsSane();
924
925 void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
926 unsigned profileGroup() const
927 {
928 if (!m_rareData)
929 return 0;
930 return m_rareData->profileGroup;
931 }
932
933 Debugger* debugger() const { return m_debugger; }
934 void setDebugger(Debugger*);
935
936 const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; }
937
938 static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; }
939
940 JS_EXPORT_PRIVATE ExecState* globalExec();
941
942 static bool shouldInterruptScript(const JSGlobalObject*) { return true; }
943 static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; }
944 static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags(); }
945
946 JS_EXPORT_PRIVATE void queueMicrotask(Ref<Microtask>&&);
947
948 bool evalEnabled() const { return m_evalEnabled; }
949 bool webAssemblyEnabled() const { return m_webAssemblyEnabled; }
950 const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
951 const String& webAssemblyDisabledErrorMessage() const { return m_webAssemblyDisabledErrorMessage; }
952 void setEvalEnabled(bool enabled, const String& errorMessage = String())
953 {
954 m_evalEnabled = enabled;
955 m_evalDisabledErrorMessage = errorMessage;
956 }
957 void setWebAssemblyEnabled(bool enabled, const String& errorMessage = String())
958 {
959 m_webAssemblyEnabled = enabled;
960 m_webAssemblyDisabledErrorMessage = errorMessage;
961 }
962
963#if !ASSERT_DISABLED
964 const ExecState* callFrameAtDebuggerEntry() const { return m_callFrameAtDebuggerEntry; }
965 void setCallFrameAtDebuggerEntry(const ExecState* callFrame) { m_callFrameAtDebuggerEntry = callFrame; }
966#endif
967
968 void resetPrototype(VM&, JSValue prototype);
969
970 VM& vm() const { return m_vm; }
971 JSObject* globalThis() const;
972 WriteBarrier<JSObject>* addressOfGlobalThis() { return &m_globalThis; }
973
974 static Structure* createStructure(VM& vm, JSValue prototype)
975 {
976 Structure* result = Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info());
977 result->setTransitionWatchpointIsLikelyToBeFired(true);
978 return result;
979 }
980
981 void registerWeakMap(OpaqueJSWeakObjectMap* map)
982 {
983 createRareDataIfNeeded();
984 m_rareData->weakMaps.add(map);
985 }
986
987 void unregisterWeakMap(OpaqueJSWeakObjectMap* map)
988 {
989 if (m_rareData)
990 m_rareData->weakMaps.remove(map);
991 }
992
993 OpaqueJSClassDataMap& opaqueJSClassData()
994 {
995 createRareDataIfNeeded();
996 return m_rareData->opaqueJSClassData;
997 }
998
999 static ptrdiff_t weakRandomOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_weakRandom); }
1000 double weakRandomNumber() { return m_weakRandom.get(); }
1001 unsigned weakRandomInteger() { return m_weakRandom.getUint32(); }
1002 WeakRandom& weakRandom() { return m_weakRandom; }
1003
1004 bool needsSiteSpecificQuirks() const { return m_needsSiteSpecificQuirks; }
1005 JS_EXPORT_PRIVATE void exposeDollarVM(VM&);
1006
1007#if JSC_OBJC_API_ENABLED
1008 JSWrapperMap* wrapperMap() const { return m_wrapperMap.get(); }
1009 void setWrapperMap(JSWrapperMap* map) { m_wrapperMap = map; }
1010 void setAPIWrapper(void* apiWrapper) { m_apiWrapper = apiWrapper; }
1011 void* apiWrapper() const { return m_apiWrapper; }
1012#endif
1013#ifdef JSC_GLIB_API_ENABLED
1014 WrapperMap* wrapperMap() const { return m_wrapperMap.get(); }
1015 void setWrapperMap(std::unique_ptr<WrapperMap>&&);
1016#endif
1017
1018 void tryInstallArraySpeciesWatchpoint(ExecState*);
1019
1020protected:
1021 struct GlobalPropertyInfo {
1022 GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
1023 : identifier(i)
1024 , value(v)
1025 , attributes(a)
1026 {
1027 }
1028
1029 const Identifier identifier;
1030 JSValue value;
1031 unsigned attributes;
1032 };
1033 JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count);
1034
1035 void setNeedsSiteSpecificQuirks(bool needQuirks) { m_needsSiteSpecificQuirks = needQuirks; }
1036
1037private:
1038 friend class LLIntOffsetsExtractor;
1039
1040 void fireWatchpointAndMakeAllArrayStructuresSlowPut(VM&);
1041 void setGlobalThis(VM&, JSObject* globalThis);
1042
1043 template<ErrorType errorType>
1044 void initializeErrorConstructor(LazyClassStructure::Initializer&);
1045
1046 JS_EXPORT_PRIVATE void init(VM&);
1047 void fixupPrototypeChainWithObjectPrototype(VM&);
1048
1049 JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
1050
1051 bool m_needsSiteSpecificQuirks { false };
1052#if JSC_OBJC_API_ENABLED
1053 RetainPtr<JSWrapperMap> m_wrapperMap;
1054 void* m_apiWrapper { nullptr };
1055#endif
1056#ifdef JSC_GLIB_API_ENABLED
1057 std::unique_ptr<WrapperMap> m_wrapperMap;
1058#endif
1059};
1060
1061inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0, JSValue newTarget = JSValue())
1062{
1063 VM& vm = globalObject->vm();
1064 auto scope = DECLARE_THROW_SCOPE(vm);
1065 Structure* structure;
1066 if (initialLength >= MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)
1067 structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(exec, ArrayWithArrayStorage, newTarget);
1068 else
1069 structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
1070 RETURN_IF_EXCEPTION(scope, nullptr);
1071
1072 JSArray* result = JSArray::tryCreate(vm, structure, initialLength);
1073 if (UNLIKELY(!result)) {
1074 throwOutOfMemoryError(exec, scope);
1075 return nullptr;
1076 }
1077 return ArrayAllocationProfile::updateLastAllocationFor(profile, result);
1078}
1079
1080inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0, JSValue newTarget = JSValue())
1081{
1082 return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength, newTarget);
1083}
1084
1085inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values, JSValue newTarget = JSValue())
1086{
1087 VM& vm = globalObject->vm();
1088 auto scope = DECLARE_THROW_SCOPE(vm);
1089 Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
1090 RETURN_IF_EXCEPTION(scope, nullptr);
1091 return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, structure, values));
1092}
1093
1094inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values, JSValue newTarget = JSValue())
1095{
1096 return constructArray(exec, profile, exec->lexicalGlobalObject(), values, newTarget);
1097}
1098
1099inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
1100{
1101 VM& vm = globalObject->vm();
1102 auto scope = DECLARE_THROW_SCOPE(vm);
1103 Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
1104 RETURN_IF_EXCEPTION(scope, nullptr);
1105 return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, structure, values, length));
1106}
1107
1108inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
1109{
1110 return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length, newTarget);
1111}
1112
1113inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
1114{
1115 VM& vm = globalObject->vm();
1116 auto scope = DECLARE_THROW_SCOPE(vm);
1117 Structure* structure = globalObject->arrayStructureForProfileDuringAllocation(exec, profile, newTarget);
1118 RETURN_IF_EXCEPTION(scope, nullptr);
1119 return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArrayNegativeIndexed(exec, structure, values, length));
1120}
1121
1122inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length, JSValue newTarget = JSValue())
1123{
1124 return constructArrayNegativeIndexed(exec, profile, exec->lexicalGlobalObject(), values, length, newTarget);
1125}
1126
1127inline JSObject* ExecState::globalThisValue() const
1128{
1129 return lexicalGlobalObject()->globalThis();
1130}
1131
1132inline JSObject* JSScope::globalThis()
1133{
1134 return globalObject()->globalThis();
1135}
1136
1137inline JSObject* JSGlobalObject::globalThis() const
1138{
1139 return m_globalThis.get();
1140}
1141
1142} // namespace JSC
1143