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