JavaScriptCore:
[WebKit-https.git] / JavaScriptCore / kjs / interpreter.h
1 /*
2  *  This file is part of the KDE libraries
3  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *  Copyright (C) 2003 Apple Computer, Inc.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Library General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Library General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Library General Public License
18  *  along with this library; see the file COPYING.LIB.  If not, write to
19  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #ifndef _KJS_INTERPRETER_H_
25 #define _KJS_INTERPRETER_H_
26
27 #include "ExecState.h"
28 #include "protect.h"
29 #include "value.h"
30 #include "types.h"
31
32 namespace KJS {
33
34   class Context;
35   class Debugger;
36   class RuntimeMethod;
37   class SavedBuiltins;
38   class ScopeChain;
39
40   namespace Bindings {
41     class RootObject;
42   }
43
44   /**
45    * Interpreter objects can be used to evaluate ECMAScript code. Each
46    * interpreter has a global object which is used for the purposes of code
47    * evaluation, and also provides access to built-in properties such as
48    * " Object" and "Number".
49    */
50   class Interpreter {
51       friend class Collector;
52   public:
53     /**
54      * Creates a new interpreter. The supplied object will be used as the global
55      * object for all scripts executed with this interpreter. During
56      * constuction, all the standard properties such as "Object" and "Number"
57      * will be added to the global object.
58      *
59      * Note: You should not use the same global object for multiple
60      * interpreters.
61      *
62      * This is due do the fact that the built-in properties are set in the
63      * constructor, and if these objects have been modified from another
64      * interpreter (e.g. a script modifying String.prototype), the changes will
65      * be overridden.
66      *
67      * @param global The object to use as the global object for this interpreter
68      */
69     Interpreter(JSObject* globalObject);
70     /**
71      * Creates a new interpreter. A global object will be created and
72      * initialized with the standard global properties.
73      */
74     Interpreter();
75     virtual ~Interpreter();
76
77     /**
78      * Returns the object that is used as the global object during all script
79      * execution performed by this interpreter
80      */
81     JSObject* globalObject() const;
82     void initGlobalObject();
83
84     /**
85      * Returns the execution state object which can be used to execute
86      * scripts using this interpreter at a the "global" level, i.e. one
87      * with a execution context that has the global object as the "this"
88      * value, and who's scope chain contains only the global object.
89      *
90      * Note: this pointer remains constant for the life of the interpreter
91      * and should not be manually deleted.
92      *
93      * @return The interpreter global execution state object
94      */
95     virtual ExecState *globalExec();
96
97     /**
98      * Parses the supplied ECMAScript code and checks for syntax errors.
99      *
100      * @param code The code to check
101      * @return true if there were no syntax errors in the code, otherwise false
102      */
103     bool checkSyntax(const UString &code);
104
105     /**
106      * Evaluates the supplied ECMAScript code.
107      *
108      * Since this method returns a Completion, you should check the type of
109      * completion to detect an error or before attempting to access the returned
110      * value. For example, if an error occurs during script execution and is not
111      * caught by the script, the completion type will be Throw.
112      *
113      * If the supplied code is invalid, a SyntaxError will be thrown.
114      *
115      * @param code The code to evaluate
116      * @param thisV The value to pass in as the "this" value for the script
117      * execution. This should either be jsNull() or an Object.
118      * @return A completion object representing the result of the execution.
119      */
120     Completion evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0);
121     Completion evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0);
122
123     /**
124      * Returns the builtin "Object" object. This is the object that was set
125      * as a property of the global object during construction; if the property
126      * is replaced by script code, this method will still return the original
127      * object.
128      *
129      * @return The builtin "Object" object
130      */
131     JSObject *builtinObject() const;
132
133     /**
134      * Returns the builtin "Function" object.
135      */
136     JSObject *builtinFunction() const;
137
138     /**
139      * Returns the builtin "Array" object.
140      */
141     JSObject *builtinArray() const;
142
143     /**
144      * Returns the builtin "Boolean" object.
145      */
146     JSObject *builtinBoolean() const;
147
148     /**
149      * Returns the builtin "String" object.
150      */
151     JSObject *builtinString() const;
152
153     /**
154      * Returns the builtin "Number" object.
155      */
156     JSObject *builtinNumber() const;
157
158     /**
159      * Returns the builtin "Date" object.
160      */
161     JSObject *builtinDate() const;
162
163     /**
164      * Returns the builtin "RegExp" object.
165      */
166     JSObject *builtinRegExp() const;
167
168     /**
169      * Returns the builtin "Error" object.
170      */
171     JSObject *builtinError() const;
172
173     /**
174      * Returns the builtin "Object.prototype" object.
175      */
176     JSObject *builtinObjectPrototype() const;
177
178     /**
179      * Returns the builtin "Function.prototype" object.
180      */
181     JSObject *builtinFunctionPrototype() const;
182
183     /**
184      * Returns the builtin "Array.prototype" object.
185      */
186     JSObject *builtinArrayPrototype() const;
187
188     /**
189      * Returns the builtin "Boolean.prototype" object.
190      */
191     JSObject *builtinBooleanPrototype() const;
192
193     /**
194      * Returns the builtin "String.prototype" object.
195      */
196     JSObject *builtinStringPrototype() const;
197
198     /**
199      * Returns the builtin "Number.prototype" object.
200      */
201     JSObject *builtinNumberPrototype() const;
202
203     /**
204      * Returns the builtin "Date.prototype" object.
205      */
206     JSObject *builtinDatePrototype() const;
207
208     /**
209      * Returns the builtin "RegExp.prototype" object.
210      */
211     JSObject *builtinRegExpPrototype() const;
212
213     /**
214      * Returns the builtin "Error.prototype" object.
215      */
216     JSObject *builtinErrorPrototype() const;
217
218     /**
219      * The initial value of "Error" global property
220      */
221     JSObject *builtinEvalError() const;
222     JSObject *builtinRangeError() const;
223     JSObject *builtinReferenceError() const;
224     JSObject *builtinSyntaxError() const;
225     JSObject *builtinTypeError() const;
226     JSObject *builtinURIError() const;
227
228     JSObject *builtinEvalErrorPrototype() const;
229     JSObject *builtinRangeErrorPrototype() const;
230     JSObject *builtinReferenceErrorPrototype() const;
231     JSObject *builtinSyntaxErrorPrototype() const;
232     JSObject *builtinTypeErrorPrototype() const;
233     JSObject *builtinURIErrorPrototype() const;
234
235     enum CompatMode { NativeMode, IECompat, NetscapeCompat };
236     /**
237      * Call this to enable a compatibility mode with another browser.
238      * (by default konqueror is in "native mode").
239      * Currently, in KJS, this only changes the behavior of Date::getYear()
240      * which returns the full year under IE.
241      */
242     void setCompatMode(CompatMode mode) { m_compatMode = mode; }
243     CompatMode compatMode() const { return m_compatMode; }
244     
245     /**
246      * Run the garbage collection. Returns true when at least one object
247      * was collected; false otherwise.
248      */
249     static bool collect();
250
251     /**
252      * Called during the mark phase of the garbage collector. Subclasses 
253      * implementing custom mark methods must make sure to chain to this one.
254      */
255     virtual void mark(bool currentThreadIsMainThread);
256
257     /**
258      * Provides a way to distinguish derived classes.
259      * Only useful if you reimplement Interpreter and if different kind of
260      * interpreters are created in the same process.
261      * The base class returns 0, the ECMA-bindings interpreter returns 1.
262      */
263     virtual int rtti() { return 0; }
264
265 #ifdef KJS_DEBUG_MEM
266     /**
267      * @internal
268      */
269     static void finalCheck();
270 #endif
271
272     static bool shouldPrintExceptions();
273     static void setShouldPrintExceptions(bool);
274
275     void saveBuiltins (SavedBuiltins&) const;
276     void restoreBuiltins (const SavedBuiltins&);
277
278     /**
279      * Determine if the value is a global object (for any interpreter).  This may
280      * be difficult to determine for multiple uses of JSC in a process that are
281      * logically independent of each other.  In the case of WebCore, this method
282      * is used to determine if an object is the Window object so we can perform
283      * security checks.
284      */
285     virtual bool isGlobalObject(JSValue*) { return false; }
286     
287     /** 
288      * Find the interpreter for a particular global object.  This should really
289      * be a static method, but we can't do that is C++.  Again, as with isGlobalObject()
290      * implementation really need to know about all instances of Interpreter
291      * created in an application to correctly implement this method.  The only
292      * override of this method is currently in WebCore.
293      */
294     virtual Interpreter* interpreterForGlobalObject(const JSValue*) { return 0; }
295     
296     /**
297      * Determine if the it is 'safe' to execute code in the target interpreter from an
298      * object that originated in this interpreter.  This check is used to enforce WebCore
299      * cross frame security rules.  In particular, attempts to access 'bound' objects are
300      * not allowed unless isSafeScript returns true.
301      */
302     virtual bool isSafeScript(const Interpreter*) { return true; }
303   
304 #if PLATFORM(MAC)
305     virtual void *createLanguageInstanceForValue(ExecState*, int language, JSObject* value, const Bindings::RootObject* origin, const Bindings::RootObject* current);
306 #endif
307
308     // This is a workaround to avoid accessing the global variables for these identifiers in
309     // important property lookup functions, to avoid taking PIC branches in Mach-O binaries
310     const Identifier& argumentsIdentifier() { return *m_argumentsPropertyName; }
311     const Identifier& specialPrototypeIdentifier() { return *m_specialPrototypePropertyName; }
312     
313     // Chained list of interpreters (ring)
314     static Interpreter* firstInterpreter() { return s_hook; }
315     Interpreter* nextInterpreter() const { return next; }
316     Interpreter* prevInterpreter() const { return prev; }
317
318     Debugger* debugger() const { return m_debugger; }
319     void setDebugger(Debugger* d) { m_debugger = d; }
320     
321     void setContext(Context* c) { m_context = c; }
322     Context* context() const { return m_context; }
323     
324     static Interpreter* interpreterWithGlobalObject(JSObject*);
325 private:
326     void init();
327     
328     /**
329      * This constructor is not implemented, in order to prevent
330      * copy-construction of Interpreter objects. You should always pass around
331      * pointers to an interpreter instance instead.
332      */
333     Interpreter(const Interpreter&);
334     
335     /**
336      * This constructor is not implemented, in order to prevent assignment of
337      * Interpreter objects. You should always pass around pointers to an
338      * interpreter instance instead.
339      */
340     Interpreter operator=(const Interpreter&);
341     
342     ExecState m_globalExec;
343     JSObject* m_globalObject;
344
345     const Identifier *m_argumentsPropertyName;
346     const Identifier *m_specialPrototypePropertyName;
347
348     // Chained list of interpreters (ring) - for collector
349     static Interpreter* s_hook;
350     Interpreter *next, *prev;
351     
352     int m_recursion;
353     
354     Debugger* m_debugger;
355     Context* m_context;
356     CompatMode m_compatMode;
357
358     ProtectedPtr<JSObject> m_Object;
359     ProtectedPtr<JSObject> m_Function;
360     ProtectedPtr<JSObject> m_Array;
361     ProtectedPtr<JSObject> m_Boolean;
362     ProtectedPtr<JSObject> m_String;
363     ProtectedPtr<JSObject> m_Number;
364     ProtectedPtr<JSObject> m_Date;
365     ProtectedPtr<JSObject> m_RegExp;
366     ProtectedPtr<JSObject> m_Error;
367     
368     ProtectedPtr<JSObject> m_ObjectPrototype;
369     ProtectedPtr<JSObject> m_FunctionPrototype;
370     ProtectedPtr<JSObject> m_ArrayPrototype;
371     ProtectedPtr<JSObject> m_BooleanPrototype;
372     ProtectedPtr<JSObject> m_StringPrototype;
373     ProtectedPtr<JSObject> m_NumberPrototype;
374     ProtectedPtr<JSObject> m_DatePrototype;
375     ProtectedPtr<JSObject> m_RegExpPrototype;
376     ProtectedPtr<JSObject> m_ErrorPrototype;
377     
378     ProtectedPtr<JSObject> m_EvalError;
379     ProtectedPtr<JSObject> m_RangeError;
380     ProtectedPtr<JSObject> m_ReferenceError;
381     ProtectedPtr<JSObject> m_SyntaxError;
382     ProtectedPtr<JSObject> m_TypeError;
383     ProtectedPtr<JSObject> m_UriError;
384     
385     ProtectedPtr<JSObject> m_EvalErrorPrototype;
386     ProtectedPtr<JSObject> m_RangeErrorPrototype;
387     ProtectedPtr<JSObject> m_ReferenceErrorPrototype;
388     ProtectedPtr<JSObject> m_SyntaxErrorPrototype;
389     ProtectedPtr<JSObject> m_TypeErrorPrototype;
390     ProtectedPtr<JSObject> m_UriErrorPrototype;
391   };
392
393 } // namespace
394
395 #endif // _KJS_INTERPRETER_H_