File indexing completed on 2024-05-12 15:43:23

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
0004  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
0005  *  Copyright (C) 2003 Apple Computer, Inc.
0006  *  Copyright (C) 2008, 2009 Maksim Orlovich (maksim@kde.org)
0007  *
0008  *  This library is free software; you can redistribute it and/or
0009  *  modify it under the terms of the GNU Library General Public
0010  *  License as published by the Free Software Foundation; either
0011  *  version 2 of the License, or (at your option) any later version.
0012  *
0013  *  This library is distributed in the hope that it will be useful,
0014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  *  Library General Public License for more details.
0017  *
0018  *  You should have received a copy of the GNU Library General Public License
0019  *  along with this library; see the file COPYING.LIB.  If not, write to
0020  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  *  Boston, MA 02110-1301, USA.
0022  *
0023  */
0024 
0025 #include "interpreter.h"
0026 
0027 #include "SavedBuiltins.h"
0028 #include "array_object.h"
0029 #include "bool_object.h"
0030 #include "collector.h"
0031 #include "date_object.h"
0032 #include "debugger.h"
0033 #include "error_object.h"
0034 #include "function_object.h"
0035 #include "internal.h"
0036 #include "math_object.h"
0037 #include "nodes.h"
0038 #include "number_object.h"
0039 #include "object.h"
0040 #include "object_object.h"
0041 #include "operations.h"
0042 #include "regexp_object.h"
0043 #include "string_object.h"
0044 #include "lexer.h"
0045 #include "json_object.h"
0046 
0047 #if USE(BINDINGS)
0048 #include "runtime.h"
0049 #endif
0050 
0051 #if defined _WIN32 || defined _WIN64
0052 #define HAVE_SYS_TIME_H 0 // no setitimer in kdewin32
0053 #endif
0054 #if HAVE_SYS_TIME_H
0055 #include <sys/time.h>
0056 #endif
0057 
0058 #include <assert.h>
0059 #include <cstdlib>
0060 #include <math.h>
0061 #include <signal.h>
0062 #include <stdio.h>
0063 #if HAVE_UNISTD_H
0064 #include <unistd.h>
0065 #endif
0066 
0067 namespace KJS
0068 {
0069 
0070 class TimeoutChecker
0071 {
0072 public:
0073     void startTimeoutCheck(Interpreter *);
0074     void stopTimeoutCheck(Interpreter *);
0075     void pauseTimeoutCheck(Interpreter *);
0076     void resumeTimeoutCheck(Interpreter *);
0077 
0078 private:
0079 #if HAVE_SYS_TIME_H
0080     static Interpreter *s_executingInterpreter;
0081     static void alarmHandler(int);
0082 
0083     Interpreter *m_oldInterpreter;
0084     itimerval m_oldtv;
0085     itimerval m_pausetv;
0086     void (*m_oldAlarmHandler)(int);
0087 #endif
0088 };
0089 
0090 #if HAVE_SYS_TIME_H
0091 Interpreter *TimeoutChecker::s_executingInterpreter = nullptr;
0092 #endif
0093 
0094 void TimeoutChecker::startTimeoutCheck(Interpreter *interpreter)
0095 {
0096     if (!interpreter->m_timeoutTime) {
0097         return;
0098     }
0099 
0100     interpreter->m_startTimeoutCheckCount++;
0101 
0102 #if HAVE_SYS_TIME_H
0103     if (s_executingInterpreter == interpreter) {
0104         return;
0105     }
0106 
0107     // Block signals
0108     m_oldAlarmHandler = signal(SIGALRM, SIG_IGN);
0109 
0110     m_oldInterpreter = s_executingInterpreter;
0111     s_executingInterpreter = interpreter;
0112 
0113     itimerval tv = {
0114         { time_t(interpreter->m_timeoutTime / 1000),
0115           suseconds_t((interpreter->m_timeoutTime % 1000) * 1000) },
0116         { time_t(interpreter->m_timeoutTime / 1000),
0117           suseconds_t((interpreter->m_timeoutTime % 1000) * 1000) }
0118     };
0119     setitimer(ITIMER_REAL, &tv, &m_oldtv);
0120 
0121     // Unblock signals
0122     signal(SIGALRM, alarmHandler);
0123 #endif
0124 }
0125 
0126 void TimeoutChecker::stopTimeoutCheck(Interpreter *interpreter)
0127 {
0128     if (!interpreter->m_timeoutTime) {
0129         return;
0130     }
0131 
0132     ASSERT(interpreter->m_startTimeoutCheckCount > 0);
0133 
0134     interpreter->m_startTimeoutCheckCount--;
0135 
0136     if (interpreter->m_startTimeoutCheckCount != 0) {
0137         return;
0138     }
0139 
0140 #if HAVE_SYS_TIME_H
0141     signal(SIGALRM, SIG_IGN);
0142 
0143     s_executingInterpreter = m_oldInterpreter;
0144 
0145     setitimer(ITIMER_REAL, &m_oldtv, nullptr);
0146     signal(SIGALRM, m_oldAlarmHandler);
0147 #endif
0148 }
0149 
0150 #if HAVE_SYS_TIME_H
0151 void TimeoutChecker::alarmHandler(int)
0152 {
0153     s_executingInterpreter->m_timedOut = true;
0154 }
0155 #endif
0156 
0157 void TimeoutChecker::pauseTimeoutCheck(Interpreter *interpreter)
0158 {
0159     if (interpreter->m_startTimeoutCheckCount == 0) {
0160         return;
0161     }
0162 
0163 #if HAVE_SYS_TIME_H
0164     ASSERT(interpreter == s_executingInterpreter);
0165 
0166     void (*currentSignalHandler)(int);
0167 
0168     // Block signal
0169     currentSignalHandler = signal(SIGALRM, SIG_IGN);
0170 
0171     if (currentSignalHandler != alarmHandler) {
0172         signal(SIGALRM, currentSignalHandler);
0173         return;
0174     }
0175 
0176     getitimer(ITIMER_REAL, &m_pausetv);
0177 #endif
0178 
0179     interpreter->m_pauseTimeoutCheckCount++;
0180 }
0181 
0182 void TimeoutChecker::resumeTimeoutCheck(Interpreter *interpreter)
0183 {
0184     if (interpreter->m_startTimeoutCheckCount == 0) {
0185         return;
0186     }
0187 
0188 #if HAVE_SYS_TIME_H
0189     ASSERT(interpreter == s_executingInterpreter);
0190 #endif
0191 
0192     interpreter->m_pauseTimeoutCheckCount--;
0193 
0194     if (interpreter->m_pauseTimeoutCheckCount != 0) {
0195         return;
0196     }
0197 
0198 #if HAVE_SYS_TIME_H
0199     void (*currentSignalHandler)(int);
0200 
0201     // Check so we have the right handler
0202     currentSignalHandler = signal(SIGALRM, SIG_IGN);
0203 
0204     if (currentSignalHandler != SIG_IGN) {
0205         signal(SIGALRM, currentSignalHandler);
0206         return;
0207     }
0208 
0209     setitimer(ITIMER_REAL, &m_pausetv, nullptr);
0210 
0211     // Unblock signal
0212     currentSignalHandler = signal(SIGALRM, alarmHandler);
0213 #endif
0214 }
0215 
0216 Interpreter *Interpreter::s_hook = nullptr;
0217 
0218 Interpreter::Interpreter(JSGlobalObject *globalObject)
0219     : m_globalObject(globalObject),
0220       m_globalExec(this, globalObject),
0221       globPkg(nullptr)
0222 {
0223     init();
0224 }
0225 
0226 Interpreter::Interpreter()
0227     : m_globalObject(new JSGlobalObject()),
0228       m_globalExec(this, m_globalObject),
0229       globPkg(nullptr)
0230 {
0231     init();
0232 }
0233 
0234 void Interpreter::init()
0235 {
0236     JSLock lock;
0237 
0238     initInternedStringsTable();
0239 
0240     m_refCount = 0;
0241     m_timeoutTime = 0;
0242     m_recursion = 0;
0243     m_debugger = nullptr;
0244     m_execState = nullptr;
0245     m_timedOut = false;
0246     m_timeoutChecker = nullptr;
0247     m_startTimeoutCheckCount = 0;
0248     m_pauseTimeoutCheckCount = 0;
0249     m_compatMode = NativeMode;
0250 
0251     const int initialStackSize = 8192;
0252     stackBase = (unsigned char *)std::malloc(initialStackSize);
0253     stackPtr  = stackBase;
0254     stackEnd  = stackBase + initialStackSize;
0255 
0256     m_numCachedActivations = 0;
0257 
0258     m_globalObject->setInterpreter(this);
0259 
0260     if (s_hook) {
0261         prev = s_hook;
0262         next = s_hook->next;
0263         s_hook->next->prev = this;
0264         s_hook->next = this;
0265     } else {
0266         // This is the first interpreter
0267         s_hook = next = prev = this;
0268     }
0269 
0270     initGlobalObject();
0271 }
0272 
0273 Interpreter::~Interpreter()
0274 {
0275     JSLock lock;
0276 
0277     ASSERT(m_startTimeoutCheckCount == 0);
0278     ASSERT(m_pauseTimeoutCheckCount == 0);
0279 
0280     delete m_timeoutChecker;
0281 
0282     if (m_debugger) {
0283         m_debugger->detach(this);
0284     }
0285 
0286     std::free(stackBase);
0287 
0288     next->prev = prev;
0289     prev->next = next;
0290     s_hook = next;
0291     if (s_hook == this) {
0292         // This was the last interpreter
0293         s_hook = nullptr;
0294     }
0295 
0296     m_globalObject->setInterpreter(nullptr);
0297 }
0298 
0299 unsigned char *Interpreter::extendStack(size_t needed)
0300 {
0301     unsigned char *oldBase = stackBase; // needed for fixing up localStores
0302 
0303     size_t curSize = stackEnd - stackBase;
0304     size_t avail = stackEnd - stackPtr;
0305     size_t extra = needed - avail;
0306 
0307     if (extra < 8192) {
0308         extra = 8192;
0309     }
0310     size_t newSize = curSize + extra;
0311 
0312     //printf("Grow stack:%d -> %d\n", curSize, newSize);
0313 
0314     stackBase = (unsigned char *)std::malloc(newSize); // Not realloc since we need the old stuff
0315     // ### seems optimizeable
0316     std::memcpy(stackBase, oldBase, curSize);
0317     stackPtr  = stackBase + (stackPtr - oldBase);
0318     stackEnd  = stackBase + newSize;
0319 
0320     // Now go through and fix up activations..
0321     ExecState *e = m_execState;
0322     while (e) {
0323         if (e->codeType() == FunctionCode) {
0324             ActivationImp *act = static_cast<ActivationImp *>(e->activationObject());
0325             if (act->localStorage) {
0326                 act->localStorage = (LocalStorageEntry *)
0327                                     (stackBase + ((unsigned char *)act->localStorage - oldBase));
0328                 e->updateLocalStorage(act->localStorage);
0329             }
0330         }
0331 
0332         e = e->savedExecState();
0333     }
0334 
0335     std::free(oldBase);
0336 
0337     return stackAlloc(needed);
0338 }
0339 
0340 void Interpreter::recycleActivation(ActivationImp *act)
0341 {
0342     ASSERT(act->localStorage == nullptr); // Should not refer to anything by now
0343     if (m_numCachedActivations >= MaxCachedActivations) {
0344         return;
0345     }
0346 
0347     act->clearProperties();
0348     m_cachedActivations[m_numCachedActivations] = act;
0349     ++m_numCachedActivations;
0350 }
0351 
0352 JSGlobalObject *Interpreter::globalObject() const
0353 {
0354     return m_globalObject;
0355 }
0356 
0357 void Interpreter::putNamedConstructor(const char *name, JSObject *value)
0358 {
0359     assert(value->implementsCall());
0360     Identifier i(name);
0361     m_globalObject->put(&m_globalExec, i, value, DontEnum);
0362     static_cast<InternalFunctionImp *>(value)->setFunctionName(i);
0363 }
0364 
0365 void Interpreter::initGlobalObject()
0366 {
0367     FunctionPrototype *funcProto = new FunctionPrototype(&m_globalExec);
0368     m_FunctionPrototype = funcProto;
0369     ObjectPrototype *objProto = new ObjectPrototype(&m_globalExec, funcProto);
0370     m_ObjectPrototype = objProto;
0371     funcProto->setPrototype(m_ObjectPrototype);
0372 
0373     ArrayPrototype *arrayProto = new ArrayPrototype(&m_globalExec, objProto);
0374     m_ArrayPrototype = arrayProto;
0375     StringPrototype *stringProto = new StringPrototype(&m_globalExec, objProto);
0376     m_StringPrototype = stringProto;
0377     BooleanPrototype *booleanProto = new BooleanPrototype(&m_globalExec, objProto, funcProto);
0378     m_BooleanPrototype = booleanProto;
0379     NumberPrototype *numberProto = new NumberPrototype(&m_globalExec, objProto, funcProto);
0380     m_NumberPrototype = numberProto;
0381     DatePrototype *dateProto = new DatePrototype(&m_globalExec, objProto);
0382     m_DatePrototype = dateProto;
0383     RegExpPrototype *regexpProto = new RegExpPrototype(&m_globalExec, objProto, funcProto);
0384     m_RegExpPrototype = regexpProto;
0385     ErrorPrototype *errorProto = new ErrorPrototype(&m_globalExec, objProto, funcProto);
0386     m_ErrorPrototype = errorProto;
0387 
0388     JSObject *o = m_globalObject;
0389     while (JSValue::isObject(o->prototype())) {
0390         o = static_cast<JSObject *>(o->prototype());
0391     }
0392     o->setPrototype(m_ObjectPrototype);
0393 
0394     // Constructors (Object, Array, etc.)
0395     m_Object = new ObjectObjectImp(&m_globalExec, objProto, funcProto);
0396     m_Function = new FunctionObjectImp(&m_globalExec, funcProto);
0397     m_Array = new ArrayObjectImp(&m_globalExec, funcProto, arrayProto);
0398     m_String = new StringObjectImp(&m_globalExec, funcProto, stringProto);
0399     m_Boolean = new BooleanObjectImp(&m_globalExec, funcProto, booleanProto);
0400     m_Number = new NumberObjectImp(&m_globalExec, funcProto, numberProto);
0401     m_Date = new DateObjectImp(&m_globalExec, funcProto, dateProto);
0402     m_RegExp = new RegExpObjectImp(&m_globalExec, funcProto, regexpProto);
0403     m_Error = new ErrorObjectImp(&m_globalExec, funcProto, errorProto);
0404 
0405     // Error object prototypes
0406     m_EvalErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, EvalError, "EvalError", "EvalError");
0407     m_RangeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, RangeError, "RangeError", "RangeError");
0408     m_ReferenceErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
0409     m_SyntaxErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
0410     m_TypeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, TypeError, "TypeError", "TypeError");
0411     m_UriErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, URIError, "URIError", "URIError");
0412 
0413     // Error objects
0414     m_EvalError = new NativeErrorImp(&m_globalExec, funcProto, m_EvalErrorPrototype);
0415     m_RangeError = new NativeErrorImp(&m_globalExec, funcProto, m_RangeErrorPrototype);
0416     m_ReferenceError = new NativeErrorImp(&m_globalExec, funcProto, m_ReferenceErrorPrototype);
0417     m_SyntaxError = new NativeErrorImp(&m_globalExec, funcProto, m_SyntaxErrorPrototype);
0418     m_TypeError = new NativeErrorImp(&m_globalExec, funcProto, m_TypeErrorPrototype);
0419     m_UriError = new NativeErrorImp(&m_globalExec, funcProto, m_UriErrorPrototype);
0420 
0421     // ECMA 15.3.4.1
0422     funcProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum);
0423 
0424     putNamedConstructor("Object", m_Object);
0425     putNamedConstructor("Function", m_Function);
0426     putNamedConstructor("Array", m_Array);
0427     putNamedConstructor("Boolean", m_Boolean);
0428     putNamedConstructor("String", m_String);
0429     putNamedConstructor("Number", m_Number);
0430     putNamedConstructor("Date", m_Date);
0431     putNamedConstructor("RegExp", m_RegExp);
0432     putNamedConstructor("Error", m_Error);
0433     putNamedConstructor("EvalError", m_EvalError);
0434     putNamedConstructor("RangeError", m_RangeError);
0435     putNamedConstructor("ReferenceError", m_ReferenceError);
0436     putNamedConstructor("SyntaxError", m_SyntaxError);
0437     putNamedConstructor("TypeError", m_TypeError);
0438     putNamedConstructor("URIError", m_UriError);
0439 
0440     // Set the constructorPropertyName property of all builtin constructors
0441     objProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Object, DontEnum);
0442     funcProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum);
0443     arrayProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Array, DontEnum);
0444     booleanProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Boolean, DontEnum);
0445     stringProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_String, DontEnum);
0446     numberProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Number, DontEnum);
0447     dateProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Date, DontEnum);
0448     regexpProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RegExp, DontEnum);
0449     errorProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Error, DontEnum);
0450     m_EvalErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_EvalError, DontEnum);
0451     m_RangeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RangeError, DontEnum);
0452     m_ReferenceErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_ReferenceError, DontEnum);
0453     m_SyntaxErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_SyntaxError, DontEnum);
0454     m_TypeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_TypeError, DontEnum);
0455     m_UriErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_UriError, DontEnum);
0456 
0457     // built-in values
0458     m_globalObject->put(&m_globalExec, "NaN",        jsNaN(), DontEnum | DontDelete | ReadOnly);
0459     m_globalObject->put(&m_globalExec, "Infinity",   jsNumber(Inf), DontEnum | DontDelete | ReadOnly);
0460     m_globalObject->put(&m_globalExec, "undefined",  jsUndefined(), DontEnum | DontDelete | ReadOnly);
0461 
0462     // built-in functions
0463     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
0464     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
0465     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
0466     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
0467     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
0468     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
0469     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
0470     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
0471     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
0472     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
0473     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
0474 #ifndef NDEBUG
0475     m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
0476 #endif
0477 
0478     // built-in objects
0479     m_globalObject->put(&m_globalExec, "Math", new MathObjectImp(&m_globalExec, objProto), DontEnum);
0480     m_globalObject->put(&m_globalExec, "JSON", new JSONObjectImp(&m_globalExec, objProto), DontEnum);
0481 }
0482 
0483 ExecState *Interpreter::globalExec()
0484 {
0485     return &m_globalExec;
0486 }
0487 
0488 void Interpreter::setGlobalPackage(Package *p)
0489 {
0490     globPkg = p;
0491 }
0492 
0493 Package *Interpreter::globalPackage()
0494 {
0495     return globPkg;
0496 }
0497 
0498 Completion Interpreter::checkSyntax(const UString &sourceURL, int startingLineNumber, const UString &code)
0499 {
0500     return checkSyntax(sourceURL, startingLineNumber, code.data(), code.size());
0501 }
0502 
0503 Completion Interpreter::checkSyntax(const UString &sourceURL, int startingLineNumber, const UChar *code, int codeLength)
0504 {
0505     JSLock lock;
0506 
0507     int errLine;
0508     UString errMsg;
0509     RefPtr<ProgramNode> progNode = parser().parseProgram(sourceURL, startingLineNumber, code, codeLength, nullptr, &errLine, &errMsg);
0510     if (!progNode) {
0511         return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, 0, sourceURL));
0512     }
0513     return Completion(Normal);
0514 }
0515 
0516 Completion Interpreter::evaluate(const UString &sourceURL, int startingLineNumber, const UString &code, JSValue *thisV)
0517 {
0518     return evaluate(sourceURL, startingLineNumber, code.data(), code.size(), thisV);
0519 }
0520 
0521 Completion Interpreter::evaluate(const UString &sourceURL, int startingLineNumber, const UChar *code, int codeLength, JSValue *thisV)
0522 {
0523     JSLock lock;
0524 
0525     // prevent against infinite recursion
0526     if (m_recursion >= 20) {
0527         return Completion(Throw, Error::create(&m_globalExec, GeneralError, "Recursion too deep"));
0528     }
0529 
0530     // parse the source code
0531     int sourceId;
0532     int errLine;
0533     UString errMsg;
0534     RefPtr<ProgramNode> progNode = parser().parseProgram(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg);
0535 
0536     // notify debugger that source has been parsed
0537     if (m_debugger) {
0538         m_debugger->reportSourceParsed(&m_globalExec, progNode.get(), sourceId, sourceURL,
0539                                        UString(code, codeLength), startingLineNumber, errLine, errMsg);
0540     }
0541 
0542     // no program node means a syntax error occurred
0543     if (!progNode) {
0544         Completion res(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, sourceId, sourceURL));
0545         if (m_debugger) {
0546             m_debugger->reportException(&m_globalExec, res.value());
0547         }
0548 
0549         if (shouldPrintExceptions()) {
0550             printException(res, sourceURL);
0551         }
0552         return res;
0553     }
0554 
0555     m_globalExec.clearException();
0556 
0557     m_recursion++;
0558 
0559     JSGlobalObject *globalObj = m_globalObject;
0560     JSObject       *thisObj   = globalObj;
0561 
0562     // "this" must be an object... use same rules as Function.prototype.apply()
0563     if (thisV && !JSValue::isUndefinedOrNull(thisV)) {
0564         thisObj = JSValue::toObject(thisV, &m_globalExec);
0565     }
0566 
0567     Completion res;
0568     if (m_globalExec.hadException())
0569         // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
0570     {
0571         res = Completion(Throw, m_globalExec.exception());
0572     } else {
0573         // execute the code
0574         InterpreterExecState newExec(this, globalObj, thisObj, progNode.get());
0575 
0576         if (m_debugger && !m_debugger->enterContext(&newExec, sourceId, startingLineNumber, nullptr, List::empty())) {
0577             // debugger requested we stop execution.
0578             m_debugger->imp()->abort();
0579             return Completion(Break);
0580         }
0581 
0582         progNode->processDecls(&newExec);
0583         res = progNode->execute(&newExec);
0584 
0585         if (m_debugger && !m_debugger->exitContext(&newExec, sourceId, startingLineNumber, nullptr)) {
0586             // debugger requested we stop execution.
0587             m_debugger->imp()->abort();
0588             return Completion(Break);
0589         }
0590     }
0591 
0592     m_recursion--;
0593 
0594     if (shouldPrintExceptions() && res.complType() == Throw) {
0595         printException(res, sourceURL);
0596     }
0597 
0598     return res;
0599 }
0600 
0601 bool Interpreter::normalizeCode(const UString &codeIn, UString *codeOut,
0602                                 int *errLine, UString *errMsg)
0603 {
0604     assert(codeOut);
0605     RefPtr<ProgramNode> progNode = parser().parseProgram("", // sourceURL
0606                                    0, // line
0607                                    codeIn.data(),
0608                                    codeIn.size(),
0609                                    nullptr, // &sourceId
0610                                    errLine, errMsg);
0611     if (progNode) {
0612         *codeOut = progNode->toString();
0613         return true;
0614     } else {
0615         return false;
0616     }
0617 }
0618 
0619 JSObject *Interpreter::builtinObject() const
0620 {
0621     return m_Object;
0622 }
0623 
0624 JSObject *Interpreter::builtinFunction() const
0625 {
0626     return m_Function;
0627 }
0628 
0629 JSObject *Interpreter::builtinArray() const
0630 {
0631     return m_Array;
0632 }
0633 
0634 JSObject *Interpreter::builtinBoolean() const
0635 {
0636     return m_Boolean;
0637 }
0638 
0639 JSObject *Interpreter::builtinString() const
0640 {
0641     return m_String;
0642 }
0643 
0644 JSObject *Interpreter::builtinNumber() const
0645 {
0646     return m_Number;
0647 }
0648 
0649 JSObject *Interpreter::builtinDate() const
0650 {
0651     return m_Date;
0652 }
0653 
0654 JSObject *Interpreter::builtinRegExp() const
0655 {
0656     return m_RegExp;
0657 }
0658 
0659 JSObject *Interpreter::builtinError() const
0660 {
0661     return m_Error;
0662 }
0663 
0664 JSObject *Interpreter::builtinObjectPrototype() const
0665 {
0666     return m_ObjectPrototype;
0667 }
0668 
0669 JSObject *Interpreter::builtinFunctionPrototype() const
0670 {
0671     return m_FunctionPrototype;
0672 }
0673 
0674 JSObject *Interpreter::builtinArrayPrototype() const
0675 {
0676     return m_ArrayPrototype;
0677 }
0678 
0679 JSObject *Interpreter::builtinBooleanPrototype() const
0680 {
0681     return m_BooleanPrototype;
0682 }
0683 
0684 JSObject *Interpreter::builtinStringPrototype() const
0685 {
0686     return m_StringPrototype;
0687 }
0688 
0689 JSObject *Interpreter::builtinNumberPrototype() const
0690 {
0691     return m_NumberPrototype;
0692 }
0693 
0694 JSObject *Interpreter::builtinDatePrototype() const
0695 {
0696     return m_DatePrototype;
0697 }
0698 
0699 JSObject *Interpreter::builtinRegExpPrototype() const
0700 {
0701     return m_RegExpPrototype;
0702 }
0703 
0704 JSObject *Interpreter::builtinErrorPrototype() const
0705 {
0706     return m_ErrorPrototype;
0707 }
0708 
0709 JSObject *Interpreter::builtinEvalError() const
0710 {
0711     return m_EvalError;
0712 }
0713 
0714 JSObject *Interpreter::builtinRangeError() const
0715 {
0716     return m_RangeError;
0717 }
0718 
0719 JSObject *Interpreter::builtinReferenceError() const
0720 {
0721     return m_ReferenceError;
0722 }
0723 
0724 JSObject *Interpreter::builtinSyntaxError() const
0725 {
0726     return m_SyntaxError;
0727 }
0728 
0729 JSObject *Interpreter::builtinTypeError() const
0730 {
0731     return m_TypeError;
0732 }
0733 
0734 JSObject *Interpreter::builtinURIError() const
0735 {
0736     return m_UriError;
0737 }
0738 
0739 JSObject *Interpreter::builtinEvalErrorPrototype() const
0740 {
0741     return m_EvalErrorPrototype;
0742 }
0743 
0744 JSObject *Interpreter::builtinRangeErrorPrototype() const
0745 {
0746     return m_RangeErrorPrototype;
0747 }
0748 
0749 JSObject *Interpreter::builtinReferenceErrorPrototype() const
0750 {
0751     return m_ReferenceErrorPrototype;
0752 }
0753 
0754 JSObject *Interpreter::builtinSyntaxErrorPrototype() const
0755 {
0756     return m_SyntaxErrorPrototype;
0757 }
0758 
0759 JSObject *Interpreter::builtinTypeErrorPrototype() const
0760 {
0761     return m_TypeErrorPrototype;
0762 }
0763 
0764 JSObject *Interpreter::builtinURIErrorPrototype() const
0765 {
0766     return m_UriErrorPrototype;
0767 }
0768 
0769 bool Interpreter::collect()
0770 {
0771     return Collector::collect();
0772 }
0773 
0774 void Interpreter::mark(bool)
0775 {
0776     if (m_execState) {
0777         m_execState->mark();
0778     }
0779     if (m_globalObject && !m_globalObject->marked()) {
0780         m_globalObject->mark();
0781     }
0782     if (m_globalExec.exception() && !JSValue::marked(m_globalExec.exception())) {
0783         JSValue::mark(m_globalExec.exception());
0784     }
0785 
0786     // Do not let cached activations survive the GC; as they have an unfortunate
0787     // tendenacy to pin blocks, increasing their number and hence spreading out
0788     // the objects somewhat
0789     m_numCachedActivations = 0;
0790 }
0791 
0792 void Interpreter::markSourceCachedObjects()
0793 {
0794     markInternedStringsTable();
0795 }
0796 
0797 #ifdef KJS_DEBUG_MEM
0798 void Interpreter::finalCheck()
0799 {
0800     fprintf(stderr, "Interpreter::finalCheck()\n");
0801     Collector::collect();
0802 
0803 //  Node::finalCheck();
0804     Collector::finalCheck();
0805 }
0806 #endif
0807 
0808 static bool printExceptions = false;
0809 
0810 bool Interpreter::shouldPrintExceptions()
0811 {
0812     return printExceptions;
0813 }
0814 
0815 void Interpreter::setShouldPrintExceptions(bool print)
0816 {
0817     printExceptions = print;
0818 }
0819 
0820 void Interpreter::printException(const Completion &c, const UString &sourceURL)
0821 {
0822     JSLock lock;
0823     ExecState *exec = globalExec();
0824     CString f = sourceURL.UTF8String();
0825     CString message = JSValue::toObject(c.value(), exec)->toString(exec).UTF8String();
0826     int line = JSValue::toUInt32(JSValue::toObject(c.value(), exec)->get(exec, "line"), exec);
0827 #if PLATFORM(WIN_OS)
0828     printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
0829 #else
0830     printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
0831 #endif
0832 }
0833 
0834 // bindings are OS X WebKit-only for now
0835 #if USE(BINDINGS)
0836 void *Interpreter::createLanguageInstanceForValue(ExecState *exec, int language, JSObject *value, const Bindings::RootObject *origin, const Bindings::RootObject *current)
0837 {
0838     return Bindings::Instance::createLanguageInstanceForValue(exec, (Bindings::Instance::BindingLanguage)language, value, origin, current);
0839 }
0840 #endif
0841 
0842 void Interpreter::saveBuiltins(SavedBuiltins &builtins) const
0843 {
0844     if (!builtins._internal) {
0845         builtins._internal = new SavedBuiltinsInternal;
0846     }
0847 
0848     builtins._internal->m_Object = m_Object;
0849     builtins._internal->m_Function = m_Function;
0850     builtins._internal->m_Array = m_Array;
0851     builtins._internal->m_Boolean = m_Boolean;
0852     builtins._internal->m_String = m_String;
0853     builtins._internal->m_Number = m_Number;
0854     builtins._internal->m_Date = m_Date;
0855     builtins._internal->m_RegExp = m_RegExp;
0856     builtins._internal->m_Error = m_Error;
0857 
0858     builtins._internal->m_ObjectPrototype = m_ObjectPrototype;
0859     builtins._internal->m_FunctionPrototype = m_FunctionPrototype;
0860     builtins._internal->m_ArrayPrototype = m_ArrayPrototype;
0861     builtins._internal->m_BooleanPrototype = m_BooleanPrototype;
0862     builtins._internal->m_StringPrototype = m_StringPrototype;
0863     builtins._internal->m_NumberPrototype = m_NumberPrototype;
0864     builtins._internal->m_DatePrototype = m_DatePrototype;
0865     builtins._internal->m_RegExpPrototype = m_RegExpPrototype;
0866     builtins._internal->m_ErrorPrototype = m_ErrorPrototype;
0867 
0868     builtins._internal->m_EvalError = m_EvalError;
0869     builtins._internal->m_RangeError = m_RangeError;
0870     builtins._internal->m_ReferenceError = m_ReferenceError;
0871     builtins._internal->m_SyntaxError = m_SyntaxError;
0872     builtins._internal->m_TypeError = m_TypeError;
0873     builtins._internal->m_UriError = m_UriError;
0874 
0875     builtins._internal->m_EvalErrorPrototype = m_EvalErrorPrototype;
0876     builtins._internal->m_RangeErrorPrototype = m_RangeErrorPrototype;
0877     builtins._internal->m_ReferenceErrorPrototype = m_ReferenceErrorPrototype;
0878     builtins._internal->m_SyntaxErrorPrototype = m_SyntaxErrorPrototype;
0879     builtins._internal->m_TypeErrorPrototype = m_TypeErrorPrototype;
0880     builtins._internal->m_UriErrorPrototype = m_UriErrorPrototype;
0881 }
0882 
0883 void Interpreter::restoreBuiltins(const SavedBuiltins &builtins)
0884 {
0885     if (!builtins._internal) {
0886         return;
0887     }
0888 
0889     m_Object = builtins._internal->m_Object;
0890     m_Function = builtins._internal->m_Function;
0891     m_Array = builtins._internal->m_Array;
0892     m_Boolean = builtins._internal->m_Boolean;
0893     m_String = builtins._internal->m_String;
0894     m_Number = builtins._internal->m_Number;
0895     m_Date = builtins._internal->m_Date;
0896     m_RegExp = builtins._internal->m_RegExp;
0897     m_Error = builtins._internal->m_Error;
0898 
0899     m_ObjectPrototype = builtins._internal->m_ObjectPrototype;
0900     m_FunctionPrototype = builtins._internal->m_FunctionPrototype;
0901     m_ArrayPrototype = builtins._internal->m_ArrayPrototype;
0902     m_BooleanPrototype = builtins._internal->m_BooleanPrototype;
0903     m_StringPrototype = builtins._internal->m_StringPrototype;
0904     m_NumberPrototype = builtins._internal->m_NumberPrototype;
0905     m_DatePrototype = builtins._internal->m_DatePrototype;
0906     m_RegExpPrototype = builtins._internal->m_RegExpPrototype;
0907     m_ErrorPrototype = builtins._internal->m_ErrorPrototype;
0908 
0909     m_EvalError = builtins._internal->m_EvalError;
0910     m_RangeError = builtins._internal->m_RangeError;
0911     m_ReferenceError = builtins._internal->m_ReferenceError;
0912     m_SyntaxError = builtins._internal->m_SyntaxError;
0913     m_TypeError = builtins._internal->m_TypeError;
0914     m_UriError = builtins._internal->m_UriError;
0915 
0916     m_EvalErrorPrototype = builtins._internal->m_EvalErrorPrototype;
0917     m_RangeErrorPrototype = builtins._internal->m_RangeErrorPrototype;
0918     m_ReferenceErrorPrototype = builtins._internal->m_ReferenceErrorPrototype;
0919     m_SyntaxErrorPrototype = builtins._internal->m_SyntaxErrorPrototype;
0920     m_TypeErrorPrototype = builtins._internal->m_TypeErrorPrototype;
0921     m_UriErrorPrototype = builtins._internal->m_UriErrorPrototype;
0922 }
0923 
0924 void Interpreter::startTimeoutCheck()
0925 {
0926     if (!m_timeoutChecker) {
0927         m_timeoutChecker = new TimeoutChecker;
0928     }
0929 
0930     m_timeoutChecker->startTimeoutCheck(this);
0931 }
0932 
0933 void Interpreter::stopTimeoutCheck()
0934 {
0935     ASSERT(m_timeoutChecker);
0936 
0937     m_timeoutChecker->stopTimeoutCheck(this);
0938 }
0939 
0940 void Interpreter::restartTimeoutCheck()
0941 {
0942     if (!m_timeoutChecker || !m_startTimeoutCheckCount) {
0943         return;
0944     }
0945 
0946     m_timedOut = false;
0947     m_timeoutChecker->stopTimeoutCheck(this);
0948     m_timeoutChecker->startTimeoutCheck(this);
0949 }
0950 
0951 void Interpreter::pauseTimeoutCheck()
0952 {
0953     ASSERT(m_timeoutChecker);
0954 
0955     m_timeoutChecker->pauseTimeoutCheck(this);
0956 }
0957 
0958 void Interpreter::resumeTimeoutCheck()
0959 {
0960     ASSERT(m_timeoutChecker);
0961 
0962     m_timeoutChecker->resumeTimeoutCheck(this);
0963 }
0964 
0965 bool Interpreter::handleTimeout()
0966 {
0967     m_timedOut = false;
0968 
0969     pauseTimeoutCheck();
0970     bool retval = shouldInterruptScript();
0971     resumeTimeoutCheck();
0972 
0973     return retval;
0974 }
0975 
0976 Interpreter::InternedStringsTable *Interpreter::s_internedStrings;
0977 
0978 void Interpreter::initInternedStringsTable()
0979 {
0980     if (!s_internedStrings) {
0981         s_internedStrings = new InternedStringsTable();
0982     }
0983 }
0984 
0985 StringImp *Interpreter::internString(const UString &literal)
0986 {
0987     InternedStringsTable::iterator i = s_internedStrings->find(literal.rep());
0988 
0989     if (i == s_internedStrings->end()) {
0990         // Need to add. Note: we can't use ->add() above to avoid a double-hash
0991         // as creation of a StringImp may cause a GC, which in turn may
0992         // rearrange the hashtable, invalidating the iterator.
0993         StringImp *si = static_cast<StringImp *>(jsOwnedString(literal));
0994         s_internedStrings->add(literal.rep(), std::make_pair(si, 1));
0995         return si;
0996     } else {
0997         ++i.values()->second; // just bump the ref count
0998         return i.values()->first;
0999     }
1000 }
1001 
1002 void Interpreter::releaseInternedString(const UString &literal)
1003 {
1004     InternedStringsTable::iterator i = s_internedStrings->find(literal.rep());
1005 
1006     --i.values()->second;
1007     if (i.values()->second == 0) {
1008         s_internedStrings->remove(i);
1009     }
1010 }
1011 
1012 void Interpreter::markInternedStringsTable()
1013 {
1014     for (InternedStringsTable::iterator i = s_internedStrings->begin();
1015             i != s_internedStrings->end(); ++i) {
1016         // Note: the StringImp* may be null here if we got called in the middle
1017         // of internString.
1018         if (i.values()->first && !i.values()->first->marked()) {
1019             i.values()->first->mark();
1020         }
1021     }
1022 }
1023 
1024 SavedBuiltins::SavedBuiltins() :
1025     _internal(nullptr)
1026 {
1027 }
1028 
1029 SavedBuiltins::~SavedBuiltins()
1030 {
1031     delete _internal;
1032 }
1033 
1034 UnicodeSupport::UnicodeSupport()
1035 {
1036 }
1037 
1038 void UnicodeSupport::setIdentStartChecker(bool (*f)(int c))
1039 {
1040     Lexer::setIdentStartChecker(f);
1041 }
1042 
1043 void UnicodeSupport::setIdentPartChecker(bool (*f)(int c))
1044 {
1045     Lexer::setIdentPartChecker(f);
1046 }
1047 
1048 void UnicodeSupport::setToLowerFunction(StringConversionFunction f)
1049 {
1050     StringProtoFunc::setToLowerFunction(f);
1051 }
1052 
1053 void UnicodeSupport::setToUpperFunction(StringConversionFunction f)
1054 {
1055     StringProtoFunc::setToUpperFunction(f);
1056 }
1057 
1058 }
1059