blob: 4bb05f3fe32dafe384020f7440424f6fe8154d3b [file] [log] [blame]
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2003-2009, 2013, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include "config.h"
#include "Nodes.h"
#include "NodeConstructors.h"
#include "JSCInlines.h"
#include "ModuleScopeData.h"
#include <wtf/Assertions.h>
using namespace WTF;
namespace JSC {
// ------------------------------ StatementNode --------------------------------
void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
{
m_lastLine = lastLine;
m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
ASSERT(m_position.offset >= m_position.lineStartOffset);
}
// ------------------------------ SourceElements --------------------------------
void SourceElements::append(StatementNode* statement)
{
if (statement->isEmptyStatement())
return;
if (!m_head) {
m_head = statement;
m_tail = statement;
return;
}
m_tail->setNext(statement);
m_tail = statement;
}
StatementNode* SourceElements::singleStatement() const
{
return m_head == m_tail ? m_head : nullptr;
}
StatementNode* SourceElements::lastStatement() const
{
return m_tail;
}
bool SourceElements::hasCompletionValue() const
{
for (StatementNode* statement = m_head; statement; statement = statement->next()) {
if (statement->hasCompletionValue())
return true;
}
return false;
}
bool SourceElements::hasEarlyBreakOrContinue() const
{
for (StatementNode* statement = m_head; statement; statement = statement->next()) {
if (statement->isBreak() || statement->isContinue())
return true;
if (statement->hasCompletionValue())
return false;
}
return false;
}
// ------------------------------ BlockNode ------------------------------------
StatementNode* BlockNode::lastStatement() const
{
return m_statements ? m_statements->lastStatement() : nullptr;
}
StatementNode* BlockNode::singleStatement() const
{
return m_statements ? m_statements->singleStatement() : nullptr;
}
bool BlockNode::hasCompletionValue() const
{
return m_statements ? m_statements->hasCompletionValue() : false;
}
bool BlockNode::hasEarlyBreakOrContinue() const
{
return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
}
// ------------------------------ ScopeNode -----------------------------
ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
: StatementNode(endLocation)
, ParserArenaRoot(parserArena)
, m_startLineNumber(startLocation.line)
, m_startStartOffset(startLocation.startOffset)
, m_startLineStartOffset(startLocation.lineStartOffset)
, m_features(inStrictContext ? StrictModeFeature : NoFeatures)
, m_innerArrowFunctionCodeFeatures(NoInnerArrowFunctionFeatures)
, m_numConstants(0)
, m_statements(0)
{
}
ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
: StatementNode(endLocation)
, ParserArenaRoot(parserArena)
, VariableEnvironmentNode(lexicalVariables, WTFMove(funcStack))
, m_startLineNumber(startLocation.line)
, m_startStartOffset(startLocation.startOffset)
, m_startLineStartOffset(startLocation.lineStartOffset)
, m_features(features)
, m_innerArrowFunctionCodeFeatures(innerArrowFunctionCodeFeatures)
, m_source(source)
, m_sloppyModeHoistedFunctions(WTFMove(sloppyModeHoistedFunctions))
, m_numConstants(numConstants)
, m_statements(children)
{
m_varDeclarations.swap(varEnvironment);
}
StatementNode* ScopeNode::singleStatement() const
{
return m_statements ? m_statements->singleStatement() : nullptr;
}
bool ScopeNode::hasCompletionValue() const
{
return m_statements ? m_statements->hasCompletionValue() : false;
}
bool ScopeNode::hasEarlyBreakOrContinue() const
{
return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
}
// ------------------------------ ProgramNode -----------------------------
ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
: ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
{
}
// ------------------------------ ModuleProgramNode -----------------------------
ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData)
: ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
, m_moduleScopeData(*WTFMove(moduleScopeData))
{
}
// ------------------------------ EvalNode -----------------------------
EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
: ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
, m_endColumn(endColumn)
{
}
// ------------------------------ FunctionMetadataNode -----------------------------
FunctionMetadataNode::FunctionMetadataNode(
ParserArena&, const JSTokenLocation& startLocation,
const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
int functionKeywordStart, int functionNameStart, int parametersStart, bool isInStrictContext,
ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
: Node(endLocation)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
, m_functionKeywordStart(functionKeywordStart)
, m_functionNameStart(functionNameStart)
, m_parametersStart(parametersStart)
, m_startStartOffset(startLocation.startOffset)
, m_parameterCount(parameterCount)
, m_parseMode(mode)
, m_isInStrictContext(isInStrictContext)
, m_superBinding(static_cast<unsigned>(superBinding))
, m_constructorKind(static_cast<unsigned>(constructorKind))
, m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
{
ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
}
void FunctionMetadataNode::finishParsing(const SourceCode& source, const Identifier& ident, FunctionMode functionMode)
{
m_source = source;
m_ident = ident;
m_functionMode = functionMode;
}
void FunctionMetadataNode::setEndPosition(JSTextPosition position)
{
m_lastLine = position.line;
m_endColumn = position.offset - position.lineStartOffset;
}
// ------------------------------ FunctionNode -----------------------------
FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
: ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
, m_parameters(parameters)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
{
}
void FunctionNode::finishParsing(const Identifier& ident, FunctionMode functionMode)
{
ASSERT(!source().isNull());
m_ident = ident;
m_functionMode = functionMode;
}
bool PropertyListNode::hasStaticallyNamedProperty(const Identifier& propName)
{
PropertyListNode* list = this;
while (list) {
if (list->m_node->isStaticClassProperty()) {
const Identifier* currentNodeName = list->m_node->name();
if (currentNodeName && *currentNodeName == propName)
return true;
}
list = list->m_next;
}
return false;
}
VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment& lexicalVariables)
{
m_lexicalVariables.swap(lexicalVariables);
}
VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment& lexicalVariables, FunctionStack&& functionStack)
{
m_lexicalVariables.swap(lexicalVariables);
m_functionStack = WTFMove(functionStack);
}
} // namespace JSC