ff9aa44ad1478ab7091dab481654024d11fa053a
[WebKit-https.git] / Source / JavaScriptCore / 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 PassRefPtr<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(DeconstructionPatternNode*) * 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