JavaScriptCore:
[WebKit.git] / JavaScriptCore / kjs / ExecState.h
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
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 ExecState_H
25 #define ExecState_H
26
27 #include "LabelStack.h"
28 #include "LocalStorage.h"
29 #include "scope_chain.h"
30 #include "types.h"
31
32 namespace KJS  {
33
34     enum CodeType {
35         GlobalCode,
36         EvalCode,
37         FunctionCode,
38     };
39     
40     class ActivationImp;
41     class CommonIdentifiers;
42     class EvalNode;
43     class FunctionBodyNode;
44     class FunctionImp;
45     class GlobalFuncImp;
46     class Interpreter;
47     class JSGlobalObject;
48     class JSVariableObject;
49     class ProgramNode;
50     class ScopeChain;
51     class ScopeNode;
52     struct LocalStorageEntry;
53     
54     /**
55      * Represents the current state of script execution. This is
56      * passed as the first argument to most functions.
57      */
58     class ExecState {
59         friend class Interpreter;
60         friend class FunctionImp;
61         friend class GlobalFuncImp;
62     public:
63         /**
64          * Returns the global object that was in scope when the current script started executing.
65          */
66         JSGlobalObject* dynamicGlobalObject() const { return m_globalObject; }
67         
68         /**
69          * Returns the global object that was in scope when the current body of code was defined.
70          */
71         JSGlobalObject* lexicalGlobalObject() const;
72                 
73         void setException(JSValue* e) { m_exception = e; }
74         void clearException() { m_exception = 0; }
75         JSValue* exception() const { return m_exception; }
76         JSValue** exceptionSlot() { return &m_exception; }
77         bool hadException() const { return !!m_exception; }
78         
79         const ScopeChain& scopeChain() const { return m_scopeChain; }
80         void replaceScopeChainTop(JSObject* o) { m_scopeChain.replaceTop(o); }
81         
82         JSVariableObject* variableObject() const { return m_variableObject; }
83         void setVariableObject(JSVariableObject* v) { m_variableObject = v; }
84         
85         JSObject* thisValue() const { return m_thisVal; }
86         
87         ExecState* callingExecState() { return m_callingExec; }
88         ExecState* savedExec() { return m_savedExec; }
89         
90         ActivationImp* activationObject() { return m_activation; }
91         void setActivationObject(ActivationImp* a) { m_activation = a; }
92         CodeType codeType() { return m_codeType; }
93         ScopeNode* scopeNode() { return m_scopeNode; }
94         FunctionImp* function() const { return m_function; }
95         const List* arguments() const { return m_arguments; }
96         
97         void pushScope(JSObject* s) { m_scopeChain.push(s); }
98         void popScope() { m_scopeChain.pop(); }
99         LabelStack* seenLabels() { return &ls; }
100         
101         void pushIteration() { m_iterationDepth++; }
102         void popIteration() { m_iterationDepth--; }
103         bool inIteration() const { return (m_iterationDepth > 0); }
104         
105         void pushSwitch() { m_switchDepth++; }
106         void popSwitch() { m_switchDepth--; }
107         bool inSwitch() const { return (m_switchDepth > 0); }
108
109         void mark();
110         
111         // These pointers are used to avoid accessing global variables for these,
112         // to avoid taking PIC branches in Mach-O binaries.
113         const CommonIdentifiers& propertyNames() const { return *m_propertyNames; }
114         const List& emptyList() const { return *m_emptyList; }
115
116         LocalStorage& localStorage() { return *m_localStorage; }
117         void setLocalStorage(LocalStorage* s) { m_localStorage = s; }
118
119         // These are only valid right after calling execute().
120         ComplType completionType() const { return m_completionType; }
121         const Identifier& breakOrContinueTarget() const
122         {
123             ASSERT(m_completionType == Break || m_completionType == Continue);
124             return *m_breakOrContinueTarget;
125         }
126
127         // Only for use in the implementation of execute().
128         void setCompletionType(ComplType type)
129         {
130             ASSERT(type != Break);
131             ASSERT(type != Continue);
132             m_completionType = type;
133         }
134         JSValue* setNormalCompletion()
135         {
136             ASSERT(!hadException());
137             m_completionType = Normal;
138             return 0;
139         }
140         JSValue* setNormalCompletion(JSValue* value)
141         {
142             ASSERT(!hadException());
143             m_completionType = Normal;
144             return value;
145         }
146         JSValue* setBreakCompletion(const Identifier* target)
147         {
148             ASSERT(!hadException());
149             m_completionType = Break;
150             m_breakOrContinueTarget = target;
151             return 0;
152         }
153         JSValue* setContinueCompletion(const Identifier* target)
154         {
155             ASSERT(!hadException());
156             m_completionType = Continue;
157             m_breakOrContinueTarget = target;
158             return 0;
159         }
160         JSValue* setReturnValueCompletion(JSValue* returnValue)
161         {
162             ASSERT(!hadException());
163             ASSERT(returnValue);
164             m_completionType = ReturnValue;
165             return returnValue;
166         }
167         JSValue* setThrowCompletion(JSValue* exception)
168         {
169             ASSERT(!hadException());
170             ASSERT(exception);
171             m_completionType = Throw;
172             return exception;
173         }
174         JSValue* setInterruptedCompletion()
175         {
176             ASSERT(!hadException());
177             m_completionType = Interrupted;
178             return 0;
179         }
180
181         ExecState(JSGlobalObject*, JSObject* thisObject, ProgramNode*);
182         ExecState(JSGlobalObject*, EvalNode*, ExecState* callingExecState);
183         ExecState(JSGlobalObject*, JSObject* thisObject, FunctionBodyNode*,
184             ExecState* callingExecState, FunctionImp*, const List& args);
185         ~ExecState();
186
187     private:
188         // ExecStates are always stack-allocated, and the garbage collector
189         // marks the stack, so we don't need to protect the objects below from GC.
190
191         JSGlobalObject* m_globalObject;
192         JSValue* m_exception;
193         CommonIdentifiers* m_propertyNames;
194         const List* m_emptyList;
195
196         ExecState* m_callingExec;
197         ExecState* m_savedExec;
198         ScopeNode* m_scopeNode;
199         
200         FunctionImp* m_function;
201         const List* m_arguments;
202         ActivationImp* m_activation;
203         LocalStorage* m_localStorage;
204
205         ScopeChain m_scopeChain;
206         JSVariableObject* m_variableObject;
207         JSObject* m_thisVal;
208         
209         LabelStack ls;
210         int m_iterationDepth;
211         int m_switchDepth;
212         CodeType m_codeType;
213
214         ComplType m_completionType;
215         const Identifier* m_breakOrContinueTarget;
216     };
217
218 } // namespace KJS
219
220 #endif // ExecState_H