JavaScriptCore:
[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 #include <assert.h>
54 #include <math.h>
55 #include <stdio.h>
56
57 namespace KJS {
58
59 Interpreter* Interpreter::s_hook = 0;
60     
61 typedef HashMap<JSObject*, Interpreter*> InterpreterMap;
62 static inline InterpreterMap &interpreterMap()
63 {
64     static InterpreterMap* map = new InterpreterMap;
65     return* map;
66 }
67     
68 Interpreter::Interpreter(JSObject* globalObject)
69     : m_globalExec(this, 0)
70     , m_globalObject(globalObject)
71     , m_argumentsPropertyName(&argumentsPropertyName)
72     , m_specialPrototypePropertyName(&specialPrototypePropertyName)
73 {
74     init();
75 }
76
77 Interpreter::Interpreter()
78     : m_globalExec(this, 0)
79     , m_globalObject(new JSObject())
80     , m_argumentsPropertyName(&argumentsPropertyName)
81     , m_specialPrototypePropertyName(&specialPrototypePropertyName)
82 {
83     init();
84 }
85
86 void Interpreter::init()
87 {
88     JSLock lock;
89
90     m_recursion = 0;
91     m_debugger= 0;
92     m_context = 0;
93     m_compatMode = NativeMode;
94
95     interpreterMap().set(m_globalObject, this);
96
97     if (s_hook) {
98         prev = s_hook;
99         next = s_hook->next;
100         s_hook->next->prev = this;
101         s_hook->next = this;
102     } else {
103         // This is the first interpreter
104         s_hook = next = prev = this;
105     }
106     
107     initGlobalObject();
108 }
109
110 Interpreter::~Interpreter()
111 {
112     JSLock lock;
113     
114     if (m_debugger)
115         m_debugger->detach(this);
116
117     next->prev = prev;
118     prev->next = next;
119     s_hook = next;
120     if (s_hook == this)
121     {
122         // This was the last interpreter
123         s_hook = 0;
124     }
125     
126     interpreterMap().remove(m_globalObject);
127 }
128
129 JSObject* Interpreter::globalObject() const
130 {
131   return m_globalObject;
132 }
133
134 void Interpreter::initGlobalObject()
135 {
136     Identifier::init();
137
138     FunctionPrototype *funcProto = new FunctionPrototype(&m_globalExec);
139     m_FunctionPrototype = funcProto;
140     ObjectPrototype *objProto = new ObjectPrototype(&m_globalExec, funcProto);
141     m_ObjectPrototype = objProto;
142     funcProto->setPrototype(m_ObjectPrototype);
143     
144     ArrayPrototype *arrayProto = new ArrayPrototype(&m_globalExec, objProto);
145     m_ArrayPrototype = arrayProto;
146     StringPrototype *stringProto = new StringPrototype(&m_globalExec, objProto);
147     m_StringPrototype = stringProto;
148     BooleanPrototype *booleanProto = new BooleanPrototype(&m_globalExec, objProto, funcProto);
149     m_BooleanPrototype = booleanProto;
150     NumberPrototype *numberProto = new NumberPrototype(&m_globalExec, objProto, funcProto);
151     m_NumberPrototype = numberProto;
152     DatePrototype *dateProto = new DatePrototype(&m_globalExec, objProto);
153     m_DatePrototype = dateProto;
154     RegExpPrototype *regexpProto = new RegExpPrototype(&m_globalExec, objProto, funcProto);
155     m_RegExpPrototype = regexpProto;
156     ErrorPrototype *errorProto = new ErrorPrototype(&m_globalExec, objProto, funcProto);
157     m_ErrorPrototype = errorProto;
158     
159     JSObject* o = m_globalObject;
160     while (o->prototype()->isObject())
161         o = static_cast<JSObject*>(o->prototype());
162     o->setPrototype(m_ObjectPrototype);
163     
164     // Constructors (Object, Array, etc.)
165     m_Object = new ObjectObjectImp(&m_globalExec, objProto, funcProto);
166     m_Function = new FunctionObjectImp(&m_globalExec, funcProto);
167     m_Array = new ArrayObjectImp(&m_globalExec, funcProto, arrayProto);
168     m_String = new StringObjectImp(&m_globalExec, funcProto, stringProto);
169     m_Boolean = new BooleanObjectImp(&m_globalExec, funcProto, booleanProto);
170     m_Number = new NumberObjectImp(&m_globalExec, funcProto, numberProto);
171     m_Date = new DateObjectImp(&m_globalExec, funcProto, dateProto);
172     m_RegExp = new RegExpObjectImp(&m_globalExec, funcProto, regexpProto);
173     m_Error = new ErrorObjectImp(&m_globalExec, funcProto, errorProto);
174     
175     // Error object prototypes
176     m_EvalErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, EvalError, "EvalError", "EvalError");
177     m_RangeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, RangeError, "RangeError", "RangeError");
178     m_ReferenceErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
179     m_SyntaxErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
180     m_TypeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, TypeError, "TypeError", "TypeError");
181     m_UriErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, URIError, "URIError", "URIError");
182     
183     // Error objects
184     m_EvalError = new NativeErrorImp(&m_globalExec, funcProto, m_EvalErrorPrototype);
185     m_RangeError = new NativeErrorImp(&m_globalExec, funcProto, m_RangeErrorPrototype);
186     m_ReferenceError = new NativeErrorImp(&m_globalExec, funcProto, m_ReferenceErrorPrototype);
187     m_SyntaxError = new NativeErrorImp(&m_globalExec, funcProto, m_SyntaxErrorPrototype);
188     m_TypeError = new NativeErrorImp(&m_globalExec, funcProto, m_TypeErrorPrototype);
189     m_UriError = new NativeErrorImp(&m_globalExec, funcProto, m_UriErrorPrototype);
190     
191     // ECMA 15.3.4.1
192     funcProto->put(&m_globalExec, constructorPropertyName, m_Function, DontEnum);
193     
194     m_globalObject->put(&m_globalExec, "Object", m_Object, DontEnum);
195     m_globalObject->put(&m_globalExec, "Function", m_Function, DontEnum);
196     m_globalObject->put(&m_globalExec, "Array", m_Array, DontEnum);
197     m_globalObject->put(&m_globalExec, "Boolean", m_Boolean, DontEnum);
198     m_globalObject->put(&m_globalExec, "String", m_String, DontEnum);
199     m_globalObject->put(&m_globalExec, "Number", m_Number, DontEnum);
200     m_globalObject->put(&m_globalExec, "Date", m_Date, DontEnum);
201     m_globalObject->put(&m_globalExec, "RegExp", m_RegExp, DontEnum);
202     m_globalObject->put(&m_globalExec, "Error", m_Error, DontEnum);
203     // Using Internal for those to have something != 0
204     // (see kjs_window). Maybe DontEnum would be ok too ?
205     m_globalObject->put(&m_globalExec, "EvalError",m_EvalError, Internal);
206     m_globalObject->put(&m_globalExec, "RangeError",m_RangeError, Internal);
207     m_globalObject->put(&m_globalExec, "ReferenceError",m_ReferenceError, Internal);
208     m_globalObject->put(&m_globalExec, "SyntaxError",m_SyntaxError, Internal);
209     m_globalObject->put(&m_globalExec, "TypeError",m_TypeError, Internal);
210     m_globalObject->put(&m_globalExec, "URIError",m_UriError, Internal);
211     
212     // Set the constructorPropertyName property of all builtin constructors
213     objProto->put(&m_globalExec, constructorPropertyName, m_Object, DontEnum | DontDelete | ReadOnly);
214     funcProto->put(&m_globalExec, constructorPropertyName, m_Function, DontEnum | DontDelete | ReadOnly);
215     arrayProto->put(&m_globalExec, constructorPropertyName, m_Array, DontEnum | DontDelete | ReadOnly);
216     booleanProto->put(&m_globalExec, constructorPropertyName, m_Boolean, DontEnum | DontDelete | ReadOnly);
217     stringProto->put(&m_globalExec, constructorPropertyName, m_String, DontEnum | DontDelete | ReadOnly);
218     numberProto->put(&m_globalExec, constructorPropertyName, m_Number, DontEnum | DontDelete | ReadOnly);
219     dateProto->put(&m_globalExec, constructorPropertyName, m_Date, DontEnum | DontDelete | ReadOnly);
220     regexpProto->put(&m_globalExec, constructorPropertyName, m_RegExp, DontEnum | DontDelete | ReadOnly);
221     errorProto->put(&m_globalExec, constructorPropertyName, m_Error, DontEnum | DontDelete | ReadOnly);
222     m_EvalErrorPrototype->put(&m_globalExec, constructorPropertyName, m_EvalError, DontEnum | DontDelete | ReadOnly);
223     m_RangeErrorPrototype->put(&m_globalExec, constructorPropertyName, m_RangeError, DontEnum | DontDelete | ReadOnly);
224     m_ReferenceErrorPrototype->put(&m_globalExec, constructorPropertyName, m_ReferenceError, DontEnum | DontDelete | ReadOnly);
225     m_SyntaxErrorPrototype->put(&m_globalExec, constructorPropertyName, m_SyntaxError, DontEnum | DontDelete | ReadOnly);
226     m_TypeErrorPrototype->put(&m_globalExec, constructorPropertyName, m_TypeError, DontEnum | DontDelete | ReadOnly);
227     m_UriErrorPrototype->put(&m_globalExec, constructorPropertyName, m_UriError, DontEnum | DontDelete | ReadOnly);
228     
229     // built-in values
230     m_globalObject->put(&m_globalExec, "NaN",        jsNaN(), DontEnum|DontDelete);
231     m_globalObject->put(&m_globalExec, "Infinity",   jsNumber(Inf), DontEnum|DontDelete);
232     m_globalObject->put(&m_globalExec, "undefined",  jsUndefined(), DontEnum|DontDelete);
233     
234     // built-in functions
235     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
236     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
237     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
238     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
239     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
240     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
241     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
242     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
243     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
244     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
245     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
246 #ifndef NDEBUG
247     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
248 #endif
249     
250     // built-in objects
251     m_globalObject->put(&m_globalExec, "Math", new MathObjectImp(&m_globalExec, objProto), DontEnum);
252 }
253
254 ExecState* Interpreter::globalExec()
255 {
256   return &m_globalExec;
257 }
258
259 bool Interpreter::checkSyntax(const UString &code)
260 {
261     JSLock lock;
262     
263     // Parser::parse() returns 0 in a syntax error occurs
264     RefPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(), code.size(), 0, 0, 0);
265     return progNode;
266 }
267
268 Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue*)
269 {
270     return evaluate(sourceURL, startingLineNumber, code.data(), code.size());
271 }
272
273 Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
274 {
275     JSLock lock;
276     
277     // prevent against infinite recursion
278     if (m_recursion >= 20)
279         return Completion(Throw, Error::create(&m_globalExec, GeneralError, "Recursion too deep"));
280     
281     // parse the source code
282     int sid;
283     int errLine;
284     UString errMsg;
285     RefPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code, codeLength, &sid, &errLine, &errMsg);
286     
287     // notify debugger that source has been parsed
288     if (m_debugger) {
289         bool cont = m_debugger->sourceParsed(&m_globalExec, sid, sourceURL, UString(code, codeLength), errLine);
290         if (!cont)
291             return Completion(Break);
292     }
293     
294     // no program node means a syntax error occurred
295     if (!progNode)
296         return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, sid, &sourceURL));
297     
298     m_globalExec.clearException();
299     
300     m_recursion++;
301     
302     JSObject* globalObj = m_globalObject;
303     JSObject* thisObj = globalObj;
304     
305     // "this" must be an object... use same rules as Function.prototype.apply()
306     if (thisV && !thisV->isUndefinedOrNull())
307         thisObj = thisV->toObject(&m_globalExec);
308     
309     Completion res;
310     if (m_globalExec.hadException())
311         // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
312         res = Completion(Throw, m_globalExec.exception());
313     else {
314         // execute the code
315         Context ctx(globalObj, this, thisObj, progNode.get());
316         ExecState newExec(this, &ctx);
317         progNode->processVarDecls(&newExec);
318         res = progNode->execute(&newExec);
319     }
320     
321     m_recursion--;
322     
323     if (shouldPrintExceptions() && res.complType() == Throw) {
324         JSLock lock;
325         ExecState* exec = globalExec();
326         CString f = sourceURL.UTF8String();
327         CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
328         int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
329 #if PLATFORM(WIN_OS)
330         printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
331 #else
332         printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
333 #endif
334     }
335
336     return res;
337 }
338
339 JSObject *Interpreter::builtinObject() const
340 {
341   return m_Object;
342 }
343
344 JSObject *Interpreter::builtinFunction() const
345 {
346   return m_Function;
347 }
348
349 JSObject *Interpreter::builtinArray() const
350 {
351   return m_Array;
352 }
353
354 JSObject *Interpreter::builtinBoolean() const
355 {
356   return m_Boolean;
357 }
358
359 JSObject *Interpreter::builtinString() const
360 {
361   return m_String;
362 }
363
364 JSObject *Interpreter::builtinNumber() const
365 {
366   return m_Number;
367 }
368
369 JSObject *Interpreter::builtinDate() const
370 {
371   return m_Date;
372 }
373
374 JSObject *Interpreter::builtinRegExp() const
375 {
376   return m_RegExp;
377 }
378
379 JSObject *Interpreter::builtinError() const
380 {
381   return m_Error;
382 }
383
384 JSObject *Interpreter::builtinObjectPrototype() const
385 {
386   return m_ObjectPrototype;
387 }
388
389 JSObject *Interpreter::builtinFunctionPrototype() const
390 {
391   return m_FunctionPrototype;
392 }
393
394 JSObject *Interpreter::builtinArrayPrototype() const
395 {
396   return m_ArrayPrototype;
397 }
398
399 JSObject *Interpreter::builtinBooleanPrototype() const
400 {
401   return m_BooleanPrototype;
402 }
403
404 JSObject *Interpreter::builtinStringPrototype() const
405 {
406   return m_StringPrototype;
407 }
408
409 JSObject *Interpreter::builtinNumberPrototype() const
410 {
411   return m_NumberPrototype;
412 }
413
414 JSObject *Interpreter::builtinDatePrototype() const
415 {
416   return m_DatePrototype;
417 }
418
419 JSObject *Interpreter::builtinRegExpPrototype() const
420 {
421   return m_RegExpPrototype;
422 }
423
424 JSObject *Interpreter::builtinErrorPrototype() const
425 {
426   return m_ErrorPrototype;
427 }
428
429 JSObject *Interpreter::builtinEvalError() const
430 {
431   return m_EvalError;
432 }
433
434 JSObject *Interpreter::builtinRangeError() const
435 {
436   return m_RangeError;
437 }
438
439 JSObject *Interpreter::builtinReferenceError() const
440 {
441   return m_ReferenceError;
442 }
443
444 JSObject *Interpreter::builtinSyntaxError() const
445 {
446   return m_SyntaxError;
447 }
448
449 JSObject *Interpreter::builtinTypeError() const
450 {
451   return m_TypeError;
452 }
453
454 JSObject *Interpreter::builtinURIError() const
455 {
456   return m_UriError;
457 }
458
459 JSObject *Interpreter::builtinEvalErrorPrototype() const
460 {
461   return m_EvalErrorPrototype;
462 }
463
464 JSObject *Interpreter::builtinRangeErrorPrototype() const
465 {
466   return m_RangeErrorPrototype;
467 }
468
469 JSObject *Interpreter::builtinReferenceErrorPrototype() const
470 {
471   return m_ReferenceErrorPrototype;
472 }
473
474 JSObject *Interpreter::builtinSyntaxErrorPrototype() const
475 {
476   return m_SyntaxErrorPrototype;
477 }
478
479 JSObject *Interpreter::builtinTypeErrorPrototype() const
480 {
481   return m_TypeErrorPrototype;
482 }
483
484 JSObject *Interpreter::builtinURIErrorPrototype() const
485 {
486   return m_UriErrorPrototype;
487 }
488
489 bool Interpreter::collect()
490 {
491   return Collector::collect();
492 }
493
494 void Interpreter::mark(bool)
495 {
496     if (m_context)
497         m_context->mark();
498     if (m_globalObject && !m_globalObject->marked())
499         m_globalObject->mark();
500     if (m_globalExec.exception() && !m_globalExec.exception()->marked())
501         m_globalExec.exception()->mark();
502 }
503
504 Interpreter* Interpreter::interpreterWithGlobalObject(JSObject* globalObject)
505 {
506     return interpreterMap().get(globalObject);
507 }
508
509 #ifdef KJS_DEBUG_MEM
510 #include "lexer.h"
511 void Interpreter::finalCheck()
512 {
513   fprintf(stderr,"Interpreter::finalCheck()\n");
514   Collector::collect();
515
516   Node::finalCheck();
517   Collector::finalCheck();
518   Lexer::globalClear();
519   UString::globalClear();
520 }
521 #endif
522
523 static bool printExceptions = false;
524
525 bool Interpreter::shouldPrintExceptions()
526 {
527   return printExceptions;
528 }
529
530 void Interpreter::setShouldPrintExceptions(bool print)
531 {
532   printExceptions = print;
533 }
534
535 // bindings are OS X WebKit-only for now
536 #if PLATFORM(MAC)
537 void *Interpreter::createLanguageInstanceForValue(ExecState *exec, int language, JSObject *value, const Bindings::RootObject *origin, const Bindings::RootObject *current)
538 {
539     return Bindings::Instance::createLanguageInstanceForValue (exec, (Bindings::Instance::BindingLanguage)language, value, origin, current);
540 }
541 #endif
542
543 void Interpreter::saveBuiltins (SavedBuiltins& builtins) const
544 {
545     if (!builtins._internal)
546         builtins._internal = new SavedBuiltinsInternal;
547     
548     builtins._internal->m_Object = m_Object;
549     builtins._internal->m_Function = m_Function;
550     builtins._internal->m_Array = m_Array;
551     builtins._internal->m_Boolean = m_Boolean;
552     builtins._internal->m_String = m_String;
553     builtins._internal->m_Number = m_Number;
554     builtins._internal->m_Date = m_Date;
555     builtins._internal->m_RegExp = m_RegExp;
556     builtins._internal->m_Error = m_Error;
557     
558     builtins._internal->m_ObjectPrototype = m_ObjectPrototype;
559     builtins._internal->m_FunctionPrototype = m_FunctionPrototype;
560     builtins._internal->m_ArrayPrototype = m_ArrayPrototype;
561     builtins._internal->m_BooleanPrototype = m_BooleanPrototype;
562     builtins._internal->m_StringPrototype = m_StringPrototype;
563     builtins._internal->m_NumberPrototype = m_NumberPrototype;
564     builtins._internal->m_DatePrototype = m_DatePrototype;
565     builtins._internal->m_RegExpPrototype = m_RegExpPrototype;
566     builtins._internal->m_ErrorPrototype = m_ErrorPrototype;
567     
568     builtins._internal->m_EvalError = m_EvalError;
569     builtins._internal->m_RangeError = m_RangeError;
570     builtins._internal->m_ReferenceError = m_ReferenceError;
571     builtins._internal->m_SyntaxError = m_SyntaxError;
572     builtins._internal->m_TypeError = m_TypeError;
573     builtins._internal->m_UriError = m_UriError;
574     
575     builtins._internal->m_EvalErrorPrototype = m_EvalErrorPrototype;
576     builtins._internal->m_RangeErrorPrototype = m_RangeErrorPrototype;
577     builtins._internal->m_ReferenceErrorPrototype = m_ReferenceErrorPrototype;
578     builtins._internal->m_SyntaxErrorPrototype = m_SyntaxErrorPrototype;
579     builtins._internal->m_TypeErrorPrototype = m_TypeErrorPrototype;
580     builtins._internal->m_UriErrorPrototype = m_UriErrorPrototype;
581 }
582
583 void Interpreter::restoreBuiltins (const SavedBuiltins& builtins)
584 {
585     if (!builtins._internal)
586         return;
587
588     m_Object = builtins._internal->m_Object;
589     m_Function = builtins._internal->m_Function;
590     m_Array = builtins._internal->m_Array;
591     m_Boolean = builtins._internal->m_Boolean;
592     m_String = builtins._internal->m_String;
593     m_Number = builtins._internal->m_Number;
594     m_Date = builtins._internal->m_Date;
595     m_RegExp = builtins._internal->m_RegExp;
596     m_Error = builtins._internal->m_Error;
597     
598     m_ObjectPrototype = builtins._internal->m_ObjectPrototype;
599     m_FunctionPrototype = builtins._internal->m_FunctionPrototype;
600     m_ArrayPrototype = builtins._internal->m_ArrayPrototype;
601     m_BooleanPrototype = builtins._internal->m_BooleanPrototype;
602     m_StringPrototype = builtins._internal->m_StringPrototype;
603     m_NumberPrototype = builtins._internal->m_NumberPrototype;
604     m_DatePrototype = builtins._internal->m_DatePrototype;
605     m_RegExpPrototype = builtins._internal->m_RegExpPrototype;
606     m_ErrorPrototype = builtins._internal->m_ErrorPrototype;
607     
608     m_EvalError = builtins._internal->m_EvalError;
609     m_RangeError = builtins._internal->m_RangeError;
610     m_ReferenceError = builtins._internal->m_ReferenceError;
611     m_SyntaxError = builtins._internal->m_SyntaxError;
612     m_TypeError = builtins._internal->m_TypeError;
613     m_UriError = builtins._internal->m_UriError;
614     
615     m_EvalErrorPrototype = builtins._internal->m_EvalErrorPrototype;
616     m_RangeErrorPrototype = builtins._internal->m_RangeErrorPrototype;
617     m_ReferenceErrorPrototype = builtins._internal->m_ReferenceErrorPrototype;
618     m_SyntaxErrorPrototype = builtins._internal->m_SyntaxErrorPrototype;
619     m_TypeErrorPrototype = builtins._internal->m_TypeErrorPrototype;
620     m_UriErrorPrototype = builtins._internal->m_UriErrorPrototype;
621 }
622
623 SavedBuiltins::SavedBuiltins() : 
624   _internal(0)
625 {
626 }
627
628 SavedBuiltins::~SavedBuiltins()
629 {
630   delete _internal;
631 }
632
633 }