9679c147f6f0a624cea84b01810a68bb6569cb92
[WebKit.git] / JavaScriptCore / kjs / JSGlobalObject.cpp
1 /*
2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "JSGlobalObject.h"
31
32 #include "SavedBuiltins.h"
33 #include "array_object.h"
34 #include "bool_object.h"
35 #include "date_object.h"
36 #include "debugger.h"
37 #include "error_object.h"
38 #include "function_object.h"
39 #include "math_object.h"
40 #include "number_object.h"
41 #include "object_object.h"
42 #include "regexp_object.h"
43 #include "string_object.h"
44
45 #if HAVE(SYS_TIME_H)
46 #include <sys/time.h>
47 #endif
48
49 #if PLATFORM(WIN_OS)
50 #include <windows.h>
51 #endif
52
53 #if PLATFORM(QT)
54 #include <QDateTime>
55 #endif
56
57 namespace KJS {
58
59 // Default number of ticks before a timeout check should be done.
60 static const int initialTickCountThreshold = 255;
61
62 // Preferred number of milliseconds between each timeout check
63 static const int preferredScriptCheckTimeInterval = 1000;
64
65 static inline void markIfNeeded(JSValue* v)
66 {
67     if (v && !v->marked())
68         v->mark();
69 }
70     
71 // Returns the current time in milliseconds
72 // It doesn't matter what "current time" is here, just as long as
73 // it's possible to measure the time difference correctly.
74 static inline unsigned getCurrentTime() {
75 #if HAVE(SYS_TIME_H)
76     struct timeval tv;
77     gettimeofday(&tv, 0);
78     return tv.tv_sec * 1000 + tv.tv_usec / 1000;
79 #elif PLATFORM(QT)
80     QDateTime t = QDateTime::currentDateTime();
81     return t.toTime_t() * 1000 + t.time().msec();
82 #elif PLATFORM(WIN_OS)
83     return timeGetTime();
84 #else
85 #error Platform does not have getCurrentTime function
86 #endif
87 }
88
89 JSGlobalObject* JSGlobalObject::s_head = 0;
90
91 JSGlobalObject::~JSGlobalObject()
92 {
93     ASSERT(JSLock::currentThreadIsHoldingLock());
94
95     if (d()->debugger)
96         d()->debugger->detach(this);
97
98     d()->next->d()->prev = d()->prev;
99     d()->prev->d()->next = d()->next;
100     s_head = d()->next;
101     if (s_head == this)
102         s_head = 0;
103     
104     delete d();
105 }
106
107 void JSGlobalObject::init()
108 {
109     ASSERT(JSLock::currentThreadIsHoldingLock());
110
111     if (s_head) {
112         d()->prev = s_head;
113         d()->next = s_head->d()->next;
114         s_head->d()->next->d()->prev = this;
115         s_head->d()->next = this;
116     } else
117         s_head = d()->next = d()->prev = this;
118
119     d()->compatMode = NativeMode;
120
121     resetTimeoutCheck();
122     d()->timeoutTime = 0;
123     d()->timeoutCheckCount = 0;
124
125     d()->currentExec = 0;
126     d()->recursion = 0;
127     d()->debugger = 0;
128     
129     reset(prototype());
130 }
131
132 bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
133 {
134     if (symbolTableGet(propertyName, slot))
135         return true;
136     return JSVariableObject::getOwnPropertySlot(exec, propertyName, slot);
137 }
138
139 void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
140 {
141     if (symbolTablePut(propertyName, value, attr))
142         return;
143     return JSVariableObject::put(exec, propertyName, value, attr);
144 }
145
146 static inline JSObject* lastInPrototypeChain(JSObject* object)
147 {
148     JSObject* o = object;
149     while (o->prototype()->isObject())
150         o = static_cast<JSObject*>(o->prototype());
151     return o;
152 }
153
154 void JSGlobalObject::reset(JSValue* prototype)
155 {
156     // Clear before inititalizing, to avoid calling mark() on stale pointers --
157     // which would be wasteful -- or uninitialized pointers -- which would be
158     // dangerous. (The allocations below may cause a GC.)
159
160     _prop.clear();
161     localStorage().clear();
162     symbolTable().clear();
163
164     // Prototypes
165     d()->functionPrototype = 0;
166     d()->objectPrototype = 0;
167
168     d()->arrayPrototype = 0;
169     d()->stringPrototype = 0;
170     d()->booleanPrototype = 0;
171     d()->numberPrototype = 0;
172     d()->datePrototype = 0;
173     d()->regExpPrototype = 0;
174     d()->errorPrototype = 0;
175     
176     d()->evalErrorPrototype = 0;
177     d()->rangeErrorPrototype = 0;
178     d()->referenceErrorPrototype = 0;
179     d()->syntaxErrorPrototype = 0;
180     d()->typeErrorPrototype = 0;
181     d()->URIErrorPrototype = 0;
182
183     // Constructors
184     d()->objectConstructor = 0;
185     d()->functionConstructor = 0;
186     d()->arrayConstructor = 0;
187     d()->stringConstructor = 0;
188     d()->booleanConstructor = 0;
189     d()->numberConstructor = 0;
190     d()->dateConstructor = 0;
191     d()->regExpConstructor = 0;
192     d()->errorConstructor = 0;
193     
194     d()->evalErrorConstructor = 0;
195     d()->rangeErrorConstructor = 0;
196     d()->referenceErrorConstructor = 0;
197     d()->syntaxErrorConstructor = 0;
198     d()->typeErrorConstructor = 0;
199     d()->URIErrorConstructor = 0;
200
201     ExecState* exec = &d()->globalExec;
202
203     // Prototypes
204     d()->functionPrototype = new FunctionPrototype(exec);
205     d()->objectPrototype = new ObjectPrototype(exec, d()->functionPrototype);
206     d()->functionPrototype->setPrototype(d()->objectPrototype);
207
208     d()->arrayPrototype = new ArrayPrototype(exec, d()->objectPrototype);
209     d()->stringPrototype = new StringPrototype(exec, d()->objectPrototype);
210     d()->booleanPrototype = new BooleanPrototype(exec, d()->objectPrototype, d()->functionPrototype);
211     d()->numberPrototype = new NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype);
212     d()->datePrototype = new DatePrototype(exec, d()->objectPrototype);
213     d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);;
214     d()->errorPrototype = new ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype);
215     
216     d()->evalErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError");
217     d()->rangeErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "RangeError", "RangeError");
218     d()->referenceErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "ReferenceError", "ReferenceError");
219     d()->syntaxErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "SyntaxError", "SyntaxError");
220     d()->typeErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "TypeError", "TypeError");
221     d()->URIErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "URIError", "URIError");
222
223     // Constructors
224     d()->objectConstructor = new ObjectObjectImp(exec, d()->objectPrototype, d()->functionPrototype);
225     d()->functionConstructor = new FunctionObjectImp(exec, d()->functionPrototype);
226     d()->arrayConstructor = new ArrayObjectImp(exec, d()->functionPrototype, d()->arrayPrototype);
227     d()->stringConstructor = new StringObjectImp(exec, d()->functionPrototype, d()->stringPrototype);
228     d()->booleanConstructor = new BooleanObjectImp(exec, d()->functionPrototype, d()->booleanPrototype);
229     d()->numberConstructor = new NumberObjectImp(exec, d()->functionPrototype, d()->numberPrototype);
230     d()->dateConstructor = new DateObjectImp(exec, d()->functionPrototype, d()->datePrototype);
231     d()->regExpConstructor = new RegExpObjectImp(exec, d()->functionPrototype, d()->regExpPrototype);
232     d()->errorConstructor = new ErrorObjectImp(exec, d()->functionPrototype, d()->errorPrototype);
233     
234     d()->evalErrorConstructor = new NativeErrorImp(exec, d()->functionPrototype, d()->evalErrorPrototype);
235     d()->rangeErrorConstructor = new NativeErrorImp(exec, d()->functionPrototype, d()->rangeErrorPrototype);
236     d()->referenceErrorConstructor = new NativeErrorImp(exec, d()->functionPrototype, d()->referenceErrorPrototype);
237     d()->syntaxErrorConstructor = new NativeErrorImp(exec, d()->functionPrototype, d()->syntaxErrorPrototype);
238     d()->typeErrorConstructor = new NativeErrorImp(exec, d()->functionPrototype, d()->typeErrorPrototype);
239     d()->URIErrorConstructor = new NativeErrorImp(exec, d()->functionPrototype, d()->URIErrorPrototype);
240     
241     d()->functionPrototype->put(exec, exec->propertyNames().constructor, d()->functionConstructor, DontEnum);
242
243     d()->objectPrototype->put(exec, exec->propertyNames().constructor, d()->objectConstructor, DontEnum | DontDelete | ReadOnly);
244     d()->functionPrototype->put(exec, exec->propertyNames().constructor, d()->functionConstructor, DontEnum | DontDelete | ReadOnly);
245     d()->arrayPrototype->put(exec, exec->propertyNames().constructor, d()->arrayConstructor, DontEnum | DontDelete | ReadOnly);
246     d()->booleanPrototype->put(exec, exec->propertyNames().constructor, d()->booleanConstructor, DontEnum | DontDelete | ReadOnly);
247     d()->stringPrototype->put(exec, exec->propertyNames().constructor, d()->stringConstructor, DontEnum | DontDelete | ReadOnly);
248     d()->numberPrototype->put(exec, exec->propertyNames().constructor, d()->numberConstructor, DontEnum | DontDelete | ReadOnly);
249     d()->datePrototype->put(exec, exec->propertyNames().constructor, d()->dateConstructor, DontEnum | DontDelete | ReadOnly);
250     d()->regExpPrototype->put(exec, exec->propertyNames().constructor, d()->regExpConstructor, DontEnum | DontDelete | ReadOnly);
251     d()->errorPrototype->put(exec, exec->propertyNames().constructor, d()->errorConstructor, DontEnum | DontDelete | ReadOnly);
252     d()->evalErrorPrototype->put(exec, exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum | DontDelete | ReadOnly);
253     d()->rangeErrorPrototype->put(exec, exec->propertyNames().constructor, d()->rangeErrorConstructor, DontEnum | DontDelete | ReadOnly);
254     d()->referenceErrorPrototype->put(exec, exec->propertyNames().constructor, d()->referenceErrorConstructor, DontEnum | DontDelete | ReadOnly);
255     d()->syntaxErrorPrototype->put(exec, exec->propertyNames().constructor, d()->syntaxErrorConstructor, DontEnum | DontDelete | ReadOnly);
256     d()->typeErrorPrototype->put(exec, exec->propertyNames().constructor, d()->typeErrorConstructor, DontEnum | DontDelete | ReadOnly);
257     d()->URIErrorPrototype->put(exec, exec->propertyNames().constructor, d()->URIErrorConstructor, DontEnum | DontDelete | ReadOnly);
258
259     // Set global constructors
260
261     // FIXME: kjs_window.cpp checks Internal/DontEnum as a performance hack, to
262     // see that these values can be put directly without a check for override
263     // properties.
264
265     // FIXME: These properties should be handled by a static hash table.
266
267     putDirect("Object", d()->objectConstructor, DontEnum);
268     putDirect("Function", d()->functionConstructor, DontEnum);
269     putDirect("Array", d()->arrayConstructor, DontEnum);
270     putDirect("Boolean", d()->booleanConstructor, DontEnum);
271     putDirect("String", d()->stringConstructor, DontEnum);
272     putDirect("Number", d()->numberConstructor, DontEnum);
273     putDirect("Date", d()->dateConstructor, DontEnum);
274     putDirect("RegExp", d()->regExpConstructor, DontEnum);
275     putDirect("Error", d()->errorConstructor, DontEnum);
276     putDirect("EvalError", d()->evalErrorConstructor, Internal);
277     putDirect("RangeError", d()->rangeErrorConstructor, Internal);
278     putDirect("ReferenceError", d()->referenceErrorConstructor, Internal);
279     putDirect("SyntaxError", d()->syntaxErrorConstructor, Internal);
280     putDirect("TypeError", d()->typeErrorConstructor, Internal);
281     putDirect("URIError", d()->URIErrorConstructor, Internal);
282
283     // Set global values.
284
285     putDirect("Math", new MathObjectImp(exec, d()->objectPrototype), DontEnum);
286
287     putDirect("NaN", jsNaN(), DontEnum | DontDelete);
288     putDirect("Infinity", jsNumber(Inf), DontEnum | DontDelete);
289     putDirect("undefined", jsUndefined(), DontEnum | DontDelete);
290
291     // Set global functions.
292
293     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
294     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
295     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
296     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
297     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
298     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
299     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
300     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
301     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
302     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
303     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
304 #ifndef NDEBUG
305     putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
306 #endif
307
308     // Set prototype, and also insert the object prototype at the end of the chain.
309
310     setPrototype(prototype);
311     lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
312 }
313
314 void JSGlobalObject::startTimeoutCheck()
315 {
316     if (!d()->timeoutCheckCount)
317         resetTimeoutCheck();
318     
319     ++d()->timeoutCheckCount;
320 }
321
322 void JSGlobalObject::stopTimeoutCheck()
323 {
324     --d()->timeoutCheckCount;
325 }
326
327 void JSGlobalObject::resetTimeoutCheck()
328 {
329     d()->tickCount = 0;
330     d()->ticksUntilNextTimeoutCheck = initialTickCountThreshold;
331     d()->timeAtLastCheckTimeout = 0;
332     d()->timeExecuting = 0;
333 }
334
335 bool JSGlobalObject::checkTimeout()
336 {    
337     d()->tickCount = 0;
338     
339     unsigned currentTime = getCurrentTime();
340
341     if (!d()->timeAtLastCheckTimeout) {
342         // Suspicious amount of looping in a script -- start timing it
343         d()->timeAtLastCheckTimeout = currentTime;
344         return false;
345     }
346
347     unsigned timeDiff = currentTime - d()->timeAtLastCheckTimeout;
348
349     if (timeDiff == 0)
350         timeDiff = 1;
351     
352     d()->timeExecuting += timeDiff;
353     d()->timeAtLastCheckTimeout = currentTime;
354     
355     // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in 
356     // preferredScriptCheckTimeInterval
357     d()->ticksUntilNextTimeoutCheck = (unsigned)((float)preferredScriptCheckTimeInterval / timeDiff) * d()->ticksUntilNextTimeoutCheck;
358
359     // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
360     // preferred script check time interval.
361     if (d()->ticksUntilNextTimeoutCheck == 0)
362         d()->ticksUntilNextTimeoutCheck = initialTickCountThreshold;
363
364     if (d()->timeoutTime && d()->timeExecuting > d()->timeoutTime) {
365         if (shouldInterruptScript())
366             return true;
367         
368         resetTimeoutCheck();
369     }
370     
371     return false;
372 }
373
374 void JSGlobalObject::saveBuiltins(SavedBuiltins& builtins) const
375 {
376     if (!builtins._internal)
377         builtins._internal = new SavedBuiltinsInternal;
378
379     builtins._internal->objectConstructor = d()->objectConstructor;
380     builtins._internal->functionConstructor = d()->functionConstructor;
381     builtins._internal->arrayConstructor = d()->arrayConstructor;
382     builtins._internal->booleanConstructor = d()->booleanConstructor;
383     builtins._internal->stringConstructor = d()->stringConstructor;
384     builtins._internal->numberConstructor = d()->numberConstructor;
385     builtins._internal->dateConstructor = d()->dateConstructor;
386     builtins._internal->regExpConstructor = d()->regExpConstructor;
387     builtins._internal->errorConstructor = d()->errorConstructor;
388     builtins._internal->evalErrorConstructor = d()->evalErrorConstructor;
389     builtins._internal->rangeErrorConstructor = d()->rangeErrorConstructor;
390     builtins._internal->referenceErrorConstructor = d()->referenceErrorConstructor;
391     builtins._internal->syntaxErrorConstructor = d()->syntaxErrorConstructor;
392     builtins._internal->typeErrorConstructor = d()->typeErrorConstructor;
393     builtins._internal->URIErrorConstructor = d()->URIErrorConstructor;
394     
395     builtins._internal->objectPrototype = d()->objectPrototype;
396     builtins._internal->functionPrototype = d()->functionPrototype;
397     builtins._internal->arrayPrototype = d()->arrayPrototype;
398     builtins._internal->booleanPrototype = d()->booleanPrototype;
399     builtins._internal->stringPrototype = d()->stringPrototype;
400     builtins._internal->numberPrototype = d()->numberPrototype;
401     builtins._internal->datePrototype = d()->datePrototype;
402     builtins._internal->regExpPrototype = d()->regExpPrototype;
403     builtins._internal->errorPrototype = d()->errorPrototype;
404     builtins._internal->evalErrorPrototype = d()->evalErrorPrototype;
405     builtins._internal->rangeErrorPrototype = d()->rangeErrorPrototype;
406     builtins._internal->referenceErrorPrototype = d()->referenceErrorPrototype;
407     builtins._internal->syntaxErrorPrototype = d()->syntaxErrorPrototype;
408     builtins._internal->typeErrorPrototype = d()->typeErrorPrototype;
409     builtins._internal->URIErrorPrototype = d()->URIErrorPrototype;
410 }
411
412 void JSGlobalObject::restoreBuiltins(const SavedBuiltins& builtins)
413 {
414     if (!builtins._internal)
415         return;
416
417     d()->objectConstructor = builtins._internal->objectConstructor;
418     d()->functionConstructor = builtins._internal->functionConstructor;
419     d()->arrayConstructor = builtins._internal->arrayConstructor;
420     d()->booleanConstructor = builtins._internal->booleanConstructor;
421     d()->stringConstructor = builtins._internal->stringConstructor;
422     d()->numberConstructor = builtins._internal->numberConstructor;
423     d()->dateConstructor = builtins._internal->dateConstructor;
424     d()->regExpConstructor = builtins._internal->regExpConstructor;
425     d()->errorConstructor = builtins._internal->errorConstructor;
426     d()->evalErrorConstructor = builtins._internal->evalErrorConstructor;
427     d()->rangeErrorConstructor = builtins._internal->rangeErrorConstructor;
428     d()->referenceErrorConstructor = builtins._internal->referenceErrorConstructor;
429     d()->syntaxErrorConstructor = builtins._internal->syntaxErrorConstructor;
430     d()->typeErrorConstructor = builtins._internal->typeErrorConstructor;
431     d()->URIErrorConstructor = builtins._internal->URIErrorConstructor;
432
433     d()->objectPrototype = builtins._internal->objectPrototype;
434     d()->functionPrototype = builtins._internal->functionPrototype;
435     d()->arrayPrototype = builtins._internal->arrayPrototype;
436     d()->booleanPrototype = builtins._internal->booleanPrototype;
437     d()->stringPrototype = builtins._internal->stringPrototype;
438     d()->numberPrototype = builtins._internal->numberPrototype;
439     d()->datePrototype = builtins._internal->datePrototype;
440     d()->regExpPrototype = builtins._internal->regExpPrototype;
441     d()->errorPrototype = builtins._internal->errorPrototype;
442     d()->evalErrorPrototype = builtins._internal->evalErrorPrototype;
443     d()->rangeErrorPrototype = builtins._internal->rangeErrorPrototype;
444     d()->referenceErrorPrototype = builtins._internal->referenceErrorPrototype;
445     d()->syntaxErrorPrototype = builtins._internal->syntaxErrorPrototype;
446     d()->typeErrorPrototype = builtins._internal->typeErrorPrototype;
447     d()->URIErrorPrototype = builtins._internal->URIErrorPrototype;
448 }
449
450 void JSGlobalObject::mark()
451 {
452     JSVariableObject::mark();
453
454     if (d()->currentExec)
455         d()->currentExec->mark();
456
457     markIfNeeded(d()->globalExec.exception());
458
459     markIfNeeded(d()->objectConstructor);
460     markIfNeeded(d()->functionConstructor);
461     markIfNeeded(d()->arrayConstructor);
462     markIfNeeded(d()->booleanConstructor);
463     markIfNeeded(d()->stringConstructor);
464     markIfNeeded(d()->numberConstructor);
465     markIfNeeded(d()->dateConstructor);
466     markIfNeeded(d()->regExpConstructor);
467     markIfNeeded(d()->errorConstructor);
468     markIfNeeded(d()->evalErrorConstructor);
469     markIfNeeded(d()->rangeErrorConstructor);
470     markIfNeeded(d()->referenceErrorConstructor);
471     markIfNeeded(d()->syntaxErrorConstructor);
472     markIfNeeded(d()->typeErrorConstructor);
473     markIfNeeded(d()->URIErrorConstructor);
474     
475     markIfNeeded(d()->objectPrototype);
476     markIfNeeded(d()->functionPrototype);
477     markIfNeeded(d()->arrayPrototype);
478     markIfNeeded(d()->booleanPrototype);
479     markIfNeeded(d()->stringPrototype);
480     markIfNeeded(d()->numberPrototype);
481     markIfNeeded(d()->datePrototype);
482     markIfNeeded(d()->regExpPrototype);
483     markIfNeeded(d()->errorPrototype);
484     markIfNeeded(d()->evalErrorPrototype);
485     markIfNeeded(d()->rangeErrorPrototype);
486     markIfNeeded(d()->referenceErrorPrototype);
487     markIfNeeded(d()->syntaxErrorPrototype);
488     markIfNeeded(d()->typeErrorPrototype);
489     markIfNeeded(d()->URIErrorPrototype);
490 }
491
492 ExecState* JSGlobalObject::globalExec()
493 {
494     return &d()->globalExec;
495 }
496
497 } // namespace KJS