JavaScriptCore:
[WebKit.git] / JavaScriptCore / kjs / ExecState.cpp
1 // -*- mode: c++; c-basic-offset: 4 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
5  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
6  *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Library General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Library General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Library General Public License
19  *  along with this library; see the file COPYING.LIB.  If not, write to
20  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #include "config.h"
26 #include "ExecState.h"
27
28 #include "Activation.h"
29 #include "JSGlobalObject.h"
30 #include "function.h"
31 #include "internal.h"
32 #include "scope_chain_mark.h"
33
34 namespace KJS {
35
36 static inline List* globalEmptyList()
37 {
38     static List staticEmptyList;
39     return &staticEmptyList;
40 }
41
42 // ECMA 10.2
43
44 ExecState::ExecState(JSGlobalObject* globalObject, JSObject* /*thisObject*/, ProgramNode* programNode)
45     : m_globalObject(globalObject)
46     , m_exception(0)
47     , m_propertyNames(CommonIdentifiers::shared())
48     , m_emptyList(globalEmptyList())
49     , m_callingExec(0)
50     , m_savedExec(0)
51     , m_scopeNode(programNode)
52     , m_function(0)
53     , m_arguments(0)
54     , m_activation(0)
55     , m_localStorage(&globalObject->localStorage())
56     , m_variableObject(globalObject)
57     , m_thisVal(globalObject)
58     , m_iterationDepth(0)
59     , m_switchDepth(0) 
60     , m_codeType(GlobalCode)
61 {
62     // FIXME: This function ignores the "thisObject" parameter, which means that the API for evaluating
63     // a script with a this object that's not the same as the global object is broken, and probably
64     // has been for some time.
65     m_scopeChain.push(globalObject);
66     if (programNode)
67         globalObject->setCurrentExec(this);
68 }
69
70 ExecState::ExecState(JSGlobalObject* globalObject, EvalNode* evalNode, ExecState* callingExec)
71     : m_globalObject(globalObject)
72     , m_exception(0)
73     , m_propertyNames(callingExec->m_propertyNames)
74     , m_emptyList(callingExec->m_emptyList)
75     , m_callingExec(callingExec)
76     , m_savedExec(globalObject->currentExec())
77     , m_scopeNode(evalNode)
78     , m_function(0)
79     , m_arguments(0)
80     , m_activation(0)
81     , m_localStorage(callingExec->m_localStorage)
82     , m_scopeChain(callingExec->m_scopeChain)
83     , m_variableObject(callingExec->m_variableObject)
84     , m_thisVal(callingExec->m_thisVal)
85     , m_iterationDepth(0)
86     , m_switchDepth(0) 
87     , m_codeType(EvalCode)
88 {    
89     globalObject->setCurrentExec(this);
90 }
91
92 ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject, 
93                      FunctionBodyNode* functionBodyNode, ExecState* callingExec,
94                      FunctionImp* func, const List& args)
95     : m_globalObject(globalObject)
96     , m_exception(0)
97     , m_propertyNames(callingExec->m_propertyNames)
98     , m_emptyList(callingExec->m_emptyList)
99     , m_callingExec(callingExec)
100     , m_savedExec(globalObject->currentExec())
101     , m_scopeNode(functionBodyNode)
102     , m_function(func)
103     , m_arguments(&args)
104     , m_scopeChain(func->scope())
105     , m_thisVal(thisObject)
106     , m_iterationDepth(0)
107     , m_switchDepth(0) 
108     , m_codeType(FunctionCode)
109 {
110     ActivationImp* activation = globalObject->pushActivation(this);
111     m_activation = activation;
112     m_localStorage = &activation->localStorage();
113     m_variableObject = activation;
114     m_scopeChain.push(activation);
115     globalObject->setCurrentExec(this);
116 }
117
118 ExecState::~ExecState()
119 {
120     if (m_codeType == FunctionCode && m_activation->needsPop())
121         m_globalObject->popActivation();
122     
123     m_globalObject->setCurrentExec(m_savedExec);
124 }
125
126 void ExecState::mark()
127 {
128     for (ExecState* exec = this; exec; exec = exec->m_callingExec)
129         exec->m_scopeChain.mark();
130 }
131
132 JSGlobalObject* ExecState::lexicalGlobalObject() const
133 {
134     if (scopeChain().isEmpty())
135         return dynamicGlobalObject();
136     
137     JSObject* object = scopeChain().bottom();
138     if (object && object->isGlobalObject())
139         return static_cast<JSGlobalObject*>(object);
140
141     return dynamicGlobalObject();
142 }
143
144 } // namespace KJS