/* * This file is part of the KDE libraries * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef _KJS_INTERPRETER_H_ #define _KJS_INTERPRETER_H_ #include "ExecState.h" #include "protect.h" #include "value.h" #include "types.h" namespace KJS { class ArrayObjectImp; class ArrayPrototype; class BooleanObjectImp; class BooleanPrototype; class Context; class DateObjectImp; class DatePrototype; class Debugger; class ErrorObjectImp; class ErrorPrototype; class EvalError; class EvalErrorPrototype; class FunctionObjectImp; class FunctionPrototype; class NativeErrorImp; class NativeErrorPrototype; class NumberObjectImp; class NumberPrototype; class ObjectObjectImp; class ObjectPrototype; class RangeError; class RangeErrorPrototype; class ReferenceError; class ReferenceError; class ReferenceErrorPrototype; class RegExpObjectImp; class RegExpPrototype; class RuntimeMethod; class SavedBuiltins; class ScopeChain; class StringObjectImp; class StringPrototype; class SyntaxErrorPrototype; class TypeError; class TypeErrorPrototype; class UriError; class UriErrorPrototype; /** * Interpreter objects can be used to evaluate ECMAScript code. Each * interpreter has a global object which is used for the purposes of code * evaluation, and also provides access to built-in properties such as * " Object" and "Number". */ class Interpreter { friend class Collector; public: /** * Creates a new interpreter. The supplied object will be used as the global * object for all scripts executed with this interpreter. During * constuction, all the standard properties such as "Object" and "Number" * will be added to the global object. * * Note: You should not use the same global object for multiple * interpreters. * * This is due do the fact that the built-in properties are set in the * constructor, and if these objects have been modified from another * interpreter (e.g. a script modifying String.prototype), the changes will * be overridden. * * @param global The object to use as the global object for this interpreter */ Interpreter(JSObject* globalObject); /** * Creates a new interpreter. A global object will be created and * initialized with the standard global properties. */ Interpreter(); /** * Resets the global object's default properties and adds the default object * prototype to its prototype chain. */ void initGlobalObject(); /** * Returns the object that is used as the global object during all script * execution performed by this interpreter */ JSObject* globalObject() const; /** * Returns the execution state object which can be used to execute * scripts using this interpreter at a the "global" level, i.e. one * with a execution context that has the global object as the "this" * value, and who's scope chain contains only the global object. * * Note: this pointer remains constant for the life of the interpreter * and should not be manually deleted. * * @return The interpreter global execution state object */ virtual ExecState *globalExec(); /** * Parses the supplied ECMAScript code and checks for syntax errors. * * @param code The code to check * @return A normal completion if there were no syntax errors in the code, * otherwise a throw completion with the syntax error as its value. */ Completion checkSyntax(const UString& sourceURL, int startingLineNumber, const UString& code); Completion checkSyntax(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength); /** * Evaluates the supplied ECMAScript code. * * Since this method returns a Completion, you should check the type of * completion to detect an error or before attempting to access the returned * value. For example, if an error occurs during script execution and is not * caught by the script, the completion type will be Throw. * * If the supplied code is invalid, a SyntaxError will be thrown. * * @param code The code to evaluate * @param thisV The value to pass in as the "this" value for the script * execution. This should either be jsNull() or an Object. * @return A completion object representing the result of the execution. */ Completion evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0); Completion evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0); /** * Returns the builtin "Object" object. This is the object that was set * as a property of the global object during construction; if the property * is replaced by script code, this method will still return the original * object. * * @return The builtin "Object" object */ JSObject *builtinObject() const; /** * Returns the builtin "Function" object. */ JSObject *builtinFunction() const; /** * Returns the builtin "Array" object. */ JSObject *builtinArray() const; /** * Returns the builtin "Boolean" object. */ JSObject *builtinBoolean() const; /** * Returns the builtin "String" object. */ JSObject *builtinString() const; /** * Returns the builtin "Number" object. */ JSObject *builtinNumber() const; /** * Returns the builtin "Date" object. */ JSObject *builtinDate() const; /** * Returns the builtin "RegExp" object. */ JSObject *builtinRegExp() const; /** * Returns the builtin "Error" object. */ JSObject *builtinError() const; /** * Returns the builtin "Object.prototype" object. */ JSObject *builtinObjectPrototype() const; /** * Returns the builtin "Function.prototype" object. */ JSObject *builtinFunctionPrototype() const; /** * Returns the builtin "Array.prototype" object. */ JSObject *builtinArrayPrototype() const; /** * Returns the builtin "Boolean.prototype" object. */ JSObject *builtinBooleanPrototype() const; /** * Returns the builtin "String.prototype" object. */ JSObject *builtinStringPrototype() const; /** * Returns the builtin "Number.prototype" object. */ JSObject *builtinNumberPrototype() const; /** * Returns the builtin "Date.prototype" object. */ JSObject *builtinDatePrototype() const; /** * Returns the builtin "RegExp.prototype" object. */ JSObject *builtinRegExpPrototype() const; /** * Returns the builtin "Error.prototype" object. */ JSObject *builtinErrorPrototype() const; /** * The initial value of "Error" global property */ JSObject *builtinEvalError() const; JSObject *builtinRangeError() const; JSObject *builtinReferenceError() const; JSObject *builtinSyntaxError() const; JSObject *builtinTypeError() const; JSObject *builtinURIError() const; JSObject *builtinEvalErrorPrototype() const; JSObject *builtinRangeErrorPrototype() const; JSObject *builtinReferenceErrorPrototype() const; JSObject *builtinSyntaxErrorPrototype() const; JSObject *builtinTypeErrorPrototype() const; JSObject *builtinURIErrorPrototype() const; enum CompatMode { NativeMode, IECompat, NetscapeCompat }; /** * Call this to enable a compatibility mode with another browser. * (by default konqueror is in "native mode"). * Currently, in KJS, this only changes the behavior of Date::getYear() * which returns the full year under IE. */ void setCompatMode(CompatMode mode) { m_compatMode = mode; } CompatMode compatMode() const { return m_compatMode; } /** * Run the garbage collection. Returns true when at least one object * was collected; false otherwise. */ static bool collect(); /** * Called during the mark phase of the garbage collector. Subclasses * implementing custom mark methods must make sure to chain to this one. */ virtual void mark(); #ifdef KJS_DEBUG_MEM /** * @internal */ static void finalCheck(); #endif static bool shouldPrintExceptions(); static void setShouldPrintExceptions(bool); void saveBuiltins (SavedBuiltins&) const; void restoreBuiltins (const SavedBuiltins&); /** * Determine if the value is a global object (for any interpreter). This may * be difficult to determine for multiple uses of JSC in a process that are * logically independent of each other. In the case of WebCore, this method * is used to determine if an object is the Window object so we can perform * security checks. */ virtual bool isGlobalObject(JSValue*) { return false; } /** * Find the interpreter for a particular global object. This should really * be a static method, but we can't do that is C++. Again, as with isGlobalObject() * implementation really need to know about all instances of Interpreter * created in an application to correctly implement this method. The only * override of this method is currently in WebCore. */ virtual Interpreter* interpreterForGlobalObject(const JSValue*) { return 0; } /** * Determine if the it is 'safe' to execute code in the target interpreter from an * object that originated in this interpreter. This check is used to enforce WebCore * cross frame security rules. In particular, attempts to access 'bound' objects are * not allowed unless isSafeScript returns true. */ virtual bool isSafeScript(const Interpreter*) { return true; } // Chained list of interpreters (ring) static Interpreter* firstInterpreter() { return s_hook; } Interpreter* nextInterpreter() const { return next; } Interpreter* prevInterpreter() const { return prev; } Debugger* debugger() const { return m_debugger; } void setDebugger(Debugger* d) { m_debugger = d; } void setContext(Context* c) { m_context = c; } Context* context() const { return m_context; } static Interpreter* interpreterWithGlobalObject(JSObject*); void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; } void startTimeoutCheck(); void stopTimeoutCheck(); bool timedOut(); void ref() { ++m_refCount; } void deref() { if (--m_refCount <= 0) delete this; } int refCount() const { return m_refCount; } protected: virtual ~Interpreter(); // only deref should delete us virtual bool shouldInterruptScript() const { return true; } unsigned m_timeoutTime; private: void init(); void resetTimeoutCheck(); bool checkTimeout(); // Uncopyable Interpreter(const Interpreter&); Interpreter operator=(const Interpreter&); int m_refCount; ExecState m_globalExec; // Chained list of interpreters (ring) - for collector static Interpreter* s_hook; Interpreter *next, *prev; int m_recursion; Debugger* m_debugger; Context* m_context; CompatMode m_compatMode; unsigned m_timeAtLastCheckTimeout; unsigned m_timeExecuting; unsigned m_timeoutCheckCount; unsigned m_tickCount; unsigned m_ticksUntilNextTimeoutCheck; JSObject* m_globalObject; ObjectObjectImp* m_Object; FunctionObjectImp* m_Function; ArrayObjectImp* m_Array; BooleanObjectImp* m_Boolean; StringObjectImp* m_String; NumberObjectImp* m_Number; DateObjectImp* m_Date; RegExpObjectImp* m_RegExp; ErrorObjectImp* m_Error; ObjectPrototype* m_ObjectPrototype; FunctionPrototype* m_FunctionPrototype; ArrayPrototype* m_ArrayPrototype; BooleanPrototype* m_BooleanPrototype; StringPrototype* m_StringPrototype; NumberPrototype* m_NumberPrototype; DatePrototype* m_DatePrototype; RegExpPrototype* m_RegExpPrototype; ErrorPrototype* m_ErrorPrototype; NativeErrorImp* m_EvalError; NativeErrorImp* m_RangeError; NativeErrorImp* m_ReferenceError; NativeErrorImp* m_SyntaxError; NativeErrorImp* m_TypeError; NativeErrorImp* m_UriError; NativeErrorPrototype* m_EvalErrorPrototype; NativeErrorPrototype* m_RangeErrorPrototype; NativeErrorPrototype* m_ReferenceErrorPrototype; NativeErrorPrototype* m_SyntaxErrorPrototype; NativeErrorPrototype* m_TypeErrorPrototype; NativeErrorPrototype* m_UriErrorPrototype; }; inline bool Interpreter::timedOut() { m_tickCount++; if (m_tickCount != m_ticksUntilNextTimeoutCheck) return false; return checkTimeout(); } } // namespace #endif // _KJS_INTERPRETER_H_