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