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>
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.
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.
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.
28 #include "NodeConstructors.h"
30 #include "CallFrame.h"
33 #include "JSFunction.h"
34 #include "JSGlobalObject.h"
35 #include "JSNameScope.h"
36 #include "LabelScope.h"
38 #include "JSCInlines.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>
52 // ------------------------------ StatementNode --------------------------------
54 void StatementNode::setLoc(unsigned firstLine
, unsigned lastLine
, int startOffset
, int lineStartOffset
)
56 m_lastLine
= lastLine
;
57 m_position
= JSTextPosition(firstLine
, startOffset
, lineStartOffset
);
58 ASSERT(m_position
.offset
>= m_position
.lineStartOffset
);
61 // ------------------------------ SourceElements --------------------------------
63 void SourceElements::append(StatementNode
* statement
)
65 if (statement
->isEmptyStatement())
74 m_tail
->setNext(statement
);
78 StatementNode
* SourceElements::singleStatement() const
80 return m_head
== m_tail
? m_head
: nullptr;
83 // ------------------------------ ScopeNode -----------------------------
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
)
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
)
105 , m_numConstants(numConstants
)
106 , m_statements(children
)
108 m_varStack
.swap(varStack
);
109 m_functionStack
.swap(funcStack
);
110 m_capturedVariables
.swap(capturedVariables
);
113 StatementNode
* ScopeNode::singleStatement() const
115 return m_statements
? m_statements
->singleStatement() : 0;
118 // ------------------------------ ProgramNode -----------------------------
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
)
127 void ProgramNode::setClosedVariables(Vector
<RefPtr
<UniquedStringImpl
>>&& closedVariables
)
129 m_closedVariables
= WTF::move(closedVariables
);
132 // ------------------------------ EvalNode -----------------------------
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
)
140 // ------------------------------ FunctionBodyNode -----------------------------
142 Ref
<FunctionParameters
> FunctionParameters::create(ParameterNode
* firstParameter
)
144 unsigned parameterCount
= 0;
145 for (ParameterNode
* parameter
= firstParameter
; parameter
; parameter
= parameter
->nextParam())
148 size_t objectSize
= sizeof(FunctionParameters
) - sizeof(void*) + sizeof(DestructuringPatternNode
*) * parameterCount
;
149 void* slot
= fastMalloc(objectSize
);
150 return adoptRef(*new (slot
) FunctionParameters(firstParameter
, parameterCount
));
153 FunctionParameters::FunctionParameters(ParameterNode
* firstParameter
, unsigned size
)
157 for (ParameterNode
* parameter
= firstParameter
; parameter
; parameter
= parameter
->nextParam()) {
158 auto pattern
= parameter
->pattern();
160 patterns()[i
++] = pattern
;
164 FunctionParameters::~FunctionParameters()
166 for (unsigned i
= 0; i
< m_size
; ++i
)
167 patterns()[i
]->deref();
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
))
185 ASSERT(m_constructorKind
== static_cast<unsigned>(constructorKind
));
188 void FunctionBodyNode::finishParsing(const SourceCode
& source
, ParameterNode
* firstParameter
, const Identifier
& ident
, enum FunctionMode functionMode
)
191 m_parameters
= FunctionParameters::create(firstParameter
);
193 m_functionMode
= functionMode
;
196 void FunctionBodyNode::setEndPosition(JSTextPosition position
)
198 m_lastLine
= position
.line
;
199 m_endColumn
= position
.offset
- position
.lineStartOffset
;
202 // ------------------------------ FunctionNode -----------------------------
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
)
211 void FunctionNode::finishParsing(PassRefPtr
<FunctionParameters
> parameters
, const Identifier
& ident
, enum FunctionMode functionMode
)
213 ASSERT(!source().isNull());
214 m_parameters
= parameters
;
216 m_functionMode
= functionMode
;