]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
1 | /* |
2 | * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | |
f9bf01c6 | 3 | * Copyright (C) 2007, 2008, 2009 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" |
f9bf01c6 | 26 | #include "JSArray.h" |
93a37866 A |
27 | #include "JSClassRef.h" |
28 | #include "VM.h" | |
29 | #include "JSSegmentedVariableObject.h" | |
4e4e5a6f | 30 | #include "JSWeakObjectMapRefInternal.h" |
9dae56ea | 31 | #include "NumberPrototype.h" |
93a37866 | 32 | #include "SpecialPointer.h" |
9dae56ea | 33 | #include "StringPrototype.h" |
14957cd0 | 34 | #include "StructureChain.h" |
93a37866 A |
35 | #include "StructureRareDataInlines.h" |
36 | #include "Watchpoint.h" | |
37 | #include <JavaScriptCore/JSBase.h> | |
9dae56ea A |
38 | #include <wtf/HashSet.h> |
39 | #include <wtf/OwnPtr.h> | |
4e4e5a6f | 40 | #include <wtf/RandomNumber.h> |
9dae56ea | 41 | |
93a37866 A |
42 | struct OpaqueJSClass; |
43 | struct OpaqueJSClassContextData; | |
44 | ||
9dae56ea A |
45 | namespace JSC { |
46 | ||
93a37866 A |
47 | class ArrayPrototype; |
48 | class BooleanPrototype; | |
49 | class DatePrototype; | |
50 | class Debugger; | |
51 | class ErrorConstructor; | |
52 | class ErrorPrototype; | |
53 | class EvalCodeBlock; | |
54 | class EvalExecutable; | |
55 | class FunctionCodeBlock; | |
56 | class FunctionExecutable; | |
57 | class FunctionPrototype; | |
58 | class GetterSetter; | |
59 | class GlobalCodeBlock; | |
60 | class JSStack; | |
61 | class LLIntOffsetsExtractor; | |
62 | class NativeErrorConstructor; | |
63 | class ProgramCodeBlock; | |
64 | class ProgramExecutable; | |
65 | class RegExpConstructor; | |
66 | class RegExpPrototype; | |
67 | class SourceCode; | |
68 | struct ActivationStackNode; | |
69 | struct HashTable; | |
70 | ||
71 | typedef Vector<ExecState*, 16> ExecStateStack; | |
f9bf01c6 | 72 | |
93a37866 A |
73 | struct GlobalObjectMethodTable { |
74 | typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*); | |
75 | AllowsAccessFromFunctionPtr allowsAccessFrom; | |
76 | ||
77 | typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*); | |
78 | SupportsProfilingFunctionPtr supportsProfiling; | |
79 | ||
80 | typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*); | |
81 | SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo; | |
82 | ||
83 | typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*); | |
84 | ShouldInterruptScriptFunctionPtr shouldInterruptScript; | |
85 | ||
86 | typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*); | |
87 | JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled; | |
88 | ||
89 | #if PLATFORM(IOS) | |
90 | // NOTE: This needs to be the last entry in the struct. We have initialization code | |
91 | // that relies on that! See <rdar://12329156>. | |
92 | typedef bool (*ShouldInterruptScriptBeforeTimeoutPtr)(const JSGlobalObject*); | |
93 | ShouldInterruptScriptBeforeTimeoutPtr shouldInterruptScriptBeforeTimeout; | |
94 | #endif | |
95 | }; | |
96 | ||
97 | class JSGlobalObject : public JSSegmentedVariableObject { | |
98 | private: | |
99 | typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet; | |
100 | typedef HashMap<OpaqueJSClass*, OwnPtr<OpaqueJSClassContextData> > OpaqueJSClassDataMap; | |
101 | ||
102 | struct JSGlobalObjectRareData { | |
103 | JSGlobalObjectRareData() | |
104 | : profileGroup(0) | |
6fe7ccc8 | 105 | { |
6fe7ccc8 A |
106 | } |
107 | ||
93a37866 A |
108 | WeakMapSet weakMaps; |
109 | unsigned profileGroup; | |
110 | ||
111 | OpaqueJSClassDataMap opaqueJSClassData; | |
112 | }; | |
14957cd0 | 113 | |
93a37866 A |
114 | protected: |
115 | ||
116 | Register m_globalCallFrame[JSStack::CallFrameHeaderSize]; | |
117 | ||
118 | WriteBarrier<JSObject> m_globalThis; | |
119 | ||
120 | WriteBarrier<RegExpConstructor> m_regExpConstructor; | |
121 | WriteBarrier<ErrorConstructor> m_errorConstructor; | |
122 | WriteBarrier<NativeErrorConstructor> m_evalErrorConstructor; | |
123 | WriteBarrier<NativeErrorConstructor> m_rangeErrorConstructor; | |
124 | WriteBarrier<NativeErrorConstructor> m_referenceErrorConstructor; | |
125 | WriteBarrier<NativeErrorConstructor> m_syntaxErrorConstructor; | |
126 | WriteBarrier<NativeErrorConstructor> m_typeErrorConstructor; | |
127 | WriteBarrier<NativeErrorConstructor> m_URIErrorConstructor; | |
128 | ||
129 | WriteBarrier<JSFunction> m_evalFunction; | |
130 | WriteBarrier<JSFunction> m_callFunction; | |
131 | WriteBarrier<JSFunction> m_applyFunction; | |
132 | WriteBarrier<GetterSetter> m_throwTypeErrorGetterSetter; | |
133 | ||
134 | WriteBarrier<ObjectPrototype> m_objectPrototype; | |
135 | WriteBarrier<FunctionPrototype> m_functionPrototype; | |
136 | WriteBarrier<ArrayPrototype> m_arrayPrototype; | |
137 | WriteBarrier<BooleanPrototype> m_booleanPrototype; | |
138 | WriteBarrier<StringPrototype> m_stringPrototype; | |
139 | WriteBarrier<NumberPrototype> m_numberPrototype; | |
140 | WriteBarrier<DatePrototype> m_datePrototype; | |
141 | WriteBarrier<RegExpPrototype> m_regExpPrototype; | |
142 | WriteBarrier<ErrorPrototype> m_errorPrototype; | |
143 | ||
144 | WriteBarrier<Structure> m_withScopeStructure; | |
145 | WriteBarrier<Structure> m_strictEvalActivationStructure; | |
146 | WriteBarrier<Structure> m_activationStructure; | |
147 | WriteBarrier<Structure> m_nameScopeStructure; | |
148 | WriteBarrier<Structure> m_argumentsStructure; | |
149 | ||
150 | // Lists the actual structures used for having these particular indexing shapes. | |
151 | WriteBarrier<Structure> m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes]; | |
152 | // Lists the structures we should use during allocation for these particular indexing shapes. | |
153 | WriteBarrier<Structure> m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes]; | |
154 | ||
155 | WriteBarrier<Structure> m_booleanObjectStructure; | |
156 | WriteBarrier<Structure> m_callbackConstructorStructure; | |
157 | WriteBarrier<Structure> m_callbackFunctionStructure; | |
158 | WriteBarrier<Structure> m_callbackObjectStructure; | |
159 | #if JSC_OBJC_API_ENABLED | |
160 | WriteBarrier<Structure> m_objcCallbackFunctionStructure; | |
161 | WriteBarrier<Structure> m_objcWrapperObjectStructure; | |
162 | #endif | |
163 | WriteBarrier<Structure> m_dateStructure; | |
164 | WriteBarrier<Structure> m_nullPrototypeObjectStructure; | |
165 | WriteBarrier<Structure> m_errorStructure; | |
166 | WriteBarrier<Structure> m_functionStructure; | |
167 | WriteBarrier<Structure> m_boundFunctionStructure; | |
168 | WriteBarrier<Structure> m_namedFunctionStructure; | |
169 | PropertyOffset m_functionNameOffset; | |
170 | WriteBarrier<Structure> m_numberObjectStructure; | |
171 | WriteBarrier<Structure> m_privateNameStructure; | |
172 | WriteBarrier<Structure> m_regExpMatchesArrayStructure; | |
173 | WriteBarrier<Structure> m_regExpStructure; | |
174 | WriteBarrier<Structure> m_stringObjectStructure; | |
175 | WriteBarrier<Structure> m_internalFunctionStructure; | |
176 | ||
177 | void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. | |
14957cd0 | 178 | |
93a37866 | 179 | Debugger* m_debugger; |
14957cd0 | 180 | |
93a37866 A |
181 | RefPtr<WatchpointSet> m_masqueradesAsUndefinedWatchpoint; |
182 | RefPtr<WatchpointSet> m_havingABadTimeWatchpoint; | |
14957cd0 | 183 | |
93a37866 | 184 | OwnPtr<JSGlobalObjectRareData> m_rareData; |
9dae56ea | 185 | |
93a37866 | 186 | WeakRandom m_weakRandom; |
9dae56ea | 187 | |
93a37866 A |
188 | bool m_evalEnabled; |
189 | String m_evalDisabledErrorMessage; | |
190 | bool m_experimentsEnabled; | |
9dae56ea | 191 | |
93a37866 A |
192 | static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable; |
193 | const GlobalObjectMethodTable* m_globalObjectMethodTable; | |
9dae56ea | 194 | |
93a37866 A |
195 | void createRareDataIfNeeded() |
196 | { | |
197 | if (m_rareData) | |
198 | return; | |
199 | m_rareData = adoptPtr(new JSGlobalObjectRareData); | |
200 | } | |
201 | ||
202 | public: | |
203 | typedef JSSegmentedVariableObject Base; | |
9dae56ea | 204 | |
93a37866 A |
205 | static JSGlobalObject* create(VM& vm, Structure* structure) |
206 | { | |
207 | JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure); | |
208 | globalObject->finishCreation(vm); | |
209 | vm.heap.addFinalizer(globalObject, destroy); | |
210 | return globalObject; | |
211 | } | |
9dae56ea | 212 | |
93a37866 | 213 | static JS_EXPORTDATA const ClassInfo s_info; |
14957cd0 | 214 | |
93a37866 A |
215 | bool hasDebugger() const { return m_debugger; } |
216 | bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); } | |
9dae56ea | 217 | |
93a37866 A |
218 | protected: |
219 | JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0); | |
9dae56ea | 220 | |
93a37866 A |
221 | void finishCreation(VM& vm) |
222 | { | |
223 | Base::finishCreation(vm); | |
224 | structure()->setGlobalObject(vm, this); | |
225 | m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); | |
226 | init(this); | |
227 | } | |
9dae56ea | 228 | |
93a37866 A |
229 | void finishCreation(VM& vm, JSObject* thisValue) |
230 | { | |
231 | Base::finishCreation(vm); | |
232 | structure()->setGlobalObject(vm, this); | |
233 | m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); | |
234 | init(thisValue); | |
235 | } | |
4e4e5a6f | 236 | |
93a37866 A |
237 | public: |
238 | JS_EXPORT_PRIVATE ~JSGlobalObject(); | |
239 | JS_EXPORT_PRIVATE static void destroy(JSCell*); | |
240 | // We don't need a destructor because we use a finalizer instead. | |
241 | static const bool needsDestruction = false; | |
4e4e5a6f | 242 | |
93a37866 | 243 | JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); |
f9bf01c6 | 244 | |
93a37866 A |
245 | JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); |
246 | JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); | |
247 | bool hasOwnPropertyForWrite(ExecState*, PropertyName); | |
248 | JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); | |
f9bf01c6 | 249 | |
93a37866 | 250 | JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); |
9dae56ea | 251 | |
93a37866 A |
252 | JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes); |
253 | JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes); | |
254 | JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); | |
9dae56ea | 255 | |
93a37866 A |
256 | // We use this in the code generator as we perform symbol table |
257 | // lookups prior to initializing the properties | |
258 | bool symbolTableHasProperty(PropertyName); | |
9dae56ea | 259 | |
93a37866 A |
260 | // The following accessors return pristine values, even if a script |
261 | // replaces the global object's associated property. | |
9dae56ea | 262 | |
93a37866 | 263 | RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); } |
9dae56ea | 264 | |
93a37866 A |
265 | ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); } |
266 | NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); } | |
267 | NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); } | |
268 | NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); } | |
269 | NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); } | |
270 | NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); } | |
271 | NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); } | |
9dae56ea | 272 | |
93a37866 A |
273 | JSFunction* evalFunction() const { return m_evalFunction.get(); } |
274 | JSFunction* callFunction() const { return m_callFunction.get(); } | |
275 | JSFunction* applyFunction() const { return m_applyFunction.get(); } | |
276 | GetterSetter* throwTypeErrorGetterSetter(ExecState* exec) | |
9dae56ea | 277 | { |
93a37866 A |
278 | if (!m_throwTypeErrorGetterSetter) |
279 | createThrowTypeError(exec); | |
280 | return m_throwTypeErrorGetterSetter.get(); | |
9dae56ea A |
281 | } |
282 | ||
93a37866 A |
283 | ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); } |
284 | FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); } | |
285 | ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); } | |
286 | BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); } | |
287 | StringPrototype* stringPrototype() const { return m_stringPrototype.get(); } | |
288 | NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); } | |
289 | DatePrototype* datePrototype() const { return m_datePrototype.get(); } | |
290 | RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); } | |
291 | ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); } | |
292 | ||
293 | Structure* withScopeStructure() const { return m_withScopeStructure.get(); } | |
294 | Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } | |
295 | Structure* activationStructure() const { return m_activationStructure.get(); } | |
296 | Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } | |
297 | Structure* argumentsStructure() const { return m_argumentsStructure.get(); } | |
298 | Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const | |
9dae56ea | 299 | { |
93a37866 A |
300 | ASSERT(indexingType & IsArray); |
301 | return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); | |
f9bf01c6 | 302 | } |
93a37866 | 303 | Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const |
9dae56ea | 304 | { |
93a37866 A |
305 | ASSERT(indexingType & IsArray); |
306 | return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); | |
9dae56ea | 307 | } |
93a37866 | 308 | Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const |
14957cd0 | 309 | { |
93a37866 | 310 | return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile)); |
14957cd0 | 311 | } |
93a37866 A |
312 | |
313 | bool isOriginalArrayStructure(Structure* structure) | |
9dae56ea | 314 | { |
93a37866 | 315 | return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure; |
9dae56ea | 316 | } |
93a37866 A |
317 | |
318 | Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } | |
319 | Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } | |
320 | Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } | |
321 | Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); } | |
322 | #if JSC_OBJC_API_ENABLED | |
323 | Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(); } | |
324 | Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(); } | |
325 | #endif | |
326 | Structure* dateStructure() const { return m_dateStructure.get(); } | |
327 | Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); } | |
328 | Structure* errorStructure() const { return m_errorStructure.get(); } | |
329 | Structure* functionStructure() const { return m_functionStructure.get(); } | |
330 | Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); } | |
331 | Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); } | |
332 | PropertyOffset functionNameOffset() const { return m_functionNameOffset; } | |
333 | Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); } | |
334 | Structure* privateNameStructure() const { return m_privateNameStructure.get(); } | |
335 | Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); } | |
336 | Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } | |
337 | Structure* regExpStructure() const { return m_regExpStructure.get(); } | |
338 | Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } | |
339 | ||
340 | void* actualPointerFor(Special::Pointer pointer) | |
9dae56ea | 341 | { |
93a37866 A |
342 | ASSERT(pointer < Special::TableSize); |
343 | return m_specialPointers[pointer]; | |
9dae56ea A |
344 | } |
345 | ||
93a37866 A |
346 | WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); } |
347 | WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); } | |
348 | ||
349 | bool isHavingABadTime() const | |
9dae56ea | 350 | { |
93a37866 A |
351 | return m_havingABadTimeWatchpoint->hasBeenInvalidated(); |
352 | } | |
353 | ||
354 | void haveABadTime(VM&); | |
355 | ||
356 | bool arrayPrototypeChainIsSane(); | |
357 | ||
358 | void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; } | |
359 | unsigned profileGroup() const | |
360 | { | |
361 | if (!m_rareData) | |
362 | return 0; | |
363 | return m_rareData->profileGroup; | |
9dae56ea A |
364 | } |
365 | ||
93a37866 A |
366 | Debugger* debugger() const { return m_debugger; } |
367 | void setDebugger(Debugger* debugger) { m_debugger = debugger; } | |
9dae56ea | 368 | |
93a37866 | 369 | const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; } |
9dae56ea | 370 | |
93a37866 A |
371 | static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; } |
372 | static bool supportsProfiling(const JSGlobalObject*) { return false; } | |
373 | static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } | |
14957cd0 | 374 | |
93a37866 | 375 | JS_EXPORT_PRIVATE ExecState* globalExec(); |
f9bf01c6 | 376 | |
93a37866 A |
377 | #if PLATFORM(IOS) |
378 | static bool shouldInterruptScriptBeforeTimeout(const JSGlobalObject*) { return false; } | |
379 | #endif | |
380 | static bool shouldInterruptScript(const JSGlobalObject*) { return true; } | |
381 | static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; } | |
f9bf01c6 | 382 | |
93a37866 A |
383 | bool isDynamicScope(bool& requiresDynamicChecks) const; |
384 | ||
385 | bool evalEnabled() const { return m_evalEnabled; } | |
386 | const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } | |
387 | void setEvalEnabled(bool enabled, const String& errorMessage = String()) | |
f9bf01c6 | 388 | { |
93a37866 A |
389 | m_evalEnabled = enabled; |
390 | m_evalDisabledErrorMessage = errorMessage; | |
f9bf01c6 A |
391 | } |
392 | ||
93a37866 A |
393 | void resetPrototype(VM&, JSValue prototype); |
394 | ||
395 | VM& vm() const { return *Heap::heap(this)->vm(); } | |
396 | JSObject* globalThis() const; | |
397 | ||
398 | static Structure* createStructure(VM& vm, JSValue prototype) | |
f9bf01c6 | 399 | { |
93a37866 | 400 | return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info); |
14957cd0 A |
401 | } |
402 | ||
93a37866 | 403 | void registerWeakMap(OpaqueJSWeakObjectMap* map) |
14957cd0 | 404 | { |
93a37866 A |
405 | createRareDataIfNeeded(); |
406 | m_rareData->weakMaps.add(map); | |
14957cd0 A |
407 | } |
408 | ||
93a37866 | 409 | void unregisterWeakMap(OpaqueJSWeakObjectMap* map) |
14957cd0 | 410 | { |
93a37866 A |
411 | if (m_rareData) |
412 | m_rareData->weakMaps.remove(map); | |
f9bf01c6 A |
413 | } |
414 | ||
93a37866 | 415 | OpaqueJSClassDataMap& opaqueJSClassData() |
f9bf01c6 | 416 | { |
93a37866 A |
417 | createRareDataIfNeeded(); |
418 | return m_rareData->opaqueJSClassData; | |
f9bf01c6 A |
419 | } |
420 | ||
93a37866 A |
421 | double weakRandomNumber() { return m_weakRandom.get(); } |
422 | unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } | |
423 | ||
424 | UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); | |
425 | UnlinkedEvalCodeBlock* createEvalCodeBlock(CodeCache*, CallFrame*, JSScope*, EvalExecutable*, JSObject** exception); | |
426 | ||
427 | protected: | |
428 | ||
429 | static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; | |
9dae56ea | 430 | |
93a37866 A |
431 | struct GlobalPropertyInfo { |
432 | GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) | |
433 | : identifier(i) | |
434 | , value(v) | |
435 | , attributes(a) | |
9dae56ea | 436 | { |
9dae56ea A |
437 | } |
438 | ||
93a37866 A |
439 | const Identifier identifier; |
440 | JSValue value; | |
441 | unsigned attributes; | |
9dae56ea | 442 | }; |
93a37866 | 443 | JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count); |
9dae56ea | 444 | |
93a37866 A |
445 | JS_EXPORT_PRIVATE static JSC::JSObject* toThisObject(JSC::JSCell*, JSC::ExecState*); |
446 | ||
447 | JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis); | |
448 | ||
449 | private: | |
450 | friend class LLIntOffsetsExtractor; | |
451 | ||
452 | // FIXME: Fold reset into init. | |
453 | JS_EXPORT_PRIVATE void init(JSObject* thisValue); | |
454 | void reset(JSValue prototype); | |
455 | ||
456 | void createThrowTypeError(ExecState*); | |
457 | ||
458 | JS_EXPORT_PRIVATE static void clearRareData(JSCell*); | |
459 | }; | |
460 | ||
461 | JSGlobalObject* asGlobalObject(JSValue); | |
462 | ||
463 | inline JSGlobalObject* asGlobalObject(JSValue value) | |
464 | { | |
465 | ASSERT(asObject(value)->isGlobalObject()); | |
466 | return jsCast<JSGlobalObject*>(asObject(value)); | |
467 | } | |
468 | ||
469 | inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) | |
470 | { | |
471 | PropertySlot slot; | |
472 | if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) | |
6fe7ccc8 | 473 | return true; |
93a37866 A |
474 | bool slotIsWriteable; |
475 | return symbolTableGet(this, propertyName, slot, slotIsWriteable); | |
476 | } | |
477 | ||
478 | inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName) | |
479 | { | |
480 | SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); | |
481 | return !entry.isNull(); | |
482 | } | |
483 | ||
484 | inline JSGlobalObject* ExecState::dynamicGlobalObject() | |
485 | { | |
486 | if (this == lexicalGlobalObject()->globalExec()) | |
487 | return lexicalGlobalObject(); | |
488 | ||
489 | // For any ExecState that's not a globalExec, the | |
490 | // dynamic global object must be set since code is running | |
491 | ASSERT(vm().dynamicGlobalObject); | |
492 | return vm().dynamicGlobalObject; | |
493 | } | |
494 | ||
495 | inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0) | |
496 | { | |
497 | return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength)); | |
498 | } | |
499 | ||
500 | inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0) | |
501 | { | |
502 | return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength); | |
503 | } | |
504 | ||
505 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values) | |
506 | { | |
507 | return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values)); | |
508 | } | |
509 | ||
510 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values) | |
511 | { | |
512 | return constructArray(exec, profile, exec->lexicalGlobalObject(), values); | |
513 | } | |
514 | ||
515 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) | |
516 | { | |
517 | return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); | |
518 | } | |
519 | ||
520 | inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) | |
521 | { | |
522 | return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length); | |
523 | } | |
524 | ||
525 | class DynamicGlobalObjectScope { | |
526 | WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope); | |
527 | public: | |
528 | JS_EXPORT_PRIVATE DynamicGlobalObjectScope(VM&, JSGlobalObject*); | |
529 | ||
530 | ~DynamicGlobalObjectScope() | |
531 | { | |
532 | m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject; | |
6fe7ccc8 A |
533 | } |
534 | ||
93a37866 A |
535 | private: |
536 | JSGlobalObject*& m_dynamicGlobalObjectSlot; | |
537 | JSGlobalObject* m_savedDynamicGlobalObject; | |
538 | }; | |
539 | ||
540 | inline bool JSGlobalObject::isDynamicScope(bool&) const | |
541 | { | |
542 | return true; | |
543 | } | |
544 | ||
545 | inline JSObject* JSScope::globalThis() | |
546 | { | |
547 | return globalObject()->globalThis(); | |
548 | } | |
549 | ||
550 | inline JSObject* JSGlobalObject::globalThis() const | |
551 | { | |
552 | return m_globalThis.get(); | |
553 | } | |
554 | ||
9dae56ea A |
555 | } // namespace JSC |
556 | ||
557 | #endif // JSGlobalObject_h |