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