]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
1 | /* |
2 | * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | |
ed1e77d3 | 3 | * Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved. |
9dae56ea A |
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 | ||
93a37866 | 25 | #include "ArrayAllocationProfile.h" |
81345200 | 26 | #include "ConstantMode.h" |
f9bf01c6 | 27 | #include "JSArray.h" |
81345200 | 28 | #include "JSArrayBufferPrototype.h" |
93a37866 | 29 | #include "JSClassRef.h" |
81345200 | 30 | #include "JSProxy.h" |
93a37866 | 31 | #include "JSSegmentedVariableObject.h" |
4e4e5a6f | 32 | #include "JSWeakObjectMapRefInternal.h" |
9dae56ea | 33 | #include "NumberPrototype.h" |
ed1e77d3 | 34 | #include "RuntimeFlags.h" |
93a37866 | 35 | #include "SpecialPointer.h" |
9dae56ea | 36 | #include "StringPrototype.h" |
14957cd0 | 37 | #include "StructureChain.h" |
93a37866 | 38 | #include "StructureRareDataInlines.h" |
ed1e77d3 A |
39 | #include "SymbolPrototype.h" |
40 | #include "TemplateRegistry.h" | |
81345200 | 41 | #include "VM.h" |
93a37866 A |
42 | #include "Watchpoint.h" |
43 | #include <JavaScriptCore/JSBase.h> | |
81345200 | 44 | #include <array> |
9dae56ea | 45 | #include <wtf/HashSet.h> |
81345200 | 46 | #include <wtf/PassRefPtr.h> |
4e4e5a6f | 47 | #include <wtf/RandomNumber.h> |
9dae56ea | 48 | |
93a37866 A |
49 | struct OpaqueJSClass; |
50 | struct OpaqueJSClassContextData; | |
51 | ||
81345200 A |
52 | namespace Inspector { |
53 | class JSGlobalObjectInspectorController; | |
54 | } | |
55 | ||
9dae56ea A |
56 | namespace JSC { |
57 | ||
93a37866 A |
58 | class ArrayPrototype; |
59 | class BooleanPrototype; | |
81345200 | 60 | class ConsoleClient; |
93a37866 A |
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 GetterSetter; | |
70 | class GlobalCodeBlock; | |
81345200 A |
71 | class InputCursor; |
72 | class JSGlobalObjectDebuggable; | |
73 | class JSPromiseConstructor; | |
74 | class JSPromisePrototype; | |
93a37866 A |
75 | class JSStack; |
76 | class LLIntOffsetsExtractor; | |
81345200 | 77 | class Microtask; |
93a37866 | 78 | class NativeErrorConstructor; |
81345200 | 79 | class ObjectConstructor; |
93a37866 A |
80 | class ProgramCodeBlock; |
81 | class ProgramExecutable; | |
82 | class RegExpConstructor; | |
83 | class RegExpPrototype; | |
84 | class SourceCode; | |
ed1e77d3 A |
85 | class NullGetterFunction; |
86 | class NullSetterFunction; | |
87 | enum class ThisTDZMode; | |
93a37866 A |
88 | struct ActivationStackNode; |
89 | struct HashTable; | |
90 | ||
81345200 | 91 | #define DEFINE_STANDARD_BUILTIN(macro, upperName, lowerName) macro(upperName, lowerName, lowerName, JS ## upperName, upperName) |
ed1e77d3 A |
92 | |
93 | #define FOR_EACH_EXPERIMENTAL_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ | |
94 | macro(Symbol, symbol, symbolObject, SymbolObject, Symbol) \ | |
95 | ||
81345200 A |
96 | #define FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ |
97 | macro(Set, set, set, JSSet, Set) \ | |
98 | macro(Map, map, map, JSMap, Map) \ | |
99 | macro(Date, date, date, DateInstance, Date) \ | |
100 | macro(String, string, stringObject, StringObject, String) \ | |
101 | macro(Boolean, boolean, booleanObject, BooleanObject, Boolean) \ | |
102 | macro(Number, number, numberObject, NumberObject, Number) \ | |
103 | macro(Error, error, error, ErrorInstance, Error) \ | |
104 | macro(JSArrayBuffer, arrayBuffer, arrayBuffer, JSArrayBuffer, ArrayBuffer) \ | |
105 | DEFINE_STANDARD_BUILTIN(macro, WeakMap, weakMap) \ | |
ed1e77d3 | 106 | DEFINE_STANDARD_BUILTIN(macro, WeakSet, weakSet) \ |
81345200 | 107 | |
ed1e77d3 | 108 | #define FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \ |
81345200 | 109 | DEFINE_STANDARD_BUILTIN(macro, ArrayIterator, arrayIterator) \ |
81345200 A |
110 | DEFINE_STANDARD_BUILTIN(macro, MapIterator, mapIterator) \ |
111 | DEFINE_STANDARD_BUILTIN(macro, SetIterator, setIterator) \ | |
ed1e77d3 | 112 | DEFINE_STANDARD_BUILTIN(macro, StringIterator, stringIterator) \ |
81345200 | 113 | |
ed1e77d3 A |
114 | #define FOR_EACH_BUILTIN_ITERATOR_TYPE(macro) \ |
115 | DEFINE_STANDARD_BUILTIN(macro, Iterator, iterator) \ | |
116 | FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(macro) \ | |
117 | ||
118 | #define FOR_EACH_SIMPLE_BUILTIN_TYPE(macro) \ | |
119 | FOR_EACH_SIMPLE_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ | |
120 | FOR_EACH_EXPERIMENTAL_BUILTIN_TYPE_WITH_CONSTRUCTOR(macro) \ | |
81345200 A |
121 | |
122 | #define DECLARE_SIMPLE_BUILTIN_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ | |
123 | class JS ## capitalName; \ | |
124 | class capitalName ## Prototype; \ | |
125 | class capitalName ## Constructor; | |
126 | ||
ed1e77d3 | 127 | class IteratorPrototype; |
81345200 | 128 | FOR_EACH_SIMPLE_BUILTIN_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE) |
ed1e77d3 | 129 | FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DECLARE_SIMPLE_BUILTIN_TYPE) |
81345200 A |
130 | |
131 | #undef DECLARE_SIMPLE_BUILTIN_TYPE | |
132 | ||
133 | typedef Vector<ExecState*, 16> ExecStateStack; | |
134 | ||
93a37866 A |
135 | struct GlobalObjectMethodTable { |
136 | typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*); | |
137 | AllowsAccessFromFunctionPtr allowsAccessFrom; | |
138 | ||
139 | typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*); | |
140 | SupportsProfilingFunctionPtr supportsProfiling; | |
141 | ||
142 | typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*); | |
143 | SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo; | |
144 | ||
145 | typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*); | |
146 | ShouldInterruptScriptFunctionPtr shouldInterruptScript; | |
147 | ||
ed1e77d3 A |
148 | typedef RuntimeFlags (*JavaScriptRuntimeFlagsFunctionPtr)(const JSGlobalObject*); |
149 | JavaScriptRuntimeFlagsFunctionPtr javaScriptRuntimeFlags; | |
93a37866 | 150 | |
81345200 A |
151 | typedef void (*QueueTaskToEventLoopFunctionPtr)(const JSGlobalObject*, PassRefPtr<Microtask>); |
152 | QueueTaskToEventLoopFunctionPtr queueTaskToEventLoop; | |
153 | ||
93a37866 A |
154 | typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*); |
155 | ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout; | |
93a37866 A |
156 | }; |
157 | ||
158 | class JSGlobalObject : public JSSegmentedVariableObject { | |
159 | private: | |
81345200 A |
160 | typedef HashSet<RefPtr<OpaqueJSWeakObjectMap>> WeakMapSet; |
161 | typedef HashMap<OpaqueJSClass*, std::unique_ptr<OpaqueJSClassContextData>> OpaqueJSClassDataMap; | |
93a37866 A |
162 | |
163 | struct JSGlobalObjectRareData { | |
164 | JSGlobalObjectRareData() | |
165 | : profileGroup(0) | |
6fe7ccc8 | 166 | { |
6fe7ccc8 A |
167 | } |
168 | ||
93a37866 A |
169 | WeakMapSet weakMaps; |
170 | unsigned profileGroup; | |
171 | ||
172 | OpaqueJSClassDataMap opaqueJSClassData; | |
173 | }; | |
14957cd0 | 174 | |
93a37866 | 175 | protected: |
93a37866 A |
176 | Register m_globalCallFrame[JSStack::CallFrameHeaderSize]; |
177 | ||
178 | WriteBarrier<JSObject> m_globalThis; | |
179 | ||
ed1e77d3 | 180 | WriteBarrier<JSObject> m_globalCallee; |
93a37866 A |
181 | WriteBarrier<RegExpConstructor> m_regExpConstructor; |
182 | WriteBarrier<ErrorConstructor> m_errorConstructor; | |
183 | WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor; | |
184 | WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor; | |
185 | WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor; | |
186 | WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor; | |
187 | WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor; | |
188 | WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor; | |
81345200 A |
189 | #if ENABLE(PROMISES) |
190 | WriteBarrier<JSPromiseConstructor> m_promiseConstructor; | |
191 | #endif | |
192 | WriteBarrier<ObjectConstructor> m_objectConstructor; | |
93a37866 | 193 | |
ed1e77d3 A |
194 | WriteBarrier<NullGetterFunction> m_nullGetterFunction; |
195 | WriteBarrier<NullSetterFunction> m_nullSetterFunction; | |
196 | ||
197 | WriteBarrier<JSFunction> m_parseIntFunction; | |
198 | ||
93a37866 A |
199 | WriteBarrier<JSFunction> m_evalFunction; |
200 | WriteBarrier<JSFunction> m_callFunction; | |
201 | WriteBarrier<JSFunction> m_applyFunction; | |
ed1e77d3 A |
202 | WriteBarrier<JSFunction> m_definePropertyFunction; |
203 | WriteBarrier<JSFunction> m_arrayProtoValuesFunction; | |
204 | #if ENABLE(PROMISES) | |
205 | WriteBarrier<JSFunction> m_initializePromiseFunction; | |
206 | WriteBarrier<JSFunction> m_newPromiseDeferredFunction; | |
207 | #endif | |
93a37866 A |
208 | WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter; |
209 | ||
210 | WriteBarrier<ObjectPrototype> m_objectPrototype; | |
211 | WriteBarrier<FunctionPrototype> m_functionPrototype; | |
212 | WriteBarrier<ArrayPrototype> m_arrayPrototype; | |
93a37866 | 213 | WriteBarrier<RegExpPrototype> m_regExpPrototype; |
ed1e77d3 | 214 | WriteBarrier<IteratorPrototype> m_iteratorPrototype; |
81345200 A |
215 | #if ENABLE(PROMISES) |
216 | WriteBarrier<JSPromisePrototype> m_promisePrototype; | |
217 | #endif | |
93a37866 | 218 | |
ed1e77d3 | 219 | WriteBarrier<Structure> m_debuggerScopeStructure; |
93a37866 A |
220 | WriteBarrier<Structure> m_withScopeStructure; |
221 | WriteBarrier<Structure> m_strictEvalActivationStructure; | |
ed1e77d3 A |
222 | WriteBarrier<Structure> m_lexicalEnvironmentStructure; |
223 | WriteBarrier<Structure> m_catchScopeStructure; | |
224 | WriteBarrier<Structure> m_functionNameScopeStructure; | |
225 | WriteBarrier<Structure> m_directArgumentsStructure; | |
226 | WriteBarrier<Structure> m_scopedArgumentsStructure; | |
227 | WriteBarrier<Structure> m_outOfBandArgumentsStructure; | |
93a37866 A |
228 | |
229 | // Lists the actual structures used for having these particular indexing shapes. | |
230 | WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes]; | |
231 | // Lists the structures we should use during allocation for these particular indexing shapes. | |
232 | WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes]; | |
81345200 | 233 | |
93a37866 A |
234 | WriteBarrier<Structure> m_callbackConstructorStructure; |
235 | WriteBarrier<Structure> m_callbackFunctionStructure; | |
236 | WriteBarrier<Structure> m_callbackObjectStructure; | |
237 | #if JSC_OBJC_API_ENABLED | |
238 | WriteBarrier<Structure> m_objcCallbackFunctionStructure; | |
239 | WriteBarrier<Structure> m_objcWrapperObjectStructure; | |
240 | #endif | |
93a37866 | 241 | WriteBarrier<Structure> m_nullPrototypeObjectStructure; |
ed1e77d3 | 242 | WriteBarrier<Structure> m_calleeStructure; |
93a37866 A |
243 | WriteBarrier<Structure> m_functionStructure; |
244 | WriteBarrier<Structure> m_boundFunctionStructure; | |
245 | WriteBarrier<Structure> m_namedFunctionStructure; | |
246 | PropertyOffset m_functionNameOffset; | |
93a37866 | 247 | WriteBarrier<Structure> m_privateNameStructure; |
93a37866 | 248 | WriteBarrier<Structure> m_regExpStructure; |
81345200 | 249 | WriteBarrier<Structure> m_consoleStructure; |
ed1e77d3 | 250 | WriteBarrier<Structure> m_dollarVMStructure; |
93a37866 | 251 | WriteBarrier<Structure> m_internalFunctionStructure; |
81345200 A |
252 | |
253 | WriteBarrier<Structure> m_iteratorResultStructure; | |
254 | ||
ed1e77d3 A |
255 | WriteBarrier<Structure> m_regExpMatchesArrayStructure; |
256 | ||
81345200 A |
257 | #if ENABLE(PROMISES) |
258 | WriteBarrier<Structure> m_promiseStructure; | |
259 | #endif // ENABLE(PROMISES) | |
260 | ||
261 | #define DEFINE_STORAGE_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ | |
262 | WriteBarrier<capitalName ## Prototype> m_ ## lowerName ## Prototype; \ | |
263 | WriteBarrier<Structure> m_ ## properName ## Structure; | |
264 | ||
265 | FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE) | |
ed1e77d3 | 266 | FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE) |
81345200 A |
267 | |
268 | #undef DEFINE_STORAGE_FOR_SIMPLE_TYPE | |
269 | ||
270 | struct TypedArrayData { | |
271 | WriteBarrier<JSObject> prototype; | |
272 | WriteBarrier<Structure> structure; | |
273 | }; | |
274 | ||
275 | std::array<TypedArrayData, NUMBER_OF_TYPED_ARRAY_TYPES> m_typedArrays; | |
ed1e77d3 A |
276 | |
277 | JSCell* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. | |
278 | JSCell* m_linkTimeConstants[LinkTimeConstantCount]; | |
14957cd0 | 279 | |
81345200 A |
280 | String m_name; |
281 | ||
93a37866 | 282 | Debugger* m_debugger; |
14957cd0 | 283 | |
81345200 A |
284 | VM& m_vm; |
285 | ||
286 | #if ENABLE(WEB_REPLAY) | |
287 | RefPtr<InputCursor> m_inputCursor; | |
288 | #endif | |
289 | ||
290 | #if ENABLE(REMOTE_INSPECTOR) | |
291 | std::unique_ptr<Inspector::JSGlobalObjectInspectorController> m_inspectorController; | |
292 | std::unique_ptr<JSGlobalObjectDebuggable> m_inspectorDebuggable; | |
293 | #endif | |
294 | ||
93a37866 A |
295 | RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint; |
296 | RefPtr<WatchpointSet> m_havingABadTimeWatchpoint; | |
81345200 | 297 | RefPtr<WatchpointSet> m_varInjectionWatchpoint; |
14957cd0 | 298 | |
ed1e77d3 | 299 | std::unique_ptr<JSGlobalObjectRareData> m_rareData; |
9dae56ea | 300 | |
93a37866 | 301 | WeakRandom m_weakRandom; |
9dae56ea | 302 | |
ed1e77d3 A |
303 | TemplateRegistry m_templateRegistry; |
304 | ||
93a37866 A |
305 | bool m_evalEnabled; |
306 | String m_evalDisabledErrorMessage; | |
ed1e77d3 | 307 | RuntimeFlags m_runtimeFlags; |
81345200 | 308 | ConsoleClient* m_consoleClient; |
9dae56ea | 309 | |
93a37866 A |
310 | static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable; |
311 | const GlobalObjectMethodTable* m_globalObjectMethodTable; | |
9dae56ea | 312 | |
93a37866 A |
313 | void createRareDataIfNeeded() |
314 | { | |
315 | if (m_rareData) | |
316 | return; | |
ed1e77d3 | 317 | m_rareData = std::make_unique<JSGlobalObjectRareData>(); |
93a37866 A |
318 | } |
319 | ||
320 | public: | |
321 | typedef JSSegmentedVariableObject Base; | |
ed1e77d3 | 322 | static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames; |
9dae56ea | 323 | |
ed1e77d3 | 324 | static JSGlobalObject* create(VM& vm, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable = nullptr) |
93a37866 | 325 | { |
ed1e77d3 | 326 | JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure, globalObjectMethodTable); |
93a37866 A |
327 | globalObject->finishCreation(vm); |
328 | vm.heap.addFinalizer(globalObject, destroy); | |
329 | return globalObject; | |
330 | } | |
9dae56ea | 331 | |
81345200 | 332 | DECLARE_EXPORT_INFO; |
14957cd0 | 333 | |
93a37866 A |
334 | bool hasDebugger() const { return m_debugger; } |
335 | bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); } | |
ed1e77d3 | 336 | const RuntimeFlags& runtimeFlags() const { return m_runtimeFlags; } |
9dae56ea | 337 | |
93a37866 A |
338 | protected: |
339 | JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0); | |
9dae56ea | 340 | |
93a37866 A |
341 | void finishCreation(VM& vm) |
342 | { | |
343 | Base::finishCreation(vm); | |
344 | structure()->setGlobalObject(vm, this); | |
ed1e77d3 A |
345 | m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this); |
346 | init(vm); | |
81345200 | 347 | setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, prototype(), PureForwardingProxyType), this)); |
93a37866 | 348 | } |
9dae56ea | 349 | |
93a37866 A |
350 | void finishCreation(VM& vm, JSObject* thisValue) |
351 | { | |
352 | Base::finishCreation(vm); | |
353 | structure()->setGlobalObject(vm, this); | |
ed1e77d3 A |
354 | m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this); |
355 | init(vm); | |
81345200 | 356 | setGlobalThis(vm, thisValue); |
93a37866 | 357 | } |
4e4e5a6f | 358 | |
ed1e77d3 | 359 | void addGlobalVar(const Identifier&, ConstantMode); |
81345200 | 360 | |
93a37866 A |
361 | public: |
362 | JS_EXPORT_PRIVATE ~JSGlobalObject(); | |
363 | JS_EXPORT_PRIVATE static void destroy(JSCell*); | |
364 | // We don't need a destructor because we use a finalizer instead. | |
365 | static const bool needsDestruction = false; | |
4e4e5a6f | 366 | |
93a37866 | 367 | JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); |
f9bf01c6 | 368 | |
81345200 | 369 | JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); |
93a37866 A |
370 | bool hasOwnPropertyForWrite(ExecState*, PropertyName); |
371 | JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); | |
f9bf01c6 | 372 | |
93a37866 A |
373 | JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes); |
374 | JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes); | |
81345200 | 375 | JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); |
9dae56ea | 376 | |
93a37866 A |
377 | // We use this in the code generator as we perform symbol table |
378 | // lookups prior to initializing the properties | |
379 | bool symbolTableHasProperty(PropertyName); | |
9dae56ea | 380 | |
81345200 A |
381 | void addVar(ExecState* exec, const Identifier& propertyName) |
382 | { | |
383 | if (!hasProperty(exec, propertyName)) | |
384 | addGlobalVar(propertyName, IsVariable); | |
385 | } | |
386 | void addConst(ExecState* exec, const Identifier& propertyName) | |
387 | { | |
388 | if (!hasProperty(exec, propertyName)) | |
389 | addGlobalVar(propertyName, IsConstant); | |
390 | } | |
ed1e77d3 | 391 | void addFunction(ExecState*, const Identifier&); |
81345200 | 392 | |
93a37866 A |
393 | // The following accessors return pristine values, even if a script |
394 | // replaces the global object's associated property. | |
9dae56ea | 395 | |
93a37866 | 396 | RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); } |
9dae56ea | 397 | |
93a37866 | 398 | ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); } |
81345200 | 399 | ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); } |
93a37866 A |
400 | NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); } |
401 | NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); } | |
402 | NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); } | |
403 | NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); } | |
404 | NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); } | |
405 | NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); } | |
81345200 A |
406 | #if ENABLE(PROMISES) |
407 | JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); } | |
408 | #endif | |
9dae56ea | 409 | |
ed1e77d3 A |
410 | NullGetterFunction* nullGetterFunction() const { return m_nullGetterFunction.get(); } |
411 | NullSetterFunction* nullSetterFunction() const { return m_nullSetterFunction.get(); } | |
412 | ||
413 | JSFunction* parseIntFunction() const { return m_parseIntFunction.get(); } | |
414 | ||
93a37866 A |
415 | JSFunction* evalFunction() const { return m_evalFunction.get(); } |
416 | JSFunction* callFunction() const { return m_callFunction.get(); } | |
417 | JSFunction* applyFunction() const { return m_applyFunction.get(); } | |
ed1e77d3 A |
418 | JSFunction* definePropertyFunction() const { return m_definePropertyFunction.get(); } |
419 | JSFunction* arrayProtoValuesFunction() const { return m_arrayProtoValuesFunction.get(); } | |
420 | #if ENABLE(PROMISES) | |
421 | JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(); } | |
422 | JSFunction* newPromiseDeferredFunction() const { return m_newPromiseDeferredFunction.get(); } | |
423 | #endif | |
81345200 | 424 | GetterSetter* throwTypeErrorGetterSetter(VM& vm) |
9dae56ea | 425 | { |
93a37866 | 426 | if (!m_throwTypeErrorGetterSetter) |
81345200 | 427 | createThrowTypeError(vm); |
93a37866 | 428 | return m_throwTypeErrorGetterSetter.get(); |
9dae56ea A |
429 | } |
430 | ||
93a37866 A |
431 | ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); } |
432 | FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); } | |
433 | ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); } | |
434 | BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); } | |
435 | StringPrototype* stringPrototype() const { return m_stringPrototype.get(); } | |
ed1e77d3 | 436 | SymbolPrototype* symbolPrototype() const { return m_symbolPrototype.get(); } |
93a37866 A |
437 | NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); } |
438 | DatePrototype* datePrototype() const { return m_datePrototype.get(); } | |
439 | RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); } | |
440 | ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); } | |
ed1e77d3 | 441 | IteratorPrototype* iteratorPrototype() const { return m_iteratorPrototype.get(); } |
81345200 A |
442 | #if ENABLE(PROMISES) |
443 | JSPromisePrototype* promisePrototype() const { return m_promisePrototype.get(); } | |
444 | #endif | |
93a37866 | 445 | |
ed1e77d3 | 446 | Structure* debuggerScopeStructure() const { return m_debuggerScopeStructure.get(); } |
93a37866 A |
447 | Structure* withScopeStructure() const { return m_withScopeStructure.get(); } |
448 | Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } | |
ed1e77d3 A |
449 | Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); } |
450 | Structure* catchScopeStructure() const { return m_catchScopeStructure.get(); } | |
451 | Structure* functionNameScopeStructure() const { return m_functionNameScopeStructure.get(); } | |
452 | Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); } | |
453 | Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); } | |
454 | Structure* outOfBandArgumentsStructure() const { return m_outOfBandArgumentsStructure.get(); } | |
93a37866 | 455 | Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const |
9dae56ea | 456 | { |
93a37866 A |
457 | ASSERT(indexingType & IsArray); |
458 | return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); | |
f9bf01c6 | 459 | } |
93a37866 | 460 | Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const |
9dae56ea | 461 | { |
93a37866 A |
462 | ASSERT(indexingType & IsArray); |
463 | return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); | |
9dae56ea | 464 | } |
93a37866 | 465 | Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const |
14957cd0 | 466 | { |
93a37866 | 467 | return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile)); |
14957cd0 | 468 | } |
93a37866 A |
469 | |
470 | bool isOriginalArrayStructure(Structure* structure) | |
9dae56ea | 471 | { |
93a37866 | 472 | return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure; |
9dae56ea | 473 | } |
93a37866 A |
474 | |
475 | Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } | |
476 | Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } | |
477 | Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } | |
478 | Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); } | |
479 | #if JSC_OBJC_API_ENABLED | |
480 | Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(); } | |
481 | Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(); } | |
482 | #endif | |
483 | Structure* dateStructure() const { return m_dateStructure.get(); } | |
484 | Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); } | |
485 | Structure* errorStructure() const { return m_errorStructure.get(); } | |
ed1e77d3 | 486 | Structure* calleeStructure() const { return m_calleeStructure.get(); } |
93a37866 A |
487 | Structure* functionStructure() const { return m_functionStructure.get(); } |
488 | Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); } | |
489 | Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); } | |
490 | PropertyOffset functionNameOffset() const { return m_functionNameOffset; } | |
491 | Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); } | |
492 | Structure* privateNameStructure() const { return m_privateNameStructure.get(); } | |
493 | Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); } | |
81345200 | 494 | Structure* mapStructure() const { return m_mapStructure.get(); } |
93a37866 | 495 | Structure* regExpStructure() const { return m_regExpStructure.get(); } |
81345200 | 496 | Structure* setStructure() const { return m_setStructure.get(); } |
93a37866 | 497 | Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } |
ed1e77d3 | 498 | Structure* symbolObjectStructure() const { return m_symbolObjectStructure.get(); } |
81345200 A |
499 | Structure* iteratorResultStructure() const { return m_iteratorResultStructure.get(); } |
500 | static ptrdiff_t iteratorResultStructureOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_iteratorResultStructure); } | |
ed1e77d3 | 501 | Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } |
81345200 A |
502 | |
503 | #if ENABLE(PROMISES) | |
504 | Structure* promiseStructure() const { return m_promiseStructure.get(); } | |
505 | #endif // ENABLE(PROMISES) | |
506 | ||
507 | JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool); | |
508 | JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const; | |
509 | ||
510 | #if ENABLE(WEB_REPLAY) | |
511 | JS_EXPORT_PRIVATE void setInputCursor(PassRefPtr<InputCursor>); | |
512 | InputCursor& inputCursor() const { return *m_inputCursor; } | |
513 | #endif | |
514 | ||
515 | #if ENABLE(REMOTE_INSPECTOR) | |
516 | Inspector::JSGlobalObjectInspectorController& inspectorController() const { return *m_inspectorController.get(); } | |
517 | JSGlobalObjectDebuggable& inspectorDebuggable() { return *m_inspectorDebuggable.get(); } | |
518 | #endif | |
519 | ||
ed1e77d3 | 520 | void setConsoleClient(ConsoleClient* consoleClient) { m_consoleClient = consoleClient; } |
81345200 A |
521 | ConsoleClient* consoleClient() const { return m_consoleClient; } |
522 | ||
523 | void setName(const String&); | |
524 | const String& name() const { return m_name; } | |
525 | ||
526 | JSArrayBufferPrototype* arrayBufferPrototype() const { return m_arrayBufferPrototype.get(); } | |
527 | ||
528 | #define DEFINE_ACCESSORS_FOR_SIMPLE_TYPE(capitalName, lowerName, properName, instanceType, jsName) \ | |
529 | Structure* properName ## Structure() { return m_ ## properName ## Structure.get(); } | |
530 | ||
531 | FOR_EACH_SIMPLE_BUILTIN_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE) | |
ed1e77d3 | 532 | FOR_EACH_BUILTIN_DERIVED_ITERATOR_TYPE(DEFINE_ACCESSORS_FOR_SIMPLE_TYPE) |
81345200 A |
533 | |
534 | #undef DEFINE_ACCESSORS_FOR_SIMPLE_TYPE | |
535 | ||
536 | Structure* typedArrayStructure(TypedArrayType type) const | |
537 | { | |
538 | return m_typedArrays[toIndex(type)].structure.get(); | |
539 | } | |
540 | bool isOriginalTypedArrayStructure(Structure* structure) | |
541 | { | |
542 | TypedArrayType type = structure->classInfo()->typedArrayStorageType; | |
543 | if (type == NotTypedArray) | |
544 | return false; | |
545 | return typedArrayStructure(type) == structure; | |
546 | } | |
93a37866 | 547 | |
ed1e77d3 | 548 | JSCell* actualPointerFor(Special::Pointer pointer) |
9dae56ea | 549 | { |
93a37866 A |
550 | ASSERT(pointer < Special::TableSize); |
551 | return m_specialPointers[pointer]; | |
9dae56ea | 552 | } |
ed1e77d3 A |
553 | JSCell* jsCellForLinkTimeConstant(LinkTimeConstant type) |
554 | { | |
555 | unsigned index = static_cast<unsigned>(type); | |
556 | ASSERT(index < LinkTimeConstantCount); | |
557 | return m_linkTimeConstants[index]; | |
558 | } | |
9dae56ea | 559 | |
93a37866 A |
560 | WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); } |
561 | WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); } | |
81345200 | 562 | WatchpointSet* varInjectionWatchpoint() { return m_varInjectionWatchpoint.get(); } |
93a37866 A |
563 | |
564 | bool isHavingABadTime() const | |
9dae56ea | 565 | { |
93a37866 A |
566 | return m_havingABadTimeWatchpoint->hasBeenInvalidated(); |
567 | } | |
568 | ||
569 | void haveABadTime(VM&); | |
570 | ||
81345200 | 571 | bool objectPrototypeIsSane(); |
93a37866 | 572 | bool arrayPrototypeChainIsSane(); |
81345200 | 573 | bool stringPrototypeChainIsSane(); |
93a37866 A |
574 | |
575 | void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; } | |
576 | unsigned profileGroup() const | |
577 | { | |
578 | if (!m_rareData) | |
579 | return 0; | |
580 | return m_rareData->profileGroup; | |
9dae56ea A |
581 | } |
582 | ||
93a37866 A |
583 | Debugger* debugger() const { return m_debugger; } |
584 | void setDebugger(Debugger* debugger) { m_debugger = debugger; } | |
9dae56ea | 585 | |
93a37866 | 586 | const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; } |
9dae56ea | 587 | |
93a37866 A |
588 | static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; } |
589 | static bool supportsProfiling(const JSGlobalObject*) { return false; } | |
590 | static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } | |
14957cd0 | 591 | |
93a37866 | 592 | JS_EXPORT_PRIVATE ExecState* globalExec(); |
f9bf01c6 | 593 | |
93a37866 | 594 | static bool shouldInterruptScript(const JSGlobalObject*) { return true; } |
81345200 | 595 | static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; } |
ed1e77d3 | 596 | static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags(); } |
f9bf01c6 | 597 | |
81345200 | 598 | void queueMicrotask(PassRefPtr<Microtask>); |
93a37866 A |
599 | |
600 | bool evalEnabled() const { return m_evalEnabled; } | |
601 | const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } | |
602 | void setEvalEnabled(bool enabled, const String& errorMessage = String()) | |
f9bf01c6 | 603 | { |
93a37866 A |
604 | m_evalEnabled = enabled; |
605 | m_evalDisabledErrorMessage = errorMessage; | |
f9bf01c6 A |
606 | } |
607 | ||
93a37866 A |
608 | void resetPrototype(VM&, JSValue prototype); |
609 | ||
81345200 | 610 | VM& vm() const { return m_vm; } |
93a37866 A |
611 | JSObject* globalThis() const; |
612 | ||
613 | static Structure* createStructure(VM& vm, JSValue prototype) | |
f9bf01c6 | 614 | { |
81345200 | 615 | return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); |
14957cd0 A |
616 | } |
617 | ||
93a37866 | 618 | void registerWeakMap(OpaqueJSWeakObjectMap* map) |
14957cd0 | 619 | { |
93a37866 A |
620 | createRareDataIfNeeded(); |
621 | m_rareData->weakMaps.add(map); | |
14957cd0 A |
622 | } |
623 | ||
93a37866 | 624 | void unregisterWeakMap(OpaqueJSWeakObjectMap* map) |
14957cd0 | 625 | { |
93a37866 A |
626 | if (m_rareData) |
627 | m_rareData->weakMaps.remove(map); | |
f9bf01c6 A |
628 | } |
629 | ||
93a37866 | 630 | OpaqueJSClassDataMap& opaqueJSClassData() |
f9bf01c6 | 631 | { |
93a37866 A |
632 | createRareDataIfNeeded(); |
633 | return m_rareData->opaqueJSClassData; | |
f9bf01c6 A |
634 | } |
635 | ||
ed1e77d3 A |
636 | TemplateRegistry& templateRegistry() { return m_templateRegistry; } |
637 | ||
93a37866 A |
638 | double weakRandomNumber() { return m_weakRandom.get(); } |
639 | unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } | |
640 | ||
641 | UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); | |
ed1e77d3 | 642 | UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode); |
93a37866 A |
643 | |
644 | protected: | |
93a37866 A |
645 | struct GlobalPropertyInfo { |
646 | GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) | |
647 | : identifier(i) | |
648 | , value(v) | |
649 | , attributes(a) | |
9dae56ea | 650 | { |
9dae56ea A |
651 | } |
652 | ||
93a37866 A |
653 | const Identifier identifier; |
654 | JSValue value; | |
655 | unsigned attributes; | |
9dae56ea | 656 | }; |
93a37866 | 657 | JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count); |
9dae56ea | 658 | |
81345200 | 659 | JS_EXPORT_PRIVATE static JSC::JSValue toThis(JSC::JSCell*, JSC::ExecState*, ECMAMode); |
93a37866 A |
660 | |
661 | private: | |
662 | friend class LLIntOffsetsExtractor; | |
81345200 A |
663 | |
664 | JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis); | |
665 | ||
ed1e77d3 | 666 | JS_EXPORT_PRIVATE void init(VM&); |
93a37866 | 667 | |
81345200 | 668 | void createThrowTypeError(VM&); |
93a37866 A |
669 | |
670 | JS_EXPORT_PRIVATE static void clearRareData(JSCell*); | |
671 | }; | |
672 | ||
673 | JSGlobalObject* asGlobalObject(JSValue); | |
674 | ||
675 | inline JSGlobalObject* asGlobalObject(JSValue value) | |
676 | { | |
677 | ASSERT(asObject(value)->isGlobalObject()); | |
678 | return jsCast<JSGlobalObject*>(asObject(value)); | |
679 | } | |
680 | ||
681 | inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) | |
682 | { | |
81345200 | 683 | PropertySlot slot(this); |
93a37866 | 684 | if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) |
6fe7ccc8 | 685 | return true; |
93a37866 A |
686 | bool slotIsWriteable; |
687 | return symbolTableGet(this, propertyName, slot, slotIsWriteable); | |
688 | } | |
689 | ||
690 | inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName) | |
691 | { | |
81345200 | 692 | SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid()); |
93a37866 A |
693 | return !entry.isNull(); |
694 | } | |
695 | ||
93a37866 A |
696 | inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0) |
697 | { | |
ed1e77d3 | 698 | return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength)); |
93a37866 A |
699 | } |
700 | ||
701 | inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0) | |
702 | { | |
703 | return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength); | |
704 | } | |
705 | ||
706 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values) | |
707 | { | |
708 | return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values)); | |
709 | } | |
710 | ||
711 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values) | |
712 | { | |
713 | return constructArray(exec, profile, exec->lexicalGlobalObject(), values); | |
714 | } | |
715 | ||
716 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) | |
717 | { | |
718 | return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); | |
719 | } | |
720 | ||
721 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) | |
722 | { | |
723 | return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length); | |
724 | } | |
725 | ||
81345200 A |
726 | inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) |
727 | { | |
728 | return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArrayNegativeIndexed(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); | |
729 | } | |
93a37866 | 730 | |
81345200 | 731 | inline JSArray* constructArrayNegativeIndexed(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) |
93a37866 | 732 | { |
81345200 | 733 | return constructArrayNegativeIndexed(exec, profile, exec->lexicalGlobalObject(), values, length); |
93a37866 A |
734 | } |
735 | ||
ed1e77d3 A |
736 | inline JSObject* ExecState::globalThisValue() const |
737 | { | |
738 | return lexicalGlobalObject()->globalThis(); | |
739 | } | |
740 | ||
93a37866 A |
741 | inline JSObject* JSScope::globalThis() |
742 | { | |
743 | return globalObject()->globalThis(); | |
744 | } | |
745 | ||
746 | inline JSObject* JSGlobalObject::globalThis() const | |
747 | { | |
748 | return m_globalThis.get(); | |
749 | } | |
750 | ||
9dae56ea A |
751 | } // namespace JSC |
752 | ||
753 | #endif // JSGlobalObject_h |