]> git.saurik.com Git - apple/javascriptcore.git/blob - kjs/ExecState.cpp
JavaScriptCore-466.1.tar.gz
[apple/javascriptcore.git] / kjs / ExecState.cpp
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 #include "config.h"
25 #include "ExecState.h"
26
27 #include "Activation.h"
28 #include "JSGlobalObject.h"
29 #include "function.h"
30 #include "internal.h"
31 #include "scope_chain_mark.h"
32
33 namespace KJS {
34
35 static inline List* globalEmptyList()
36 {
37 static List staticEmptyList;
38 return &staticEmptyList;
39 }
40
41 // ECMA 10.2
42
43 // The constructor for the globalExec pseudo-ExecState
44 inline ExecState::ExecState(JSGlobalObject* globalObject)
45 : m_globalObject(globalObject)
46 , m_exception(0)
47 , m_propertyNames(CommonIdentifiers::shared())
48 , m_emptyList(globalEmptyList())
49 , m_callingExec(0)
50 , m_scopeNode(0)
51 , m_function(0)
52 , m_arguments(0)
53 , m_activation(0)
54 , m_localStorage(&globalObject->localStorage())
55 , m_variableObject(globalObject)
56 , m_thisValue(globalObject)
57 , m_iterationDepth(0)
58 , m_switchDepth(0)
59 , m_codeType(GlobalCode)
60 {
61 m_scopeChain.push(globalObject);
62 }
63
64 inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* /*thisObject*/, ProgramNode* programNode)
65 : m_globalObject(globalObject)
66 , m_exception(0)
67 , m_propertyNames(CommonIdentifiers::shared())
68 , m_emptyList(globalEmptyList())
69 , m_callingExec(0)
70 , m_scopeNode(programNode)
71 , m_function(0)
72 , m_arguments(0)
73 , m_activation(0)
74 , m_localStorage(&globalObject->localStorage())
75 , m_variableObject(globalObject)
76 , m_thisValue(globalObject)
77 , m_iterationDepth(0)
78 , m_switchDepth(0)
79 , m_codeType(GlobalCode)
80 {
81 // FIXME: This function ignores the "thisObject" parameter, which means that the API for evaluating
82 // a script with a this object that's not the same as the global object is broken, and probably
83 // has been for some time.
84 ASSERT(m_scopeNode);
85 m_scopeChain.push(globalObject);
86 }
87
88 inline ExecState::ExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
89 : m_globalObject(globalObject)
90 , m_exception(0)
91 , m_propertyNames(callingExec->m_propertyNames)
92 , m_emptyList(callingExec->m_emptyList)
93 , m_callingExec(callingExec)
94 , m_scopeNode(evalNode)
95 , m_function(0)
96 , m_arguments(0)
97 , m_activation(0)
98 , m_localStorage(callingExec->m_localStorage)
99 , m_scopeChain(callingExec->m_scopeChain)
100 , m_variableObject(callingExec->m_variableObject)
101 , m_thisValue(callingExec->m_thisValue)
102 , m_iterationDepth(0)
103 , m_switchDepth(0)
104 , m_codeType(EvalCode)
105 {
106 ASSERT(m_scopeNode);
107 }
108
109 inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject,
110 FunctionBodyNode* functionBodyNode, ExecState* callingExec,
111 FunctionImp* func, const List& args)
112 : m_globalObject(globalObject)
113 , m_exception(0)
114 , m_propertyNames(callingExec->m_propertyNames)
115 , m_emptyList(callingExec->m_emptyList)
116 , m_callingExec(callingExec)
117 , m_scopeNode(functionBodyNode)
118 , m_function(func)
119 , m_arguments(&args)
120 , m_scopeChain(func->scope())
121 , m_thisValue(thisObject)
122 , m_iterationDepth(0)
123 , m_switchDepth(0)
124 , m_codeType(FunctionCode)
125 {
126 ASSERT(m_scopeNode);
127
128 ActivationImp* activation = globalObject->pushActivation(this);
129 m_activation = activation;
130 m_localStorage = &activation->localStorage();
131 m_variableObject = activation;
132 m_scopeChain.push(activation);
133 }
134
135 inline ExecState::~ExecState()
136 {
137 }
138
139 JSGlobalObject* ExecState::lexicalGlobalObject() const
140 {
141 JSObject* object = m_scopeChain.bottom();
142 if (object && object->isGlobalObject())
143 return static_cast<JSGlobalObject*>(object);
144 return m_globalObject;
145 }
146
147 void ExecState::markActiveExecStates()
148 {
149 ExecStateStack::const_iterator end = activeExecStates().end();
150 for (ExecStateStack::const_iterator it = activeExecStates().begin(); it != end; ++it)
151 (*it)->m_scopeChain.mark();
152 }
153
154 static inline ExecStateStack& inlineActiveExecStates()
155 {
156 static ExecStateStack staticActiveExecStates;
157 return staticActiveExecStates;
158 }
159
160 ExecStateStack& ExecState::activeExecStates()
161 {
162 return inlineActiveExecStates();
163 }
164
165 GlobalExecState::GlobalExecState(JSGlobalObject* globalObject)
166 : ExecState(globalObject)
167 {
168 }
169
170 GlobalExecState::~GlobalExecState()
171 {
172 }
173
174 InterpreterExecState::InterpreterExecState(JSGlobalObject* globalObject, JSObject* thisObject, ProgramNode* programNode)
175 : ExecState(globalObject, thisObject, programNode)
176 {
177 inlineActiveExecStates().append(this);
178 }
179
180 InterpreterExecState::~InterpreterExecState()
181 {
182 ASSERT(inlineActiveExecStates().last() == this);
183 inlineActiveExecStates().removeLast();
184 }
185
186 EvalExecState::EvalExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
187 : ExecState(globalObject, evalNode, callingExec)
188 {
189 inlineActiveExecStates().append(this);
190 }
191
192 EvalExecState::~EvalExecState()
193 {
194 ASSERT(inlineActiveExecStates().last() == this);
195 inlineActiveExecStates().removeLast();
196 }
197
198 FunctionExecState::FunctionExecState(JSGlobalObject* globalObject, JSObject* thisObject,
199 FunctionBodyNode* functionBodyNode, ExecState* callingExec,
200 FunctionImp* func, const List& args)
201 : ExecState(globalObject, thisObject, functionBodyNode, callingExec, func, args)
202 {
203 inlineActiveExecStates().append(this);
204 }
205
206 FunctionExecState::~FunctionExecState()
207 {
208 ASSERT(inlineActiveExecStates().last() == this);
209 inlineActiveExecStates().removeLast();
210
211 if (m_activation->needsPop())
212 m_globalObject->popActivation();
213 }
214
215 } // namespace KJS