]> git.saurik.com Git - apple/javascriptcore.git/blame - kjs/ExecState.h
JavaScriptCore-461.tar.gz
[apple/javascriptcore.git] / kjs / ExecState.h
CommitLineData
b37bf2e1
A
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, 2008 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 "completion.h"
30#include "list.h"
31#include "scope_chain.h"
32
33namespace KJS {
34
35 class ActivationImp;
36 class CommonIdentifiers;
37 class EvalNode;
38 class FunctionBodyNode;
39 class FunctionImp;
40 class GlobalFuncImp;
41 class Interpreter;
42 class JSGlobalObject;
43 class JSVariableObject;
44 class ProgramNode;
45 class ScopeNode;
46
47 enum CodeType { GlobalCode, EvalCode, FunctionCode };
48
49 typedef Vector<ExecState*, 16> ExecStateStack;
50
51 // Represents the current state of script execution.
52 // Passed as the first argument to most functions.
53 class ExecState : Noncopyable {
54 public:
55 // Global object that was in scope when the current script started executing.
56 JSGlobalObject* dynamicGlobalObject() const { return m_globalObject; }
57
58 // Global object that was in scope when the current body of code was defined.
59 JSGlobalObject* lexicalGlobalObject() const;
60
61 void setException(JSValue* e) { m_exception = e; }
62 void clearException() { m_exception = 0; }
63 JSValue* exception() const { return m_exception; }
64 JSValue** exceptionSlot() { return &m_exception; }
65 bool hadException() const { return !!m_exception; }
66
67 const ScopeChain& scopeChain() const { return m_scopeChain; }
68 void pushScope(JSObject* s) { m_scopeChain.push(s); }
69 void popScope() { m_scopeChain.pop(); }
70 void replaceScopeChainTop(JSObject* o) { m_scopeChain.replaceTop(o); }
71
72 JSVariableObject* variableObject() const { return m_variableObject; }
73 void setVariableObject(JSVariableObject* v) { m_variableObject = v; }
74
75 JSObject* thisValue() const { return m_thisValue; }
76
77 ExecState* callingExecState() { return m_callingExec; }
78
79 ActivationImp* activationObject() { return m_activation; }
80 void setActivationObject(ActivationImp* a) { m_activation = a; }
81 CodeType codeType() { return m_codeType; }
82 ScopeNode* scopeNode() { return m_scopeNode; }
83 FunctionImp* function() const { return m_function; }
84 const List* arguments() const { return m_arguments; }
85
86 LabelStack& seenLabels() { return m_labelStack; }
87
88 void pushIteration() { m_iterationDepth++; }
89 void popIteration() { m_iterationDepth--; }
90 bool inIteration() const { return (m_iterationDepth > 0); }
91
92 void pushSwitch() { m_switchDepth++; }
93 void popSwitch() { m_switchDepth--; }
94 bool inSwitch() const { return (m_switchDepth > 0); }
95
96 // These pointers are used to avoid accessing global variables for these,
97 // to avoid taking PIC branches in Mach-O binaries.
98 const CommonIdentifiers& propertyNames() const { return *m_propertyNames; }
99 const List& emptyList() const { return *m_emptyList; }
100
101 LocalStorage& localStorage() { return *m_localStorage; }
102 void setLocalStorage(LocalStorage* s) { m_localStorage = s; }
103
104 // These are only valid right after calling execute().
105 ComplType completionType() const { return m_completionType; }
106 const Identifier& breakOrContinueTarget() const
107 {
108 ASSERT(m_completionType == Break || m_completionType == Continue);
109 return *m_breakOrContinueTarget;
110 }
111
112 // Only for use in the implementation of execute().
113 void setCompletionType(ComplType type)
114 {
115 ASSERT(type != Break);
116 ASSERT(type != Continue);
117 m_completionType = type;
118 }
119 JSValue* setNormalCompletion()
120 {
121 ASSERT(!hadException());
122 m_completionType = Normal;
123 return 0;
124 }
125 JSValue* setNormalCompletion(JSValue* value)
126 {
127 ASSERT(!hadException());
128 m_completionType = Normal;
129 return value;
130 }
131 JSValue* setBreakCompletion(const Identifier* target)
132 {
133 ASSERT(!hadException());
134 m_completionType = Break;
135 m_breakOrContinueTarget = target;
136 return 0;
137 }
138 JSValue* setContinueCompletion(const Identifier* target)
139 {
140 ASSERT(!hadException());
141 m_completionType = Continue;
142 m_breakOrContinueTarget = target;
143 return 0;
144 }
145 JSValue* setReturnValueCompletion(JSValue* returnValue)
146 {
147 ASSERT(!hadException());
148 ASSERT(returnValue);
149 m_completionType = ReturnValue;
150 return returnValue;
151 }
152 JSValue* setThrowCompletion(JSValue* exception)
153 {
154 ASSERT(!hadException());
155 ASSERT(exception);
156 m_completionType = Throw;
157 return exception;
158 }
159 JSValue* setInterruptedCompletion()
160 {
161 ASSERT(!hadException());
162 m_completionType = Interrupted;
163 return 0;
164 }
165 JSValue* setInterruptedCompletion(JSValue* returnValue)
166 {
167 ASSERT(!hadException());
168 ASSERT(returnValue);
169 m_completionType = Interrupted;
170 return returnValue;
171 }
172
173 static void markActiveExecStates();
174 static ExecStateStack& activeExecStates();
175
176 protected:
177 ExecState(JSGlobalObject*);
178 ExecState(JSGlobalObject*, JSObject* thisObject, ProgramNode*);
179 ExecState(JSGlobalObject*, EvalNode*, ExecState* callingExecState);
180 ExecState(JSGlobalObject*, JSObject* thisObject, FunctionBodyNode*,
181 ExecState* callingExecState, FunctionImp*, const List& args);
182 ~ExecState();
183
184 // ExecStates are always stack-allocated, and the garbage collector
185 // marks the stack, so we don't need to protect the objects below from GC.
186
187 JSGlobalObject* m_globalObject;
188 JSValue* m_exception;
189 CommonIdentifiers* m_propertyNames;
190 const List* m_emptyList;
191
192 ExecState* m_callingExec;
193
194 ScopeNode* m_scopeNode;
195
196 FunctionImp* m_function;
197 const List* m_arguments;
198 ActivationImp* m_activation;
199 LocalStorage* m_localStorage;
200
201 ScopeChain m_scopeChain;
202 JSVariableObject* m_variableObject;
203 JSObject* m_thisValue;
204
205 LabelStack m_labelStack;
206 int m_iterationDepth;
207 int m_switchDepth;
208 CodeType m_codeType;
209
210 ComplType m_completionType;
211 const Identifier* m_breakOrContinueTarget;
212 };
213
214 class GlobalExecState : public ExecState {
215 public:
216 GlobalExecState(JSGlobalObject*);
217 ~GlobalExecState();
218 };
219
220 class InterpreterExecState : public ExecState {
221 public:
222 InterpreterExecState(JSGlobalObject*, JSObject* thisObject, ProgramNode*);
223 ~InterpreterExecState();
224 };
225
226 class EvalExecState : public ExecState {
227 public:
228 EvalExecState(JSGlobalObject*, EvalNode*, ExecState* callingExecState);
229 ~EvalExecState();
230 };
231
232 class FunctionExecState : public ExecState {
233 public:
234 FunctionExecState(JSGlobalObject*, JSObject* thisObject, FunctionBodyNode*,
235 ExecState* callingExecState, FunctionImp*, const List& args);
236 ~FunctionExecState();
237 };
238
239} // namespace KJS
240
241#endif // ExecState_h