defb1d6aec602f615d5b2bf5f96056eea4899e87
[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 "value.h"
28 #include "types.h"
29
30 namespace KJS {
31
32   class Context;
33   class InterpreterImp;
34   class RuntimeMethod;
35   class ScopeChain;
36
37   namespace Bindings {
38     class RootObject;
39   }
40
41   class SavedBuiltinsInternal;
42
43   class SavedBuiltins {
44     friend class InterpreterImp;
45   public:
46     SavedBuiltins();
47     ~SavedBuiltins();
48   private:
49     SavedBuiltinsInternal *_internal;
50   };
51
52   /**
53    * Interpreter objects can be used to evaluate ECMAScript code. Each
54    * interpreter has a global object which is used for the purposes of code
55    * evaluation, and also provides access to built-in properties such as
56    * " Object" and "Number".
57    */
58   class Interpreter {
59   public:
60     /**
61      * Creates a new interpreter. The supplied object will be used as the global
62      * object for all scripts executed with this interpreter. During
63      * constuction, all the standard properties such as "Object" and "Number"
64      * will be added to the global object.
65      *
66      * Note: You should not use the same global object for multiple
67      * interpreters.
68      *
69      * This is due do the fact that the built-in properties are set in the
70      * constructor, and if these objects have been modified from another
71      * interpreter (e.g. a script modifying String.prototype), the changes will
72      * be overridden.
73      *
74      * @param global The object to use as the global object for this interpreter
75      */
76     Interpreter(JSObject *global);
77     /**
78      * Creates a new interpreter. A global object will be created and
79      * initialized with the standard global properties.
80      */
81     Interpreter();
82     virtual ~Interpreter();
83
84     /**
85      * Returns the object that is used as the global object during all script
86      * execution performed by this interpreter
87      */
88     JSObject *globalObject() const;
89
90     void initGlobalObject();
91
92     /**
93      * Returns the execution state object which can be used to execute
94      * scripts using this interpreter at a the "global" level, i.e. one
95      * with a execution context that has the global object as the "this"
96      * value, and who's scope chain contains only the global object.
97      *
98      * Note: this pointer remains constant for the life of the interpreter
99      * and should not be manually deleted.
100      *
101      * @return The interpreter global execution state object
102      */
103     virtual ExecState *globalExec();
104
105     /**
106      * Parses the supplied ECMAScript code and checks for syntax errors.
107      *
108      * @param code The code to check
109      * @return true if there were no syntax errors in the code, otherwise false
110      */
111     bool checkSyntax(const UString &code);
112
113     /**
114      * Evaluates the supplied ECMAScript code.
115      *
116      * Since this method returns a Completion, you should check the type of
117      * completion to detect an error or before attempting to access the returned
118      * value. For example, if an error occurs during script execution and is not
119      * caught by the script, the completion type will be Throw.
120      *
121      * If the supplied code is invalid, a SyntaxError will be thrown.
122      *
123      * @param code The code to evaluate
124      * @param thisV The value to pass in as the "this" value for the script
125      * execution. This should either be jsNull() or an Object.
126      * @return A completion object representing the result of the execution.
127      */
128     Completion evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0);
129     Completion evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0);
130
131     /**
132      * @internal
133      *
134      * Returns the implementation object associated with this interpreter.
135      * Only useful for internal KJS operations.
136      */
137     InterpreterImp *imp() const { return rep; }
138
139     /**
140      * Returns the builtin "Object" object. This is the object that was set
141      * as a property of the global object during construction; if the property
142      * is replaced by script code, this method will still return the original
143      * object.
144      *
145      * @return The builtin "Object" object
146      */
147     JSObject *builtinObject() const;
148
149     /**
150      * Returns the builtin "Function" object.
151      */
152     JSObject *builtinFunction() const;
153
154     /**
155      * Returns the builtin "Array" object.
156      */
157     JSObject *builtinArray() const;
158
159     /**
160      * Returns the builtin "Boolean" object.
161      */
162     JSObject *builtinBoolean() const;
163
164     /**
165      * Returns the builtin "String" object.
166      */
167     JSObject *builtinString() const;
168
169     /**
170      * Returns the builtin "Number" object.
171      */
172     JSObject *builtinNumber() const;
173
174     /**
175      * Returns the builtin "Date" object.
176      */
177     JSObject *builtinDate() const;
178
179     /**
180      * Returns the builtin "RegExp" object.
181      */
182     JSObject *builtinRegExp() const;
183
184     /**
185      * Returns the builtin "Error" object.
186      */
187     JSObject *builtinError() const;
188
189     /**
190      * Returns the builtin "Object.prototype" object.
191      */
192     JSObject *builtinObjectPrototype() const;
193
194     /**
195      * Returns the builtin "Function.prototype" object.
196      */
197     JSObject *builtinFunctionPrototype() const;
198
199     /**
200      * Returns the builtin "Array.prototype" object.
201      */
202     JSObject *builtinArrayPrototype() const;
203
204     /**
205      * Returns the builtin "Boolean.prototype" object.
206      */
207     JSObject *builtinBooleanPrototype() const;
208
209     /**
210      * Returns the builtin "String.prototype" object.
211      */
212     JSObject *builtinStringPrototype() const;
213
214     /**
215      * Returns the builtin "Number.prototype" object.
216      */
217     JSObject *builtinNumberPrototype() const;
218
219     /**
220      * Returns the builtin "Date.prototype" object.
221      */
222     JSObject *builtinDatePrototype() const;
223
224     /**
225      * Returns the builtin "RegExp.prototype" object.
226      */
227     JSObject *builtinRegExpPrototype() const;
228
229     /**
230      * Returns the builtin "Error.prototype" object.
231      */
232     JSObject *builtinErrorPrototype() const;
233
234     /**
235      * The initial value of "Error" global property
236      */
237     JSObject *builtinEvalError() const;
238     JSObject *builtinRangeError() const;
239     JSObject *builtinReferenceError() const;
240     JSObject *builtinSyntaxError() const;
241     JSObject *builtinTypeError() const;
242     JSObject *builtinURIError() const;
243
244     JSObject *builtinEvalErrorPrototype() const;
245     JSObject *builtinRangeErrorPrototype() const;
246     JSObject *builtinReferenceErrorPrototype() const;
247     JSObject *builtinSyntaxErrorPrototype() const;
248     JSObject *builtinTypeErrorPrototype() const;
249     JSObject *builtinURIErrorPrototype() const;
250
251     enum CompatMode { NativeMode, IECompat, NetscapeCompat };
252     /**
253      * Call this to enable a compatibility mode with another browser.
254      * (by default konqueror is in "native mode").
255      * Currently, in KJS, this only changes the behavior of Date::getYear()
256      * which returns the full year under IE.
257      */
258     void setCompatMode(CompatMode mode);
259     CompatMode compatMode() const;
260
261     /**
262      * Run the garbage collection. Returns true when at least one object
263      * was collected; false otherwise.
264      */
265     static bool collect();
266
267     /**
268      * Called by InterpreterImp during the mark phase of the garbage collector
269      * Default implementation does nothing, this exist for classes that reimplement Interpreter.
270      */
271     virtual void mark(bool currentThreadIsMainThread);
272
273     /**
274      * Provides a way to distinguish derived classes.
275      * Only useful if you reimplement Interpreter and if different kind of
276      * interpreters are created in the same process.
277      * The base class returns 0, the ECMA-bindings interpreter returns 1.
278      */
279     virtual int rtti() { return 0; }
280
281 #ifdef KJS_DEBUG_MEM
282     /**
283      * @internal
284      */
285     static void finalCheck();
286 #endif
287
288     static bool shouldPrintExceptions();
289     static void setShouldPrintExceptions(bool);
290
291     void saveBuiltins (SavedBuiltins &) const;
292     void restoreBuiltins (const SavedBuiltins &);
293
294     /**
295      * Determine if the value is a global object (for any interpreter).  This may
296      * be difficult to determine for multiple uses of JSC in a process that are
297      * logically independent of each other.  In the case of WebCore, this method
298      * is used to determine if an object is the Window object so we can perform
299      * security checks.
300      */
301     virtual bool isGlobalObject(JSValue*) { return false; }
302     
303     /** 
304      * Find the interpreter for a particular global object.  This should really
305      * be a static method, but we can't do that is C++.  Again, as with isGlobalObject()
306      * implementation really need to know about all instances of Interpreter
307      * created in an application to correctly implement this method.  The only
308      * override of this method is currently in WebCore.
309      */
310     virtual Interpreter* interpreterForGlobalObject(const JSValue*) { return 0; }
311     
312     /**
313      * Determine if the it is 'safe' to execute code in the target interpreter from an
314      * object that originated in this interpreter.  This check is used to enforce WebCore
315      * cross frame security rules.  In particular, attempts to access 'bound' objects are
316      * not allowed unless isSafeScript returns true.
317      */
318     virtual bool isSafeScript(const Interpreter*) { return true; }
319   
320 #if PLATFORM(MAC)
321     virtual void *createLanguageInstanceForValue(ExecState*, int language, JSObject* value, const Bindings::RootObject* origin, const Bindings::RootObject* current);
322 #endif
323
324     // This is a workaround to avoid accessing the global variables for these identifiers in
325     // important property lookup functions, to avoid taking PIC branches in Mach-O binaries
326     const Identifier& argumentsIdentifier() { return *m_argumentsPropertyName; }
327     const Identifier& specialPrototypeIdentifier() { return *m_specialPrototypePropertyName; }
328     
329   private:
330     InterpreterImp *rep;
331
332     const Identifier *m_argumentsPropertyName;
333     const Identifier *m_specialPrototypePropertyName;
334
335     /**
336      * This constructor is not implemented, in order to prevent
337      * copy-construction of Interpreter objects. You should always pass around
338      * pointers to an interpreter instance instead.
339      */
340     Interpreter(const Interpreter&);
341
342     /**
343      * This constructor is not implemented, in order to prevent assignment of
344      * Interpreter objects. You should always pass around pointers to an
345      * interpreter instance instead.
346      */
347     Interpreter operator=(const Interpreter&);
348   };
349
350   /**
351    * Represents the current state of script execution. This object allows you
352    * obtain a handle the interpreter that is currently executing the script,
353    * and also the current execution state context.
354    */
355   class ExecState {
356     friend class InterpreterImp;
357     friend class FunctionImp;
358     friend class RuntimeMethodImp;
359     friend class GlobalFuncImp;
360   public:
361     /**
362      * Returns the interpreter associated with this execution state
363      *
364      * @return The interpreter executing the script
365      */
366     Interpreter *dynamicInterpreter() const { return m_interpreter; }
367
368     /**
369      * Returns the interpreter associated with the current scope's
370      * global object
371      *
372      * @return The interpreter currently in scope
373      */
374     Interpreter *lexicalInterpreter() const;
375
376     /**
377      * Returns the execution context associated with this execution state
378      *
379      * @return The current execution state context
380      */
381     Context* context() const { return m_context; }
382
383     void setException(JSValue* e) { m_exception = e; }
384     void clearException() { m_exception = 0; }
385     JSValue* exception() const { return m_exception; }
386     bool hadException() const { return m_exception; }
387
388   private:
389     ExecState(Interpreter* interp, Context* con)
390         : m_interpreter(interp)
391         , m_context(con)
392         , m_exception(0)
393     { 
394     }
395     Interpreter* m_interpreter;
396     Context* m_context;
397     JSValue* m_exception;
398   };
399
400 } // namespace
401
402 #endif // _KJS_INTERPRETER_H_