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