Reviewed by Eric Seidel.
[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 "types.h"
30 #include "value.h"
31 #include <wtf/RefCounted.h>
32
33 namespace KJS {
34
35   class ArrayObjectImp;
36   class ArrayPrototype;
37   class BooleanObjectImp;
38   class BooleanPrototype;
39   class DateObjectImp;
40   class DatePrototype;
41   class Debugger;
42   class ErrorObjectImp;
43   class ErrorPrototype;
44   class EvalError;
45   class EvalErrorPrototype;
46   class FunctionObjectImp;
47   class FunctionPrototype;
48   class JSGlobalObject;
49   class NativeErrorImp;
50   class NativeErrorPrototype;
51   class NumberObjectImp;
52   class NumberPrototype;
53   class ObjectObjectImp;
54   class ObjectPrototype;
55   class RangeError;
56   class RangeErrorPrototype;
57   class ReferenceError;
58   class ReferenceError;
59   class ReferenceErrorPrototype;
60   class RegExpObjectImp;
61   class RegExpPrototype;
62   class RuntimeMethod;
63   class SavedBuiltins;
64   class ScopeChain;
65   class StringObjectImp;
66   class StringPrototype;
67   class SyntaxErrorPrototype;
68   class TypeError;
69   class TypeErrorPrototype;
70   class UriError;
71   class UriErrorPrototype;
72   
73   /**
74    * Interpreter objects can be used to evaluate ECMAScript code. Each
75    * interpreter has a global object which is used for the purposes of code
76    * evaluation, and also provides access to built-in properties such as
77    * " Object" and "Number".
78    */
79   class Interpreter : public RefCounted<Interpreter> {
80       friend class Collector;
81   public:
82     /**
83      * Creates a new interpreter. The supplied object will be used as the global
84      * object for all scripts executed with this interpreter. During
85      * constuction, all the standard properties such as "Object" and "Number"
86      * will be added to the global object.
87      *
88      * Note: You should not use the same global object for multiple
89      * interpreters.
90      *
91      * This is due do the fact that the built-in properties are set in the
92      * constructor, and if these objects have been modified from another
93      * interpreter (e.g. a script modifying String.prototype), the changes will
94      * be overridden.
95      *
96      * @param global The object to use as the global object for this interpreter
97      */
98     Interpreter(JSGlobalObject*);
99     /**
100      * Creates a new interpreter. A global object will be created and
101      * initialized with the standard global properties.
102      */
103     Interpreter();
104     
105     virtual ~Interpreter(); // only deref should delete us
106
107     /**
108      * Resets the global object's default properties and adds the default object 
109      * prototype to its prototype chain.
110      */
111     void initGlobalObject();
112
113     /**
114      * Returns the object that is used as the global object during all script
115      * execution performed by this interpreter
116      */
117     JSGlobalObject* globalObject() const;
118
119     /**
120      * Returns the execution state object which can be used to execute
121      * scripts using this interpreter at a the "global" level, i.e. one
122      * with a execution context that has the global object as the "this"
123      * value, and who's scope chain contains only the global object.
124      *
125      * Note: this pointer remains constant for the life of the interpreter
126      * and should not be manually deleted.
127      *
128      * @return The interpreter global execution state object
129      */
130     virtual ExecState *globalExec();
131
132     /**
133      * Parses the supplied ECMAScript code and checks for syntax errors.
134      *
135      * @param code The code to check
136      * @return A normal completion if there were no syntax errors in the code, 
137      * otherwise a throw completion with the syntax error as its value.
138      */
139     Completion checkSyntax(const UString& sourceURL, int startingLineNumber, const UString& code);
140     Completion checkSyntax(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength);
141
142     /**
143      * Evaluates the supplied ECMAScript code.
144      *
145      * Since this method returns a Completion, you should check the type of
146      * completion to detect an error or before attempting to access the returned
147      * value. For example, if an error occurs during script execution and is not
148      * caught by the script, the completion type will be Throw.
149      *
150      * If the supplied code is invalid, a SyntaxError will be thrown.
151      *
152      * @param code The code to evaluate
153      * @param thisV The value to pass in as the "this" value for the script
154      * execution. This should either be jsNull() or an Object.
155      * @return A completion object representing the result of the execution.
156      */
157     Completion evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0);
158     Completion evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0);
159
160     /**
161      * Returns the builtin "Object" object. This is the object that was set
162      * as a property of the global object during construction; if the property
163      * is replaced by script code, this method will still return the original
164      * object.
165      *
166      * @return The builtin "Object" object
167      */
168     JSObject *builtinObject() const;
169
170     /**
171      * Returns the builtin "Function" object.
172      */
173     JSObject *builtinFunction() const;
174
175     /**
176      * Returns the builtin "Array" object.
177      */
178     JSObject *builtinArray() const;
179
180     /**
181      * Returns the builtin "Boolean" object.
182      */
183     JSObject *builtinBoolean() const;
184
185     /**
186      * Returns the builtin "String" object.
187      */
188     JSObject *builtinString() const;
189
190     /**
191      * Returns the builtin "Number" object.
192      */
193     JSObject *builtinNumber() const;
194
195     /**
196      * Returns the builtin "Date" object.
197      */
198     JSObject *builtinDate() const;
199
200     /**
201      * Returns the builtin "RegExp" object.
202      */
203     RegExpObjectImp* builtinRegExp() const { return m_RegExp; }
204
205     /**
206      * Returns the builtin "Error" object.
207      */
208     JSObject *builtinError() const;
209
210     /**
211      * Returns the builtin "Object.prototype" object.
212      */
213     JSObject *builtinObjectPrototype() const;
214
215     /**
216      * Returns the builtin "Function.prototype" object.
217      */
218     JSObject *builtinFunctionPrototype() const;
219
220     /**
221      * Returns the builtin "Array.prototype" object.
222      */
223     JSObject *builtinArrayPrototype() const;
224
225     /**
226      * Returns the builtin "Boolean.prototype" object.
227      */
228     JSObject *builtinBooleanPrototype() const;
229
230     /**
231      * Returns the builtin "String.prototype" object.
232      */
233     JSObject *builtinStringPrototype() const;
234
235     /**
236      * Returns the builtin "Number.prototype" object.
237      */
238     JSObject *builtinNumberPrototype() const;
239
240     /**
241      * Returns the builtin "Date.prototype" object.
242      */
243     JSObject *builtinDatePrototype() const;
244
245     /**
246      * Returns the builtin "RegExp.prototype" object.
247      */
248     JSObject *builtinRegExpPrototype() const;
249
250     /**
251      * Returns the builtin "Error.prototype" object.
252      */
253     JSObject *builtinErrorPrototype() const;
254
255     /**
256      * The initial value of "Error" global property
257      */
258     JSObject *builtinEvalError() const;
259     JSObject *builtinRangeError() const;
260     JSObject *builtinReferenceError() const;
261     JSObject *builtinSyntaxError() const;
262     JSObject *builtinTypeError() const;
263     JSObject *builtinURIError() const;
264
265     JSObject *builtinEvalErrorPrototype() const;
266     JSObject *builtinRangeErrorPrototype() const;
267     JSObject *builtinReferenceErrorPrototype() const;
268     JSObject *builtinSyntaxErrorPrototype() const;
269     JSObject *builtinTypeErrorPrototype() const;
270     JSObject *builtinURIErrorPrototype() const;
271
272     enum CompatMode { NativeMode, IECompat, NetscapeCompat };
273     /**
274      * Call this to enable a compatibility mode with another browser.
275      * (by default konqueror is in "native mode").
276      * Currently, in KJS, this only changes the behavior of Date::getYear()
277      * which returns the full year under IE.
278      */
279     void setCompatMode(CompatMode mode) { m_compatMode = mode; }
280     CompatMode compatMode() const { return m_compatMode; }
281     
282     /**
283      * Run the garbage collection. Returns true when at least one object
284      * was collected; false otherwise.
285      */
286     static bool collect();
287
288     /**
289      * Called during the mark phase of the garbage collector. Subclasses 
290      * implementing custom mark methods must make sure to chain to this one.
291      */
292     virtual void mark();
293
294     static bool shouldPrintExceptions();
295     static void setShouldPrintExceptions(bool);
296
297     void saveBuiltins (SavedBuiltins&) const;
298     void restoreBuiltins (const SavedBuiltins&);
299     
300     /**
301      * Determine if the it is 'safe' to execute code in the target interpreter from an
302      * object that originated in this interpreter.  This check is used to enforce WebCore
303      * cross frame security rules.  In particular, attempts to access 'bound' objects are
304      * not allowed unless isSafeScript returns true.
305      */
306     virtual bool isSafeScript(const Interpreter*) { return true; }
307   
308     // Chained list of interpreters (ring)
309     static Interpreter* firstInterpreter() { return s_hook; }
310     Interpreter* nextInterpreter() const { return next; }
311     Interpreter* prevInterpreter() const { return prev; }
312
313     Debugger* debugger() const { return m_debugger; }
314     void setDebugger(Debugger* d) { m_debugger = d; }
315     
316     void setCurrentExec(ExecState* exec) { m_currentExec = exec; }
317     ExecState* currentExec() const { return m_currentExec; }
318         
319     void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
320
321     void startTimeoutCheck();
322     void stopTimeoutCheck();
323     
324     bool timedOut();
325     
326 protected:
327     virtual bool shouldInterruptScript() const { return true; }
328
329     unsigned m_timeoutTime;
330
331 private:
332     void init();
333
334     void resetTimeoutCheck();
335     bool checkTimeout();
336
337     // Uncopyable
338     Interpreter(const Interpreter&);
339     Interpreter operator=(const Interpreter&);
340     
341     ExecState* m_currentExec;
342     JSGlobalObject* m_globalObject;
343     ExecState m_globalExec;
344
345     // Chained list of interpreters (ring) - for collector
346     static Interpreter* s_hook;
347     Interpreter *next, *prev;
348     
349     int m_recursion;
350     
351     Debugger* m_debugger;
352     CompatMode m_compatMode;
353
354     unsigned m_timeAtLastCheckTimeout;
355     unsigned m_timeExecuting;
356     unsigned m_timeoutCheckCount;
357     
358     unsigned m_tickCount;
359     unsigned m_ticksUntilNextTimeoutCheck;
360
361
362     ObjectObjectImp* m_Object;
363     FunctionObjectImp* m_Function;
364     ArrayObjectImp* m_Array;
365     BooleanObjectImp* m_Boolean;
366     StringObjectImp* m_String;
367     NumberObjectImp* m_Number;
368     DateObjectImp* m_Date;
369     RegExpObjectImp* m_RegExp;
370     ErrorObjectImp* m_Error;
371     
372     ObjectPrototype* m_ObjectPrototype;
373     FunctionPrototype* m_FunctionPrototype;
374     ArrayPrototype* m_ArrayPrototype;
375     BooleanPrototype* m_BooleanPrototype;
376     StringPrototype* m_StringPrototype;
377     NumberPrototype* m_NumberPrototype;
378     DatePrototype* m_DatePrototype;
379     RegExpPrototype* m_RegExpPrototype;
380     ErrorPrototype* m_ErrorPrototype;
381     
382     NativeErrorImp* m_EvalError;
383     NativeErrorImp* m_RangeError;
384     NativeErrorImp* m_ReferenceError;
385     NativeErrorImp* m_SyntaxError;
386     NativeErrorImp* m_TypeError;
387     NativeErrorImp* m_UriError;
388     
389     NativeErrorPrototype* m_EvalErrorPrototype;
390     NativeErrorPrototype* m_RangeErrorPrototype;
391     NativeErrorPrototype* m_ReferenceErrorPrototype;
392     NativeErrorPrototype* m_SyntaxErrorPrototype;
393     NativeErrorPrototype* m_TypeErrorPrototype;
394     NativeErrorPrototype* m_UriErrorPrototype;
395   };
396
397   inline bool Interpreter::timedOut()
398   {
399       m_tickCount++;
400       
401       if (m_tickCount != m_ticksUntilNextTimeoutCheck)
402           return false;
403       
404       return checkTimeout();
405   }
406   
407 } // namespace
408
409 #endif // _KJS_INTERPRETER_H_