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