2008-03-20 Maciej Stachowiak <mjs@apple.com>
[WebKit.git] / JavaScriptCore / kjs / JSGlobalObject.h
1 // -*- c-basic-offset: 4 -*-
2 /*
3  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
4  *  Copyright (C) 2007 Apple Inc. All rights reserved.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifndef KJS_GlobalObject_h
24 #define KJS_GlobalObject_h
25
26 #include "JSVariableObject.h"
27 #include "Activation.h"
28
29 namespace KJS {
30
31     class ActivationImp;
32     class ArrayObjectImp;
33     class ArrayPrototype;
34     class BooleanObjectImp;
35     class BooleanPrototype;
36     class DateObjectImp;
37     class DatePrototype;
38     class Debugger;
39     class ErrorObjectImp;
40     class ErrorPrototype;
41     class EvalError;
42     class EvalErrorPrototype;
43     class FunctionObjectImp;
44     class FunctionPrototype;
45     class JSGlobalObject;
46     class NativeErrorImp;
47     class NativeErrorPrototype;
48     class NumberObjectImp;
49     class NumberPrototype;
50     class ObjectObjectImp;
51     class ObjectPrototype;
52     class PrototypeReflexiveFunction;
53     class RangeError;
54     class RangeErrorPrototype;
55     class ReferenceError;
56     class ReferenceError;
57     class ReferenceErrorPrototype;
58     class RegExpObjectImp;
59     class RegExpPrototype;
60     class RuntimeMethod;
61     class SavedBuiltins;
62     class ScopeChain;
63     class StringObjectImp;
64     class StringPrototype;
65     class SyntaxErrorPrototype;
66     class TypeError;
67     class TypeErrorPrototype;
68     class UriError;
69     class UriErrorPrototype;
70     struct ActivationStackNode;
71
72     typedef Vector<ExecState*, 16> ExecStateStack;
73
74     class JSGlobalObject : public JSVariableObject {
75     protected:
76         using JSVariableObject::JSVariableObjectData;
77
78         struct JSGlobalObjectData : public JSVariableObjectData {
79             JSGlobalObjectData(JSGlobalObject* globalObject)
80                 : JSVariableObjectData(&inlineSymbolTable)
81                 , globalExec(globalObject)
82             {
83             }
84
85             JSGlobalObject* next;
86             JSGlobalObject* prev;
87
88             Debugger* debugger;
89             
90             GlobalExecState globalExec;
91             int recursion;
92
93             unsigned timeoutTime;
94             unsigned timeAtLastCheckTimeout;
95             unsigned timeExecuting;
96             unsigned timeoutCheckCount;
97             unsigned tickCount;
98             unsigned ticksUntilNextTimeoutCheck;
99
100             ObjectObjectImp* objectConstructor;
101             FunctionObjectImp* functionConstructor;
102             ArrayObjectImp* arrayConstructor;
103             BooleanObjectImp* booleanConstructor;
104             StringObjectImp* stringConstructor;
105             NumberObjectImp* numberConstructor;
106             DateObjectImp* dateConstructor;
107             RegExpObjectImp* regExpConstructor;
108             ErrorObjectImp* errorConstructor;
109             NativeErrorImp* evalErrorConstructor;
110             NativeErrorImp* rangeErrorConstructor;
111             NativeErrorImp* referenceErrorConstructor;
112             NativeErrorImp* syntaxErrorConstructor;
113             NativeErrorImp* typeErrorConstructor;
114             NativeErrorImp* URIErrorConstructor;
115
116             PrototypeReflexiveFunction* evalFunction;
117
118             ObjectPrototype* objectPrototype;
119             FunctionPrototype* functionPrototype;
120             ArrayPrototype* arrayPrototype;
121             BooleanPrototype* booleanPrototype;
122             StringPrototype* stringPrototype;
123             NumberPrototype* numberPrototype;
124             DatePrototype* datePrototype;
125             RegExpPrototype* regExpPrototype;
126             ErrorPrototype* errorPrototype;
127             NativeErrorPrototype* evalErrorPrototype;
128             NativeErrorPrototype* rangeErrorPrototype;
129             NativeErrorPrototype* referenceErrorPrototype;
130             NativeErrorPrototype* syntaxErrorPrototype;
131             NativeErrorPrototype* typeErrorPrototype;
132             NativeErrorPrototype* URIErrorPrototype;
133             
134             SymbolTable inlineSymbolTable;
135
136             ExecStateStack activeExecStates;
137
138             ActivationStackNode* activations;
139             size_t activationCount;
140         };
141
142     public:
143         JSGlobalObject()
144             : JSVariableObject(new JSGlobalObjectData(this))
145         {
146             init();
147         }
148
149     protected:
150         JSGlobalObject(JSValue* proto)
151             : JSVariableObject(proto, new JSGlobalObjectData(this))
152         {
153             init();
154         }
155
156     public:
157         virtual ~JSGlobalObject();
158
159         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
160         virtual void put(ExecState*, const Identifier&, JSValue*);
161         virtual void initializeVariable(ExecState*, const Identifier&, JSValue*, unsigned attributes);
162
163         // Linked list of all global objects.
164         static JSGlobalObject* head() { return s_head; }
165         JSGlobalObject* next() { return d()->next; }
166
167         // Resets the global object to contain only built-in properties, sets
168         // the global object's prototype to "prototype," then adds the 
169         // default object prototype to the tail of the global object's 
170         // prototype chain.
171         void reset(JSValue* prototype);
172
173         // The following accessors return pristine values, even if a script 
174         // replaces the global object's associated property.
175
176         ObjectObjectImp* objectConstructor() const { return d()->objectConstructor; }
177         FunctionObjectImp* functionConstructor() const { return d()->functionConstructor; }
178         ArrayObjectImp* arrayConstructor() const { return d()->arrayConstructor; }
179         BooleanObjectImp* booleanConstructor() const { return d()->booleanConstructor; }
180         StringObjectImp* stringConstructor() const{ return d()->stringConstructor; }
181         NumberObjectImp* numberConstructor() const{ return d()->numberConstructor; }
182         DateObjectImp* dateConstructor() const{ return d()->dateConstructor; }
183         RegExpObjectImp* regExpConstructor() const { return d()->regExpConstructor; }
184         ErrorObjectImp* errorConstructor() const { return d()->errorConstructor; }
185         NativeErrorImp* evalErrorConstructor() const { return d()->evalErrorConstructor; }
186         NativeErrorImp* rangeErrorConstructor() const { return d()->rangeErrorConstructor; }
187         NativeErrorImp* referenceErrorConstructor() const { return d()->referenceErrorConstructor; }
188         NativeErrorImp* syntaxErrorConstructor() const { return d()->syntaxErrorConstructor; }
189         NativeErrorImp* typeErrorConstructor() const { return d()->typeErrorConstructor; }
190         NativeErrorImp* URIErrorConstructor() const { return d()->URIErrorConstructor; }
191
192         PrototypeReflexiveFunction* evalFunction() const { return d()->evalFunction; }
193
194         ObjectPrototype* objectPrototype() const { return d()->objectPrototype; }
195         FunctionPrototype* functionPrototype() const { return d()->functionPrototype; }
196         ArrayPrototype* arrayPrototype() const { return d()->arrayPrototype; }
197         BooleanPrototype* booleanPrototype() const { return d()->booleanPrototype; }
198         StringPrototype* stringPrototype() const { return d()->stringPrototype; }
199         NumberPrototype* numberPrototype() const { return d()->numberPrototype; }
200         DatePrototype* datePrototype() const { return d()->datePrototype; }
201         RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
202         ErrorPrototype* errorPrototype() const { return d()->errorPrototype; }
203         NativeErrorPrototype* evalErrorPrototype() const { return d()->evalErrorPrototype; }
204         NativeErrorPrototype* rangeErrorPrototype() const { return d()->rangeErrorPrototype; }
205         NativeErrorPrototype* referenceErrorPrototype() const { return d()->referenceErrorPrototype; }
206         NativeErrorPrototype* syntaxErrorPrototype() const { return d()->syntaxErrorPrototype; }
207         NativeErrorPrototype* typeErrorPrototype() const { return d()->typeErrorPrototype; }
208         NativeErrorPrototype* URIErrorPrototype() const { return d()->URIErrorPrototype; }
209
210         void saveBuiltins(SavedBuiltins&) const;
211         void restoreBuiltins(const SavedBuiltins&);
212
213         void setTimeoutTime(unsigned timeoutTime) { d()->timeoutTime = timeoutTime; }
214         void startTimeoutCheck();
215         void stopTimeoutCheck();
216         bool timedOut();
217
218         Debugger* debugger() const { return d()->debugger; }
219         void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
220         
221         int recursion() { return d()->recursion; }
222         void incRecursion() { ++d()->recursion; }
223         void decRecursion() { --d()->recursion; }
224
225         virtual void mark();
226
227         virtual bool isGlobalObject() const { return true; }
228
229         virtual ExecState* globalExec();
230
231         virtual bool shouldInterruptScript() const { return true; }
232
233         virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
234
235         ActivationImp* pushActivation(ExecState*);
236         void popActivation();
237         void tearOffActivation(ExecState*, bool markAsRelic = false);
238
239         virtual bool isDynamicScope() const;
240
241         ExecStateStack& activeExecStates() const { return d()->activeExecStates; }
242
243     private:
244         void init();
245         
246         JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
247
248         bool checkTimeout();
249         void resetTimeoutCheck();
250
251         void deleteActivationStack();
252         void checkActivationCount();
253
254         static JSGlobalObject* s_head;
255     };
256
257     inline bool JSGlobalObject::timedOut()
258     {
259         d()->tickCount++;
260
261         if (d()->tickCount != d()->ticksUntilNextTimeoutCheck)
262             return false;
263
264         return checkTimeout();
265     }
266
267     inline ActivationImp* JSGlobalObject::pushActivation(ExecState* exec)
268     {
269         if (d()->activationCount == activationStackNodeSize) {
270             ActivationStackNode* newNode = new ActivationStackNode;
271             newNode->prev = d()->activations;
272             d()->activations = newNode;
273             d()->activationCount = 0;
274         }
275         
276         StackActivation* stackEntry = &d()->activations->data[d()->activationCount++];
277         stackEntry->activationStorage.init(exec);
278         return &stackEntry->activationStorage;
279     }
280
281     inline void JSGlobalObject::checkActivationCount()
282     {
283         if (!d()->activationCount) {
284             ActivationStackNode* prev = d()->activations->prev;
285             ASSERT(prev);
286             delete d()->activations;
287             d()->activations = prev;
288             d()->activationCount = activationStackNodeSize;
289         }
290     }
291
292     inline void JSGlobalObject::popActivation()
293     {
294         checkActivationCount();
295         d()->activations->data[--d()->activationCount].activationDataStorage.localStorage.shrink(0);    
296     }
297
298 } // namespace KJS
299
300 #endif // KJS_GlobalObject_h