]> git.saurik.com Git - apple/javascriptcore.git/blob - parser/Nodes.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / parser / Nodes.cpp
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, 2013 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 "CallFrame.h"
31 #include "Debugger.h"
32 #include "JIT.h"
33 #include "JSFunction.h"
34 #include "JSGlobalObject.h"
35 #include "JSNameScope.h"
36 #include "LabelScope.h"
37 #include "Lexer.h"
38 #include "JSCInlines.h"
39 #include "Parser.h"
40 #include "PropertyNameArray.h"
41 #include "RegExpObject.h"
42 #include "SamplingTool.h"
43 #include <wtf/Assertions.h>
44 #include <wtf/RefCountedLeakCounter.h>
45 #include <wtf/Threading.h>
46
47 using namespace WTF;
48
49 namespace JSC {
50
51
52 // ------------------------------ StatementNode --------------------------------
53
54 void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
55 {
56 m_lastLine = lastLine;
57 m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
58 ASSERT(m_position.offset >= m_position.lineStartOffset);
59 }
60
61 // ------------------------------ SourceElements --------------------------------
62
63 void SourceElements::append(StatementNode* statement)
64 {
65 if (statement->isEmptyStatement())
66 return;
67
68 if (!m_head) {
69 m_head = statement;
70 m_tail = statement;
71 return;
72 }
73
74 m_tail->setNext(statement);
75 m_tail = statement;
76 }
77
78 StatementNode* SourceElements::singleStatement() const
79 {
80 return m_head == m_tail ? m_head : nullptr;
81 }
82
83 // ------------------------------ ScopeNode -----------------------------
84
85 ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
86 : StatementNode(endLocation)
87 , ParserArenaRoot(parserArena)
88 , m_startLineNumber(startLocation.line)
89 , m_startStartOffset(startLocation.startOffset)
90 , m_startLineStartOffset(startLocation.lineStartOffset)
91 , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
92 , m_numConstants(0)
93 , m_statements(0)
94 {
95 }
96
97 ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
98 : StatementNode(endLocation)
99 , ParserArenaRoot(parserArena)
100 , m_startLineNumber(startLocation.line)
101 , m_startStartOffset(startLocation.startOffset)
102 , m_startLineStartOffset(startLocation.lineStartOffset)
103 , m_features(features)
104 , m_source(source)
105 , m_numConstants(numConstants)
106 , m_statements(children)
107 {
108 m_varStack.swap(varStack);
109 m_functionStack.swap(funcStack);
110 m_capturedVariables.swap(capturedVariables);
111 }
112
113 StatementNode* ScopeNode::singleStatement() const
114 {
115 return m_statements ? m_statements->singleStatement() : 0;
116 }
117
118 // ------------------------------ ProgramNode -----------------------------
119
120 ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
121 : ScopeNode(parserArena, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
122 , m_startColumn(startColumn)
123 , m_endColumn(endColumn)
124 {
125 }
126
127 void ProgramNode::setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&& closedVariables)
128 {
129 m_closedVariables = WTF::move(closedVariables);
130 }
131
132 // ------------------------------ EvalNode -----------------------------
133
134 EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
135 : ScopeNode(parserArena, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
136 , m_endColumn(endColumn)
137 {
138 }
139
140 // ------------------------------ FunctionBodyNode -----------------------------
141
142 Ref<FunctionParameters> FunctionParameters::create(ParameterNode* firstParameter)
143 {
144 unsigned parameterCount = 0;
145 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
146 ++parameterCount;
147
148 size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(DestructuringPatternNode*) * parameterCount;
149 void* slot = fastMalloc(objectSize);
150 return adoptRef(*new (slot) FunctionParameters(firstParameter, parameterCount));
151 }
152
153 FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size)
154 : m_size(size)
155 {
156 unsigned i = 0;
157 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) {
158 auto pattern = parameter->pattern();
159 pattern->ref();
160 patterns()[i++] = pattern;
161 }
162 }
163
164 FunctionParameters::~FunctionParameters()
165 {
166 for (unsigned i = 0; i < m_size; ++i)
167 patterns()[i]->deref();
168 }
169
170 FunctionBodyNode::FunctionBodyNode(
171 ParserArena&, const JSTokenLocation& startLocation,
172 const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
173 int functionKeywordStart, int functionNameStart, int parametersStart,
174 bool isInStrictContext, ConstructorKind constructorKind)
175 : StatementNode(endLocation)
176 , m_startColumn(startColumn)
177 , m_endColumn(endColumn)
178 , m_functionKeywordStart(functionKeywordStart)
179 , m_functionNameStart(functionNameStart)
180 , m_parametersStart(parametersStart)
181 , m_startStartOffset(startLocation.startOffset)
182 , m_isInStrictContext(isInStrictContext)
183 , m_constructorKind(static_cast<unsigned>(constructorKind))
184 {
185 ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
186 }
187
188 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident, enum FunctionMode functionMode)
189 {
190 m_source = source;
191 m_parameters = FunctionParameters::create(firstParameter);
192 m_ident = ident;
193 m_functionMode = functionMode;
194 }
195
196 void FunctionBodyNode::setEndPosition(JSTextPosition position)
197 {
198 m_lastLine = position.line;
199 m_endColumn = position.offset - position.lineStartOffset;
200 }
201
202 // ------------------------------ FunctionNode -----------------------------
203
204 FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack& varStack, FunctionStack& funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
205 : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
206 , m_startColumn(startColumn)
207 , m_endColumn(endColumn)
208 {
209 }
210
211 void FunctionNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident, enum FunctionMode functionMode)
212 {
213 ASSERT(!source().isNull());
214 m_parameters = parameters;
215 m_ident = ident;
216 m_functionMode = functionMode;
217 }
218
219 } // namespace JSC