• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 *  Copyright (C) 2007 Maks Orlovich
7 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8 *
9 *  This library is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU Library General Public
11 *  License as published by the Free Software Foundation; either
12 *  version 2 of the License, or (at your option) any later version.
13 *
14 *  This library is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *  Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Library General Public License
20 *  along with this library; see the file COPYING.LIB.  If not, write to
21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25 
26 #include "config.h"
27 #include "Nodes.h"
28 #include "NodeConstructors.h"
29 
30 #include "BytecodeGenerator.h"
31 #include "CallFrame.h"
32 #include "Debugger.h"
33 #include "JIT.h"
34 #include "JSFunction.h"
35 #include "JSGlobalObject.h"
36 #include "JSStaticScopeObject.h"
37 #include "LabelScope.h"
38 #include "Lexer.h"
39 #include "Operations.h"
40 #include "Parser.h"
41 #include "PropertyNameArray.h"
42 #include "RegExpObject.h"
43 #include "SamplingTool.h"
44 #include <wtf/Assertions.h>
45 #include <wtf/RefCountedLeakCounter.h>
46 #include <wtf/Threading.h>
47 
48 using namespace WTF;
49 
50 namespace JSC {
51 
52 
53 // ------------------------------ StatementNode --------------------------------
54 
setLoc(int firstLine,int lastLine)55 void StatementNode::setLoc(int firstLine, int lastLine)
56 {
57     m_line = firstLine;
58     m_lastLine = lastLine;
59 }
60 
61 // ------------------------------ SourceElements --------------------------------
62 
append(StatementNode * statement)63 void SourceElements::append(StatementNode* statement)
64 {
65     if (statement->isEmptyStatement())
66         return;
67     m_statements.append(statement);
68 }
69 
singleStatement() const70 StatementNode* SourceElements::singleStatement() const
71 {
72     size_t size = m_statements.size();
73     return size == 1 ? m_statements[0] : 0;
74 }
75 
76 // -----------------------------ScopeNodeData ---------------------------
77 
ScopeNodeData(ParserArena & arena,SourceElements * statements,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,int numConstants)78 ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants)
79     : m_numConstants(numConstants)
80     , m_statements(statements)
81 {
82     m_arena.swap(arena);
83     if (varStack)
84         m_varStack.swap(*varStack);
85     if (funcStack)
86         m_functionStack.swap(*funcStack);
87     m_capturedVariables.swap(capturedVariables);
88 }
89 
90 // ------------------------------ ScopeNode -----------------------------
91 
ScopeNode(JSGlobalData * globalData,bool inStrictContext)92 ScopeNode::ScopeNode(JSGlobalData* globalData, bool inStrictContext)
93     : StatementNode(globalData)
94     , ParserArenaRefCounted(globalData)
95     , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
96 {
97 }
98 
ScopeNode(JSGlobalData * globalData,const SourceCode & source,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,CodeFeatures features,int numConstants)99 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
100     : StatementNode(globalData)
101     , ParserArenaRefCounted(globalData)
102     , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, capturedVariables, numConstants)))
103     , m_features(features)
104     , m_source(source)
105 {
106 }
107 
singleStatement() const108 StatementNode* ScopeNode::singleStatement() const
109 {
110     return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
111 }
112 
113 // ------------------------------ ProgramNode -----------------------------
114 
ProgramNode(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,const SourceCode & source,CodeFeatures features,int numConstants)115 inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
116     : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
117 {
118 }
119 
create(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,const SourceCode & source,CodeFeatures features,int numConstants)120 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
121 {
122     RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
123 
124     ASSERT(node->data()->m_arena.last() == node);
125     node->data()->m_arena.removeLast();
126     ASSERT(!node->data()->m_arena.contains(node.get()));
127 
128     return node.release();
129 }
130 
131 // ------------------------------ EvalNode -----------------------------
132 
EvalNode(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,const SourceCode & source,CodeFeatures features,int numConstants)133 inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
134     : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
135 {
136 }
137 
create(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,const SourceCode & source,CodeFeatures features,int numConstants)138 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
139 {
140     RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
141 
142     ASSERT(node->data()->m_arena.last() == node);
143     node->data()->m_arena.removeLast();
144     ASSERT(!node->data()->m_arena.contains(node.get()));
145 
146     return node.release();
147 }
148 
149 // ------------------------------ FunctionBodyNode -----------------------------
150 
FunctionParameters(ParameterNode * firstParameter)151 FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
152 {
153     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
154         append(parameter->ident());
155 }
156 
FunctionBodyNode(JSGlobalData * globalData,bool inStrictContext)157 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, bool inStrictContext)
158     : ScopeNode(globalData, inStrictContext)
159 {
160 }
161 
FunctionBodyNode(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,const SourceCode & sourceCode,CodeFeatures features,int numConstants)162 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
163     : ScopeNode(globalData, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
164 {
165 }
166 
finishParsing(const SourceCode & source,ParameterNode * firstParameter,const Identifier & ident)167 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident)
168 {
169     setSource(source);
170     finishParsing(FunctionParameters::create(firstParameter), ident);
171 }
172 
finishParsing(PassRefPtr<FunctionParameters> parameters,const Identifier & ident)173 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident)
174 {
175     ASSERT(!source().isNull());
176     m_parameters = parameters;
177     m_ident = ident;
178 }
179 
create(JSGlobalData * globalData,bool inStrictContext)180 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, bool inStrictContext)
181 {
182     return new FunctionBodyNode(globalData, inStrictContext);
183 }
184 
create(JSGlobalData * globalData,SourceElements * children,VarStack * varStack,FunctionStack * funcStack,IdentifierSet & capturedVariables,const SourceCode & sourceCode,CodeFeatures features,int numConstants)185 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
186 {
187     RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
188 
189     ASSERT(node->data()->m_arena.last() == node);
190     node->data()->m_arena.removeLast();
191     ASSERT(!node->data()->m_arena.contains(node.get()));
192 
193     return node.release();
194 }
195 
196 } // namespace JSC
197