source: webkit/trunk/JavaScriptCore/kjs/JSGlobalObject.cpp@ 28474

Last change on this file since 28474 was 28474, checked in by [email protected], 17 years ago

Build fix: added some #includes.

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