b779f4304e36f72742fe97de03bfd7937d83c467
[WebKit-https.git] / JavaScriptCore / kjs / JSGlobalObject.cpp
1 /*
2  * Copyright (C) 2007 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 namespace KJS {
46
47 // Default number of ticks before a timeout check should be done.
48 static const int initialTickCountThreshold = 255;
49
50 // Preferred number of milliseconds between each timeout check
51 static const int preferredScriptCheckTimeInterval = 1000;
52
53 static inline void markIfNeeded(JSValue* v)
54 {
55     if (v && !v->marked())
56         v->mark();
57 }
58     
59 // Returns the current time in milliseconds
60 // It doesn't matter what "current time" is here, just as long as
61 // it's possible to measure the time difference correctly.
62 static inline unsigned getCurrentTime() {
63 #if HAVE(SYS_TIME_H)
64     struct timeval tv;
65     gettimeofday(&tv, 0);
66     return tv.tv_sec * 1000 + tv.tv_usec / 1000;
67 #elif PLATFORM(QT)
68     QDateTime t = QDateTime::currentDateTime();
69     return t.toTime_t() * 1000 + t.time().msec();
70 #elif PLATFORM(WIN_OS)
71     return timeGetTime();
72 #else
73 #error Platform does not have getCurrentTime function
74 #endif
75 }
76
77 JSGlobalObject* JSGlobalObject::s_head = 0;
78
79 JSGlobalObject::~JSGlobalObject()
80 {
81     ASSERT(JSLock::currentThreadIsHoldingLock());
82
83     if (d->debugger)
84         d->debugger->detach(this);
85
86     d->next->d->prev = d->prev;
87     d->prev->d->next = d->next;
88     s_head = d->next;
89     if (s_head == this)
90         s_head = 0;
91 }
92
93 void JSGlobalObject::init()
94 {
95     ASSERT(JSLock::currentThreadIsHoldingLock());
96
97     d.reset(new JSGlobalObjectData(this));
98
99     if (s_head) {
100         d->prev = s_head;
101         d->next = s_head->d->next;
102         s_head->d->next->d->prev = this;
103         s_head->d->next = this;
104     } else
105         s_head = d->next = d->prev = this;
106
107     d->compatMode = NativeMode;
108
109     resetTimeoutCheck();
110     d->timeoutTime = 0;
111     d->timeoutCheckCount = 0;
112
113     d->currentExec = 0;
114     d->recursion = 0;
115     d->debugger = 0;
116     
117     reset(prototype());
118 }
119
120 static inline JSObject* lastInPrototypeChain(JSObject* object)
121 {
122     JSObject* o = object;
123     while (o->prototype()->isObject())
124         o = static_cast<JSObject*>(o->prototype());
125     return o;
126 }
127
128 void JSGlobalObject::reset(JSValue* prototype)
129 {
130     // Clear before inititalizing, to avoid marking uninitialized (dangerous) or 
131     // stale (wasteful) pointers during possible garbage collection while creating
132     // new objects below.
133
134     ExecState* exec = &d->globalExec;
135
136     // Prototypes
137     d->functionPrototype = 0;
138     d->objectPrototype = 0;
139
140     d->arrayPrototype = 0;
141     d->stringPrototype = 0;
142     d->booleanPrototype = 0;
143     d->numberPrototype = 0;
144     d->datePrototype = 0;
145     d->regExpPrototype = 0;
146     d->errorPrototype = 0;
147     
148     d->evalErrorPrototype = 0;
149     d->rangeErrorPrototype = 0;
150     d->referenceErrorPrototype = 0;
151     d->syntaxErrorPrototype = 0;
152     d->typeErrorPrototype = 0;
153     d->URIErrorPrototype = 0;
154
155     // Constructors
156     d->objectConstructor = 0;
157     d->functionConstructor = 0;
158     d->arrayConstructor = 0;
159     d->stringConstructor = 0;
160     d->booleanConstructor = 0;
161     d->numberConstructor = 0;
162     d->dateConstructor = 0;
163     d->regExpConstructor = 0;
164     d->errorConstructor = 0;
165     
166     d->evalErrorConstructor = 0;
167     d->rangeErrorConstructor = 0;
168     d->referenceErrorConstructor = 0;
169     d->syntaxErrorConstructor = 0;
170     d->typeErrorConstructor = 0;
171     d->URIErrorConstructor = 0;
172
173     // Prototypes
174     d->functionPrototype = new FunctionPrototype(exec);
175     d->objectPrototype = new ObjectPrototype(exec, d->functionPrototype);
176     d->functionPrototype->setPrototype(d->objectPrototype);
177
178     d->arrayPrototype = new ArrayPrototype(exec, d->objectPrototype);
179     d->stringPrototype = new StringPrototype(exec, d->objectPrototype);
180     d->booleanPrototype = new BooleanPrototype(exec, d->objectPrototype, d->functionPrototype);
181     d->numberPrototype = new NumberPrototype(exec, d->objectPrototype, d->functionPrototype);
182     d->datePrototype = new DatePrototype(exec, d->objectPrototype);
183     d->regExpPrototype = new RegExpPrototype(exec, d->objectPrototype, d->functionPrototype);;
184     d->errorPrototype = new ErrorPrototype(exec, d->objectPrototype, d->functionPrototype);
185     
186     d->evalErrorPrototype = new NativeErrorPrototype(exec, d->errorPrototype, EvalError, "EvalError", "EvalError");
187     d->rangeErrorPrototype = new NativeErrorPrototype(exec, d->errorPrototype, RangeError, "RangeError", "RangeError");
188     d->referenceErrorPrototype = new NativeErrorPrototype(exec, d->errorPrototype, ReferenceError, "ReferenceError", "ReferenceError");
189     d->syntaxErrorPrototype = new NativeErrorPrototype(exec, d->errorPrototype, SyntaxError, "SyntaxError", "SyntaxError");
190     d->typeErrorPrototype = new NativeErrorPrototype(exec, d->errorPrototype, TypeError, "TypeError", "TypeError");
191     d->URIErrorPrototype = new NativeErrorPrototype(exec, d->errorPrototype, URIError, "URIError", "URIError");
192
193     // Constructors
194     d->objectConstructor = new ObjectObjectImp(exec, d->objectPrototype, d->functionPrototype);
195     d->functionConstructor = new FunctionObjectImp(exec, d->functionPrototype);
196     d->arrayConstructor = new ArrayObjectImp(exec, d->functionPrototype, d->arrayPrototype);
197     d->stringConstructor = new StringObjectImp(exec, d->functionPrototype, d->stringPrototype);
198     d->booleanConstructor = new BooleanObjectImp(exec, d->functionPrototype, d->booleanPrototype);
199     d->numberConstructor = new NumberObjectImp(exec, d->functionPrototype, d->numberPrototype);
200     d->dateConstructor = new DateObjectImp(exec, d->functionPrototype, d->datePrototype);
201     d->regExpConstructor = new RegExpObjectImp(exec, d->functionPrototype, d->regExpPrototype);
202     d->errorConstructor = new ErrorObjectImp(exec, d->functionPrototype, d->errorPrototype);
203     
204     d->evalErrorConstructor = new NativeErrorImp(exec, d->functionPrototype, d->evalErrorPrototype);
205     d->rangeErrorConstructor = new NativeErrorImp(exec, d->functionPrototype, d->rangeErrorPrototype);
206     d->referenceErrorConstructor = new NativeErrorImp(exec, d->functionPrototype, d->referenceErrorPrototype);
207     d->syntaxErrorConstructor = new NativeErrorImp(exec, d->functionPrototype, d->syntaxErrorPrototype);
208     d->typeErrorConstructor = new NativeErrorImp(exec, d->functionPrototype, d->typeErrorPrototype);
209     d->URIErrorConstructor = new NativeErrorImp(exec, d->functionPrototype, d->URIErrorPrototype);
210     
211     d->functionPrototype->put(exec, exec->propertyNames().constructor, d->functionConstructor, DontEnum);
212
213     d->objectPrototype->put(exec, exec->propertyNames().constructor, d->objectConstructor, DontEnum | DontDelete | ReadOnly);
214     d->functionPrototype->put(exec, exec->propertyNames().constructor, d->functionConstructor, DontEnum | DontDelete | ReadOnly);
215     d->arrayPrototype->put(exec, exec->propertyNames().constructor, d->arrayConstructor, DontEnum | DontDelete | ReadOnly);
216     d->booleanPrototype->put(exec, exec->propertyNames().constructor, d->booleanConstructor, DontEnum | DontDelete | ReadOnly);
217     d->stringPrototype->put(exec, exec->propertyNames().constructor, d->stringConstructor, DontEnum | DontDelete | ReadOnly);
218     d->numberPrototype->put(exec, exec->propertyNames().constructor, d->numberConstructor, DontEnum | DontDelete | ReadOnly);
219     d->datePrototype->put(exec, exec->propertyNames().constructor, d->dateConstructor, DontEnum | DontDelete | ReadOnly);
220     d->regExpPrototype->put(exec, exec->propertyNames().constructor, d->regExpConstructor, DontEnum | DontDelete | ReadOnly);
221     d->errorPrototype->put(exec, exec->propertyNames().constructor, d->errorConstructor, DontEnum | DontDelete | ReadOnly);
222     d->evalErrorPrototype->put(exec, exec->propertyNames().constructor, d->evalErrorConstructor, DontEnum | DontDelete | ReadOnly);
223     d->rangeErrorPrototype->put(exec, exec->propertyNames().constructor, d->rangeErrorConstructor, DontEnum | DontDelete | ReadOnly);
224     d->referenceErrorPrototype->put(exec, exec->propertyNames().constructor, d->referenceErrorConstructor, DontEnum | DontDelete | ReadOnly);
225     d->syntaxErrorPrototype->put(exec, exec->propertyNames().constructor, d->syntaxErrorConstructor, DontEnum | DontDelete | ReadOnly);
226     d->typeErrorPrototype->put(exec, exec->propertyNames().constructor, d->typeErrorConstructor, DontEnum | DontDelete | ReadOnly);
227     d->URIErrorPrototype->put(exec, exec->propertyNames().constructor, d->URIErrorConstructor, DontEnum | DontDelete | ReadOnly);
228
229     // Set global constructors
230
231     // FIXME: kjs_window.cpp checks Internal/DontEnum as a performance hack, to
232     // see that these values can be put directly without a check for override
233     // properties.
234
235     // FIXME: These properties should be handled by a static hash table.
236
237     putDirect("Object", d->objectConstructor, DontEnum);
238     putDirect("Function", d->functionConstructor, DontEnum);
239     putDirect("Array", d->arrayConstructor, DontEnum);
240     putDirect("Boolean", d->booleanConstructor, DontEnum);
241     putDirect("String", d->stringConstructor, DontEnum);
242     putDirect("Number", d->numberConstructor, DontEnum);
243     putDirect("Date", d->dateConstructor, DontEnum);
244     putDirect("RegExp", d->regExpConstructor, DontEnum);
245     putDirect("Error", d->errorConstructor, DontEnum);
246     putDirect("EvalError", d->evalErrorConstructor, Internal);
247     putDirect("RangeError", d->rangeErrorConstructor, Internal);
248     putDirect("ReferenceError", d->referenceErrorConstructor, Internal);
249     putDirect("SyntaxError", d->syntaxErrorConstructor, Internal);
250     putDirect("TypeError", d->typeErrorConstructor, Internal);
251     putDirect("URIError", d->URIErrorConstructor, Internal);
252
253     // Set global values.
254
255     putDirect("Math", new MathObjectImp(exec, d->objectPrototype), DontEnum);
256
257     putDirect("NaN", jsNaN(), DontEnum | DontDelete);
258     putDirect("Infinity", jsNumber(Inf), DontEnum | DontDelete);
259     putDirect("undefined", jsUndefined(), DontEnum | DontDelete);
260
261     // Set global functions.
262
263     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
264     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
265     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
266     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
267     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
268     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
269     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
270     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
271     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
272     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
273     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
274 #ifndef NDEBUG
275     putDirectFunction(new GlobalFuncImp(exec, d->functionPrototype, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
276 #endif
277
278     // Set prototype, and also insert the object prototype at the end of the chain.
279
280     setPrototype(prototype);
281     lastInPrototypeChain(this)->setPrototype(d->objectPrototype);
282 }
283
284 void JSGlobalObject::startTimeoutCheck()
285 {
286     if (!d->timeoutCheckCount)
287         resetTimeoutCheck();
288     
289     ++d->timeoutCheckCount;
290 }
291
292 void JSGlobalObject::stopTimeoutCheck()
293 {
294     --d->timeoutCheckCount;
295 }
296
297 void JSGlobalObject::resetTimeoutCheck()
298 {
299     d->tickCount = 0;
300     d->ticksUntilNextTimeoutCheck = initialTickCountThreshold;
301     d->timeAtLastCheckTimeout = 0;
302     d->timeExecuting = 0;
303 }
304
305 bool JSGlobalObject::checkTimeout()
306 {    
307     d->tickCount = 0;
308     
309     unsigned currentTime = getCurrentTime();
310
311     if (!d->timeAtLastCheckTimeout) {
312         // Suspicious amount of looping in a script -- start timing it
313         d->timeAtLastCheckTimeout = currentTime;
314         return false;
315     }
316
317     unsigned timeDiff = currentTime - d->timeAtLastCheckTimeout;
318
319     if (timeDiff == 0)
320         timeDiff = 1;
321     
322     d->timeExecuting += timeDiff;
323     d->timeAtLastCheckTimeout = currentTime;
324     
325     // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in 
326     // preferredScriptCheckTimeInterval
327     d->ticksUntilNextTimeoutCheck = (unsigned)((float)preferredScriptCheckTimeInterval / timeDiff) * d->ticksUntilNextTimeoutCheck;
328
329     // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
330     // preferred script check time interval.
331     if (d->ticksUntilNextTimeoutCheck == 0)
332         d->ticksUntilNextTimeoutCheck = initialTickCountThreshold;
333
334     if (d->timeoutTime && d->timeExecuting > d->timeoutTime) {
335         if (shouldInterruptScript())
336             return true;
337         
338         resetTimeoutCheck();
339     }
340     
341     return false;
342 }
343
344 void JSGlobalObject::saveBuiltins(SavedBuiltins& builtins) const
345 {
346     if (!builtins._internal)
347         builtins._internal = new SavedBuiltinsInternal;
348
349     builtins._internal->objectConstructor = d->objectConstructor;
350     builtins._internal->functionConstructor = d->functionConstructor;
351     builtins._internal->arrayConstructor = d->arrayConstructor;
352     builtins._internal->booleanConstructor = d->booleanConstructor;
353     builtins._internal->stringConstructor = d->stringConstructor;
354     builtins._internal->numberConstructor = d->numberConstructor;
355     builtins._internal->dateConstructor = d->dateConstructor;
356     builtins._internal->regExpConstructor = d->regExpConstructor;
357     builtins._internal->errorConstructor = d->errorConstructor;
358     builtins._internal->evalErrorConstructor = d->evalErrorConstructor;
359     builtins._internal->rangeErrorConstructor = d->rangeErrorConstructor;
360     builtins._internal->referenceErrorConstructor = d->referenceErrorConstructor;
361     builtins._internal->syntaxErrorConstructor = d->syntaxErrorConstructor;
362     builtins._internal->typeErrorConstructor = d->typeErrorConstructor;
363     builtins._internal->URIErrorConstructor = d->URIErrorConstructor;
364     
365     builtins._internal->objectPrototype = d->objectPrototype;
366     builtins._internal->functionPrototype = d->functionPrototype;
367     builtins._internal->arrayPrototype = d->arrayPrototype;
368     builtins._internal->booleanPrototype = d->booleanPrototype;
369     builtins._internal->stringPrototype = d->stringPrototype;
370     builtins._internal->numberPrototype = d->numberPrototype;
371     builtins._internal->datePrototype = d->datePrototype;
372     builtins._internal->regExpPrototype = d->regExpPrototype;
373     builtins._internal->errorPrototype = d->errorPrototype;
374     builtins._internal->evalErrorPrototype = d->evalErrorPrototype;
375     builtins._internal->rangeErrorPrototype = d->rangeErrorPrototype;
376     builtins._internal->referenceErrorPrototype = d->referenceErrorPrototype;
377     builtins._internal->syntaxErrorPrototype = d->syntaxErrorPrototype;
378     builtins._internal->typeErrorPrototype = d->typeErrorPrototype;
379     builtins._internal->URIErrorPrototype = d->URIErrorPrototype;
380 }
381
382 void JSGlobalObject::restoreBuiltins(const SavedBuiltins& builtins)
383 {
384     if (!builtins._internal)
385         return;
386
387     d->objectConstructor = builtins._internal->objectConstructor;
388     d->functionConstructor = builtins._internal->functionConstructor;
389     d->arrayConstructor = builtins._internal->arrayConstructor;
390     d->booleanConstructor = builtins._internal->booleanConstructor;
391     d->stringConstructor = builtins._internal->stringConstructor;
392     d->numberConstructor = builtins._internal->numberConstructor;
393     d->dateConstructor = builtins._internal->dateConstructor;
394     d->regExpConstructor = builtins._internal->regExpConstructor;
395     d->errorConstructor = builtins._internal->errorConstructor;
396     d->evalErrorConstructor = builtins._internal->evalErrorConstructor;
397     d->rangeErrorConstructor = builtins._internal->rangeErrorConstructor;
398     d->referenceErrorConstructor = builtins._internal->referenceErrorConstructor;
399     d->syntaxErrorConstructor = builtins._internal->syntaxErrorConstructor;
400     d->typeErrorConstructor = builtins._internal->typeErrorConstructor;
401     d->URIErrorConstructor = builtins._internal->URIErrorConstructor;
402
403     d->objectPrototype = builtins._internal->objectPrototype;
404     d->functionPrototype = builtins._internal->functionPrototype;
405     d->arrayPrototype = builtins._internal->arrayPrototype;
406     d->booleanPrototype = builtins._internal->booleanPrototype;
407     d->stringPrototype = builtins._internal->stringPrototype;
408     d->numberPrototype = builtins._internal->numberPrototype;
409     d->datePrototype = builtins._internal->datePrototype;
410     d->regExpPrototype = builtins._internal->regExpPrototype;
411     d->errorPrototype = builtins._internal->errorPrototype;
412     d->evalErrorPrototype = builtins._internal->evalErrorPrototype;
413     d->rangeErrorPrototype = builtins._internal->rangeErrorPrototype;
414     d->referenceErrorPrototype = builtins._internal->referenceErrorPrototype;
415     d->syntaxErrorPrototype = builtins._internal->syntaxErrorPrototype;
416     d->typeErrorPrototype = builtins._internal->typeErrorPrototype;
417     d->URIErrorPrototype = builtins._internal->URIErrorPrototype;
418 }
419
420 void JSGlobalObject::mark()
421 {
422     JSObject::mark();
423
424     if (d->currentExec)
425         d->currentExec->mark();
426
427     markIfNeeded(d->globalExec.exception());
428
429     markIfNeeded(d->objectConstructor);
430     markIfNeeded(d->functionConstructor);
431     markIfNeeded(d->arrayConstructor);
432     markIfNeeded(d->booleanConstructor);
433     markIfNeeded(d->stringConstructor);
434     markIfNeeded(d->numberConstructor);
435     markIfNeeded(d->dateConstructor);
436     markIfNeeded(d->regExpConstructor);
437     markIfNeeded(d->errorConstructor);
438     markIfNeeded(d->evalErrorConstructor);
439     markIfNeeded(d->rangeErrorConstructor);
440     markIfNeeded(d->referenceErrorConstructor);
441     markIfNeeded(d->syntaxErrorConstructor);
442     markIfNeeded(d->typeErrorConstructor);
443     markIfNeeded(d->URIErrorConstructor);
444     
445     markIfNeeded(d->objectPrototype);
446     markIfNeeded(d->functionPrototype);
447     markIfNeeded(d->arrayPrototype);
448     markIfNeeded(d->booleanPrototype);
449     markIfNeeded(d->stringPrototype);
450     markIfNeeded(d->numberPrototype);
451     markIfNeeded(d->datePrototype);
452     markIfNeeded(d->regExpPrototype);
453     markIfNeeded(d->errorPrototype);
454     markIfNeeded(d->evalErrorPrototype);
455     markIfNeeded(d->rangeErrorPrototype);
456     markIfNeeded(d->referenceErrorPrototype);
457     markIfNeeded(d->syntaxErrorPrototype);
458     markIfNeeded(d->typeErrorPrototype);
459     markIfNeeded(d->URIErrorPrototype);
460 }
461
462 ExecState* JSGlobalObject::globalExec()
463 {
464     return &d->globalExec;
465 }
466
467 } // namespace KJS