source: webkit/trunk/JavaScriptCore/kjs/interpreter.cpp@ 17945

Last change on this file since 17945 was 17945, checked in by ggaren, 18 years ago

JavaScriptCore:

Reviewed by Beth Dakin.


Fixed up garbage collection at window close time.

  • kjs/interpreter.cpp: (KJS::Interpreter::~Interpreter): Garbage collect here, since destroying the interpreter frees the global object and therefore creates a lot of garbage.

WebCore:

Reviewed by Beth Dakin.


Fixed up garbage collection at window close time.

  • bindings/js/kjs_proxy.cpp: Don't garbage collect in the KJSProxy destructor, since the global object hasn't been freed yet.
  • bindings/js/kjs_proxy.h:
  • loader/FrameLoader.cpp: (WebCore::FrameLoader::detachFromParent): Made this function cross- platform.
  • loader/FrameLoader.h:
  • loader/mac/FrameLoaderMac.mm: (WebCore::FrameLoader::setTitle): Moved this function to FrameLoaderMac, since it's Mac-only. (WebCore::FrameLoader::closeBridge):
  • page/Page.cpp: (WebCore::Page::~Page): Don't garbage collect in the Page destructor, since the Interpreter destructor will do it for us.
  • Property svn:eol-style set to native
File size: 26.3 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2001 Harri Porten ([email protected])
5 * Copyright (C) 2001 Peter Kelly ([email protected])
6 * Copyright (C) 2003 Apple Computer, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#include "config.h"
26#include "interpreter.h"
27
28#include "SavedBuiltins.h"
29#include "array_object.h"
30#include "bool_object.h"
31#include "collector.h"
32#include "context.h"
33#include "date_object.h"
34#include "debugger.h"
35#include "error_object.h"
36#include "function_object.h"
37#include "internal.h"
38#include "math_object.h"
39#include "nodes.h"
40#include "number_object.h"
41#include "object.h"
42#include "object_object.h"
43#include "operations.h"
44#include "regexp_object.h"
45#include "string_object.h"
46#include "types.h"
47#include "value.h"
48
49#include "runtime.h"
50
51#if HAVE(SYS_TIME_H)
52#include <sys/time.h>
53#endif
54
55#include <assert.h>
56#include <math.h>
57#include <signal.h>
58#include <stdio.h>
59
60namespace KJS {
61
62class TimeoutChecker {
63public:
64 void startTimeoutCheck(Interpreter*);
65 void stopTimeoutCheck(Interpreter*);
66 void pauseTimeoutCheck(Interpreter*);
67 void resumeTimeoutCheck(Interpreter*);
68
69private:
70#if HAVE(SYS_TIME_H)
71 static Interpreter* s_executingInterpreter;
72 static void alarmHandler(int);
73
74 Interpreter* m_oldInterpreter;
75 itimerval m_oldtv;
76 itimerval m_pausetv;
77 void (*m_oldAlarmHandler)(int);
78#endif
79};
80
81#if HAVE(SYS_TIME_H)
82Interpreter* TimeoutChecker::s_executingInterpreter = 0;
83#endif
84
85void TimeoutChecker::startTimeoutCheck(Interpreter *interpreter)
86{
87 if (!interpreter->m_timeoutTime)
88 return;
89
90 interpreter->m_startTimeoutCheckCount++;
91
92#if HAVE(SYS_TIME_H)
93 if (s_executingInterpreter == interpreter)
94 return;
95
96 // Block signals
97 m_oldAlarmHandler = signal(SIGALRM, SIG_IGN);
98
99 m_oldInterpreter = s_executingInterpreter;
100 s_executingInterpreter = interpreter;
101
102 itimerval tv = {
103 { interpreter->m_timeoutTime / 1000, (interpreter->m_timeoutTime % 1000) * 1000 },
104 { interpreter->m_timeoutTime / 1000, (interpreter->m_timeoutTime % 1000) * 1000 }
105 };
106 setitimer(ITIMER_REAL, &tv, &m_oldtv);
107
108 // Unblock signals
109 signal(SIGALRM, alarmHandler);
110#endif
111}
112
113void TimeoutChecker::stopTimeoutCheck(Interpreter* interpreter)
114{
115 if (!interpreter->m_timeoutTime)
116 return;
117
118 ASSERT(interpreter->m_startTimeoutCheckCount > 0);
119
120 interpreter->m_startTimeoutCheckCount--;
121
122 if (interpreter->m_startTimeoutCheckCount != 0)
123 return;
124
125#if HAVE(SYS_TIME_H)
126 signal(SIGALRM, SIG_IGN);
127
128 s_executingInterpreter = m_oldInterpreter;
129
130 setitimer(ITIMER_REAL, &m_oldtv, 0L);
131 signal(SIGALRM, m_oldAlarmHandler);
132#endif
133}
134
135#if HAVE(SYS_TIME_H)
136void TimeoutChecker::alarmHandler(int)
137{
138 s_executingInterpreter->m_timedOut = true;
139}
140#endif
141
142void TimeoutChecker::pauseTimeoutCheck(Interpreter* interpreter)
143{
144 if (interpreter->m_startTimeoutCheckCount == 0)
145 return;
146
147#if HAVE(SYS_TIME_H)
148 ASSERT(interpreter == s_executingInterpreter);
149
150 void (*currentSignalHandler)(int);
151
152 // Block signal
153 currentSignalHandler = signal(SIGALRM, SIG_IGN);
154
155 if (currentSignalHandler != alarmHandler) {
156 signal(SIGALRM, currentSignalHandler);
157 return;
158 }
159
160 setitimer(ITIMER_REAL, 0L, &m_pausetv);
161#endif
162
163 interpreter->m_pauseTimeoutCheckCount++;
164}
165
166void TimeoutChecker::resumeTimeoutCheck(Interpreter* interpreter)
167{
168 if (interpreter->m_startTimeoutCheckCount == 0)
169 return;
170
171#if HAVE(SYS_TIME_H)
172 ASSERT(interpreter == s_executingInterpreter);
173#endif
174
175 interpreter->m_pauseTimeoutCheckCount--;
176
177 if (interpreter->m_pauseTimeoutCheckCount != 0)
178 return;
179
180#if HAVE(SYS_TIME_H)
181 void (*currentSignalHandler)(int);
182
183 // Check so we have the right handler
184 currentSignalHandler = signal(SIGALRM, SIG_IGN);
185
186 if (currentSignalHandler != SIG_IGN) {
187 signal(SIGALRM, currentSignalHandler);
188 return;
189 }
190
191 setitimer(ITIMER_REAL, &m_pausetv, 0L);
192
193 // Unblock signal
194 currentSignalHandler = signal(SIGALRM, alarmHandler);
195#endif
196}
197
198Interpreter* Interpreter::s_hook = 0;
199
200typedef HashMap<JSObject*, Interpreter*> InterpreterMap;
201static inline InterpreterMap &interpreterMap()
202{
203 static InterpreterMap* map = new InterpreterMap;
204 return* map;
205}
206
207Interpreter::Interpreter(JSObject* globalObject)
208 : m_globalExec(this, 0)
209 , m_globalObject(globalObject)
210{
211 init();
212}
213
214Interpreter::Interpreter()
215 : m_globalExec(this, 0)
216 , m_globalObject(new JSObject())
217{
218 init();
219}
220
221void Interpreter::init()
222{
223 JSLock lock;
224
225 m_refCount = 0;
226 m_timeoutTime = 0;
227 m_recursion = 0;
228 m_debugger= 0;
229 m_context = 0;
230 m_timedOut = false;
231 m_timeoutChecker = 0;
232 m_startTimeoutCheckCount = 0;
233 m_pauseTimeoutCheckCount = 0;
234 m_compatMode = NativeMode;
235 m_argumentsPropertyName = &argumentsPropertyName;
236 m_specialPrototypePropertyName = &specialPrototypePropertyName;
237
238 interpreterMap().set(m_globalObject, this);
239
240 if (s_hook) {
241 prev = s_hook;
242 next = s_hook->next;
243 s_hook->next->prev = this;
244 s_hook->next = this;
245 } else {
246 // This is the first interpreter
247 s_hook = next = prev = this;
248 }
249
250 initGlobalObject();
251}
252
253Interpreter::~Interpreter()
254{
255 JSLock lock;
256
257 ASSERT (m_startTimeoutCheckCount == 0);
258 ASSERT (m_pauseTimeoutCheckCount == 0);
259
260 delete m_timeoutChecker;
261
262 if (m_debugger)
263 m_debugger->detach(this);
264
265 next->prev = prev;
266 prev->next = next;
267 s_hook = next;
268 if (s_hook == this)
269 {
270 // This was the last interpreter
271 s_hook = 0;
272 }
273
274 interpreterMap().remove(m_globalObject);
275
276 // It's likely that destroying the interpreter has created a lot of garbage.
277 Collector::collect();
278}
279
280JSObject* Interpreter::globalObject() const
281{
282 return m_globalObject;
283}
284
285void Interpreter::initGlobalObject()
286{
287 Identifier::init();
288
289 FunctionPrototype *funcProto = new FunctionPrototype(&m_globalExec);
290 m_FunctionPrototype = funcProto;
291 ObjectPrototype *objProto = new ObjectPrototype(&m_globalExec, funcProto);
292 m_ObjectPrototype = objProto;
293 funcProto->setPrototype(m_ObjectPrototype);
294
295 ArrayPrototype *arrayProto = new ArrayPrototype(&m_globalExec, objProto);
296 m_ArrayPrototype = arrayProto;
297 StringPrototype *stringProto = new StringPrototype(&m_globalExec, objProto);
298 m_StringPrototype = stringProto;
299 BooleanPrototype *booleanProto = new BooleanPrototype(&m_globalExec, objProto, funcProto);
300 m_BooleanPrototype = booleanProto;
301 NumberPrototype *numberProto = new NumberPrototype(&m_globalExec, objProto, funcProto);
302 m_NumberPrototype = numberProto;
303 DatePrototype *dateProto = new DatePrototype(&m_globalExec, objProto);
304 m_DatePrototype = dateProto;
305 RegExpPrototype *regexpProto = new RegExpPrototype(&m_globalExec, objProto, funcProto);
306 m_RegExpPrototype = regexpProto;
307 ErrorPrototype *errorProto = new ErrorPrototype(&m_globalExec, objProto, funcProto);
308 m_ErrorPrototype = errorProto;
309
310 JSObject* o = m_globalObject;
311 while (o->prototype()->isObject())
312 o = static_cast<JSObject*>(o->prototype());
313 o->setPrototype(m_ObjectPrototype);
314
315 // Constructors (Object, Array, etc.)
316 m_Object = new ObjectObjectImp(&m_globalExec, objProto, funcProto);
317 m_Function = new FunctionObjectImp(&m_globalExec, funcProto);
318 m_Array = new ArrayObjectImp(&m_globalExec, funcProto, arrayProto);
319 m_String = new StringObjectImp(&m_globalExec, funcProto, stringProto);
320 m_Boolean = new BooleanObjectImp(&m_globalExec, funcProto, booleanProto);
321 m_Number = new NumberObjectImp(&m_globalExec, funcProto, numberProto);
322 m_Date = new DateObjectImp(&m_globalExec, funcProto, dateProto);
323 m_RegExp = new RegExpObjectImp(&m_globalExec, funcProto, regexpProto);
324 m_Error = new ErrorObjectImp(&m_globalExec, funcProto, errorProto);
325
326 // Error object prototypes
327 m_EvalErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, EvalError, "EvalError", "EvalError");
328 m_RangeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, RangeError, "RangeError", "RangeError");
329 m_ReferenceErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
330 m_SyntaxErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
331 m_TypeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, TypeError, "TypeError", "TypeError");
332 m_UriErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, URIError, "URIError", "URIError");
333
334 // Error objects
335 m_EvalError = new NativeErrorImp(&m_globalExec, funcProto, m_EvalErrorPrototype);
336 m_RangeError = new NativeErrorImp(&m_globalExec, funcProto, m_RangeErrorPrototype);
337 m_ReferenceError = new NativeErrorImp(&m_globalExec, funcProto, m_ReferenceErrorPrototype);
338 m_SyntaxError = new NativeErrorImp(&m_globalExec, funcProto, m_SyntaxErrorPrototype);
339 m_TypeError = new NativeErrorImp(&m_globalExec, funcProto, m_TypeErrorPrototype);
340 m_UriError = new NativeErrorImp(&m_globalExec, funcProto, m_UriErrorPrototype);
341
342 // ECMA 15.3.4.1
343 funcProto->put(&m_globalExec, constructorPropertyName, m_Function, DontEnum);
344
345 m_globalObject->put(&m_globalExec, "Object", m_Object, DontEnum);
346 m_globalObject->put(&m_globalExec, "Function", m_Function, DontEnum);
347 m_globalObject->put(&m_globalExec, "Array", m_Array, DontEnum);
348 m_globalObject->put(&m_globalExec, "Boolean", m_Boolean, DontEnum);
349 m_globalObject->put(&m_globalExec, "String", m_String, DontEnum);
350 m_globalObject->put(&m_globalExec, "Number", m_Number, DontEnum);
351 m_globalObject->put(&m_globalExec, "Date", m_Date, DontEnum);
352 m_globalObject->put(&m_globalExec, "RegExp", m_RegExp, DontEnum);
353 m_globalObject->put(&m_globalExec, "Error", m_Error, DontEnum);
354 // Using Internal for those to have something != 0
355 // (see kjs_window). Maybe DontEnum would be ok too ?
356 m_globalObject->put(&m_globalExec, "EvalError",m_EvalError, Internal);
357 m_globalObject->put(&m_globalExec, "RangeError",m_RangeError, Internal);
358 m_globalObject->put(&m_globalExec, "ReferenceError",m_ReferenceError, Internal);
359 m_globalObject->put(&m_globalExec, "SyntaxError",m_SyntaxError, Internal);
360 m_globalObject->put(&m_globalExec, "TypeError",m_TypeError, Internal);
361 m_globalObject->put(&m_globalExec, "URIError",m_UriError, Internal);
362
363 // Set the constructorPropertyName property of all builtin constructors
364 objProto->put(&m_globalExec, constructorPropertyName, m_Object, DontEnum | DontDelete | ReadOnly);
365 funcProto->put(&m_globalExec, constructorPropertyName, m_Function, DontEnum | DontDelete | ReadOnly);
366 arrayProto->put(&m_globalExec, constructorPropertyName, m_Array, DontEnum | DontDelete | ReadOnly);
367 booleanProto->put(&m_globalExec, constructorPropertyName, m_Boolean, DontEnum | DontDelete | ReadOnly);
368 stringProto->put(&m_globalExec, constructorPropertyName, m_String, DontEnum | DontDelete | ReadOnly);
369 numberProto->put(&m_globalExec, constructorPropertyName, m_Number, DontEnum | DontDelete | ReadOnly);
370 dateProto->put(&m_globalExec, constructorPropertyName, m_Date, DontEnum | DontDelete | ReadOnly);
371 regexpProto->put(&m_globalExec, constructorPropertyName, m_RegExp, DontEnum | DontDelete | ReadOnly);
372 errorProto->put(&m_globalExec, constructorPropertyName, m_Error, DontEnum | DontDelete | ReadOnly);
373 m_EvalErrorPrototype->put(&m_globalExec, constructorPropertyName, m_EvalError, DontEnum | DontDelete | ReadOnly);
374 m_RangeErrorPrototype->put(&m_globalExec, constructorPropertyName, m_RangeError, DontEnum | DontDelete | ReadOnly);
375 m_ReferenceErrorPrototype->put(&m_globalExec, constructorPropertyName, m_ReferenceError, DontEnum | DontDelete | ReadOnly);
376 m_SyntaxErrorPrototype->put(&m_globalExec, constructorPropertyName, m_SyntaxError, DontEnum | DontDelete | ReadOnly);
377 m_TypeErrorPrototype->put(&m_globalExec, constructorPropertyName, m_TypeError, DontEnum | DontDelete | ReadOnly);
378 m_UriErrorPrototype->put(&m_globalExec, constructorPropertyName, m_UriError, DontEnum | DontDelete | ReadOnly);
379
380 // built-in values
381 m_globalObject->put(&m_globalExec, "NaN", jsNaN(), DontEnum|DontDelete);
382 m_globalObject->put(&m_globalExec, "Infinity", jsNumber(Inf), DontEnum|DontDelete);
383 m_globalObject->put(&m_globalExec, "undefined", jsUndefined(), DontEnum|DontDelete);
384
385 // built-in functions
386 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
387 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
388 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
389 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
390 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
391 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
392 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
393 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
394 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
395 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
396 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
397#ifndef NDEBUG
398 m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
399#endif
400
401 // built-in objects
402 m_globalObject->put(&m_globalExec, "Math", new MathObjectImp(&m_globalExec, objProto), DontEnum);
403}
404
405ExecState* Interpreter::globalExec()
406{
407 return &m_globalExec;
408}
409
410Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UString& code)
411{
412 return checkSyntax(sourceURL, startingLineNumber, code.data(), code.size());
413}
414
415Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength)
416{
417 JSLock lock;
418
419 int errLine;
420 UString errMsg;
421 RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
422 if (!progNode)
423 return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, 0, sourceURL));
424 return Completion(Normal);
425}
426
427Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
428{
429 return evaluate(sourceURL, startingLineNumber, code.data(), code.size(), thisV);
430}
431
432Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
433{
434 JSLock lock;
435
436 // prevent against infinite recursion
437 if (m_recursion >= 20)
438 return Completion(Throw, Error::create(&m_globalExec, GeneralError, "Recursion too deep"));
439
440 // parse the source code
441 int sid;
442 int errLine;
443 UString errMsg;
444 RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
445
446 // notify debugger that source has been parsed
447 if (m_debugger) {
448 bool cont = m_debugger->sourceParsed(&m_globalExec, sid, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
449 if (!cont)
450 return Completion(Break);
451 }
452
453 // no program node means a syntax error occurred
454 if (!progNode)
455 return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, sid, sourceURL));
456
457 m_globalExec.clearException();
458
459 m_recursion++;
460
461 JSObject* globalObj = m_globalObject;
462 JSObject* thisObj = globalObj;
463
464 // "this" must be an object... use same rules as Function.prototype.apply()
465 if (thisV && !thisV->isUndefinedOrNull())
466 thisObj = thisV->toObject(&m_globalExec);
467
468 Completion res;
469 if (m_globalExec.hadException())
470 // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
471 res = Completion(Throw, m_globalExec.exception());
472 else {
473 // execute the code
474 Context ctx(globalObj, this, thisObj, progNode.get());
475 ExecState newExec(this, &ctx);
476 ctx.setExecState(&newExec);
477 progNode->processVarDecls(&newExec);
478 res = progNode->execute(&newExec);
479 }
480
481 m_recursion--;
482
483 if (shouldPrintExceptions() && res.complType() == Throw) {
484 JSLock lock;
485 ExecState* exec = globalExec();
486 CString f = sourceURL.UTF8String();
487 CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
488 int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
489#if PLATFORM(WIN_OS)
490 printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
491#else
492 printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
493#endif
494 }
495
496 return res;
497}
498
499JSObject *Interpreter::builtinObject() const
500{
501 return m_Object;
502}
503
504JSObject *Interpreter::builtinFunction() const
505{
506 return m_Function;
507}
508
509JSObject *Interpreter::builtinArray() const
510{
511 return m_Array;
512}
513
514JSObject *Interpreter::builtinBoolean() const
515{
516 return m_Boolean;
517}
518
519JSObject *Interpreter::builtinString() const
520{
521 return m_String;
522}
523
524JSObject *Interpreter::builtinNumber() const
525{
526 return m_Number;
527}
528
529JSObject *Interpreter::builtinDate() const
530{
531 return m_Date;
532}
533
534JSObject *Interpreter::builtinRegExp() const
535{
536 return m_RegExp;
537}
538
539JSObject *Interpreter::builtinError() const
540{
541 return m_Error;
542}
543
544JSObject *Interpreter::builtinObjectPrototype() const
545{
546 return m_ObjectPrototype;
547}
548
549JSObject *Interpreter::builtinFunctionPrototype() const
550{
551 return m_FunctionPrototype;
552}
553
554JSObject *Interpreter::builtinArrayPrototype() const
555{
556 return m_ArrayPrototype;
557}
558
559JSObject *Interpreter::builtinBooleanPrototype() const
560{
561 return m_BooleanPrototype;
562}
563
564JSObject *Interpreter::builtinStringPrototype() const
565{
566 return m_StringPrototype;
567}
568
569JSObject *Interpreter::builtinNumberPrototype() const
570{
571 return m_NumberPrototype;
572}
573
574JSObject *Interpreter::builtinDatePrototype() const
575{
576 return m_DatePrototype;
577}
578
579JSObject *Interpreter::builtinRegExpPrototype() const
580{
581 return m_RegExpPrototype;
582}
583
584JSObject *Interpreter::builtinErrorPrototype() const
585{
586 return m_ErrorPrototype;
587}
588
589JSObject *Interpreter::builtinEvalError() const
590{
591 return m_EvalError;
592}
593
594JSObject *Interpreter::builtinRangeError() const
595{
596 return m_RangeError;
597}
598
599JSObject *Interpreter::builtinReferenceError() const
600{
601 return m_ReferenceError;
602}
603
604JSObject *Interpreter::builtinSyntaxError() const
605{
606 return m_SyntaxError;
607}
608
609JSObject *Interpreter::builtinTypeError() const
610{
611 return m_TypeError;
612}
613
614JSObject *Interpreter::builtinURIError() const
615{
616 return m_UriError;
617}
618
619JSObject *Interpreter::builtinEvalErrorPrototype() const
620{
621 return m_EvalErrorPrototype;
622}
623
624JSObject *Interpreter::builtinRangeErrorPrototype() const
625{
626 return m_RangeErrorPrototype;
627}
628
629JSObject *Interpreter::builtinReferenceErrorPrototype() const
630{
631 return m_ReferenceErrorPrototype;
632}
633
634JSObject *Interpreter::builtinSyntaxErrorPrototype() const
635{
636 return m_SyntaxErrorPrototype;
637}
638
639JSObject *Interpreter::builtinTypeErrorPrototype() const
640{
641 return m_TypeErrorPrototype;
642}
643
644JSObject *Interpreter::builtinURIErrorPrototype() const
645{
646 return m_UriErrorPrototype;
647}
648
649bool Interpreter::collect()
650{
651 return Collector::collect();
652}
653
654void Interpreter::mark(bool)
655{
656 if (m_context)
657 m_context->mark();
658 if (m_globalObject && !m_globalObject->marked())
659 m_globalObject->mark();
660 if (m_globalExec.exception() && !m_globalExec.exception()->marked())
661 m_globalExec.exception()->mark();
662}
663
664Interpreter* Interpreter::interpreterWithGlobalObject(JSObject* globalObject)
665{
666 return interpreterMap().get(globalObject);
667}
668
669#ifdef KJS_DEBUG_MEM
670#include "lexer.h"
671void Interpreter::finalCheck()
672{
673 fprintf(stderr,"Interpreter::finalCheck()\n");
674 Collector::collect();
675
676 Node::finalCheck();
677 Collector::finalCheck();
678 Lexer::globalClear();
679 UString::globalClear();
680}
681#endif
682
683static bool printExceptions = false;
684
685bool Interpreter::shouldPrintExceptions()
686{
687 return printExceptions;
688}
689
690void Interpreter::setShouldPrintExceptions(bool print)
691{
692 printExceptions = print;
693}
694
695void *Interpreter::createLanguageInstanceForValue(ExecState *exec, int language, JSObject *value, const Bindings::RootObject *origin, const Bindings::RootObject *current)
696{
697 return Bindings::Instance::createLanguageInstanceForValue (exec, (Bindings::Instance::BindingLanguage)language, value, origin, current);
698}
699
700void Interpreter::saveBuiltins (SavedBuiltins& builtins) const
701{
702 if (!builtins._internal)
703 builtins._internal = new SavedBuiltinsInternal;
704
705 builtins._internal->m_Object = m_Object;
706 builtins._internal->m_Function = m_Function;
707 builtins._internal->m_Array = m_Array;
708 builtins._internal->m_Boolean = m_Boolean;
709 builtins._internal->m_String = m_String;
710 builtins._internal->m_Number = m_Number;
711 builtins._internal->m_Date = m_Date;
712 builtins._internal->m_RegExp = m_RegExp;
713 builtins._internal->m_Error = m_Error;
714
715 builtins._internal->m_ObjectPrototype = m_ObjectPrototype;
716 builtins._internal->m_FunctionPrototype = m_FunctionPrototype;
717 builtins._internal->m_ArrayPrototype = m_ArrayPrototype;
718 builtins._internal->m_BooleanPrototype = m_BooleanPrototype;
719 builtins._internal->m_StringPrototype = m_StringPrototype;
720 builtins._internal->m_NumberPrototype = m_NumberPrototype;
721 builtins._internal->m_DatePrototype = m_DatePrototype;
722 builtins._internal->m_RegExpPrototype = m_RegExpPrototype;
723 builtins._internal->m_ErrorPrototype = m_ErrorPrototype;
724
725 builtins._internal->m_EvalError = m_EvalError;
726 builtins._internal->m_RangeError = m_RangeError;
727 builtins._internal->m_ReferenceError = m_ReferenceError;
728 builtins._internal->m_SyntaxError = m_SyntaxError;
729 builtins._internal->m_TypeError = m_TypeError;
730 builtins._internal->m_UriError = m_UriError;
731
732 builtins._internal->m_EvalErrorPrototype = m_EvalErrorPrototype;
733 builtins._internal->m_RangeErrorPrototype = m_RangeErrorPrototype;
734 builtins._internal->m_ReferenceErrorPrototype = m_ReferenceErrorPrototype;
735 builtins._internal->m_SyntaxErrorPrototype = m_SyntaxErrorPrototype;
736 builtins._internal->m_TypeErrorPrototype = m_TypeErrorPrototype;
737 builtins._internal->m_UriErrorPrototype = m_UriErrorPrototype;
738}
739
740void Interpreter::restoreBuiltins (const SavedBuiltins& builtins)
741{
742 if (!builtins._internal)
743 return;
744
745 m_Object = builtins._internal->m_Object;
746 m_Function = builtins._internal->m_Function;
747 m_Array = builtins._internal->m_Array;
748 m_Boolean = builtins._internal->m_Boolean;
749 m_String = builtins._internal->m_String;
750 m_Number = builtins._internal->m_Number;
751 m_Date = builtins._internal->m_Date;
752 m_RegExp = builtins._internal->m_RegExp;
753 m_Error = builtins._internal->m_Error;
754
755 m_ObjectPrototype = builtins._internal->m_ObjectPrototype;
756 m_FunctionPrototype = builtins._internal->m_FunctionPrototype;
757 m_ArrayPrototype = builtins._internal->m_ArrayPrototype;
758 m_BooleanPrototype = builtins._internal->m_BooleanPrototype;
759 m_StringPrototype = builtins._internal->m_StringPrototype;
760 m_NumberPrototype = builtins._internal->m_NumberPrototype;
761 m_DatePrototype = builtins._internal->m_DatePrototype;
762 m_RegExpPrototype = builtins._internal->m_RegExpPrototype;
763 m_ErrorPrototype = builtins._internal->m_ErrorPrototype;
764
765 m_EvalError = builtins._internal->m_EvalError;
766 m_RangeError = builtins._internal->m_RangeError;
767 m_ReferenceError = builtins._internal->m_ReferenceError;
768 m_SyntaxError = builtins._internal->m_SyntaxError;
769 m_TypeError = builtins._internal->m_TypeError;
770 m_UriError = builtins._internal->m_UriError;
771
772 m_EvalErrorPrototype = builtins._internal->m_EvalErrorPrototype;
773 m_RangeErrorPrototype = builtins._internal->m_RangeErrorPrototype;
774 m_ReferenceErrorPrototype = builtins._internal->m_ReferenceErrorPrototype;
775 m_SyntaxErrorPrototype = builtins._internal->m_SyntaxErrorPrototype;
776 m_TypeErrorPrototype = builtins._internal->m_TypeErrorPrototype;
777 m_UriErrorPrototype = builtins._internal->m_UriErrorPrototype;
778}
779
780void Interpreter::startTimeoutCheck()
781{
782 if (!m_timeoutChecker)
783 m_timeoutChecker = new TimeoutChecker;
784
785 m_timeoutChecker->startTimeoutCheck(this);
786}
787
788void Interpreter::stopTimeoutCheck()
789{
790 ASSERT(m_timeoutChecker);
791
792 m_timeoutChecker->stopTimeoutCheck(this);
793}
794
795void Interpreter::pauseTimeoutCheck()
796{
797 ASSERT(m_timeoutChecker);
798
799 m_timeoutChecker->pauseTimeoutCheck(this);
800}
801
802void Interpreter::resumeTimeoutCheck()
803{
804 ASSERT(m_timeoutChecker);
805
806 m_timeoutChecker->resumeTimeoutCheck(this);
807}
808
809bool Interpreter::handleTimeout()
810{
811 m_timedOut = false;
812
813 pauseTimeoutCheck();
814 bool retval = shouldInterruptScript();
815 resumeTimeoutCheck();
816
817 return retval;
818}
819
820
821SavedBuiltins::SavedBuiltins() :
822 _internal(0)
823{
824}
825
826SavedBuiltins::~SavedBuiltins()
827{
828 delete _internal;
829}
830
831}
Note: See TracBrowser for help on using the repository browser.