summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/parser/Nodes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/parser/Nodes.cpp')
-rw-r--r--Source/JavaScriptCore/parser/Nodes.cpp159
1 files changed, 95 insertions, 64 deletions
diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp
index 255754494..fc9ccd9f6 100644
--- a/Source/JavaScriptCore/parser/Nodes.cpp
+++ b/Source/JavaScriptCore/parser/Nodes.cpp
@@ -27,14 +27,16 @@
#include "Nodes.h"
#include "NodeConstructors.h"
+#include "BytecodeGenerator.h"
#include "CallFrame.h"
#include "Debugger.h"
#include "JIT.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
+#include "JSNameScope.h"
#include "LabelScope.h"
#include "Lexer.h"
-#include "JSCInlines.h"
+#include "Operations.h"
#include "Parser.h"
#include "PropertyNameArray.h"
#include "RegExpObject.h"
@@ -63,27 +65,20 @@ 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;
+ m_statements.append(statement);
}
StatementNode* SourceElements::singleStatement() const
{
- return m_head == m_tail ? m_head : nullptr;
+ size_t size = m_statements.size();
+ return size == 1 ? m_statements[0] : 0;
}
// ------------------------------ ScopeNode -----------------------------
-ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
+ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
: StatementNode(endLocation)
- , ParserArenaRoot(parserArena)
+ , ParserArenaRefCounted(vm)
, m_startLineNumber(startLocation.line)
, m_startStartOffset(startLocation.startOffset)
, m_startLineStartOffset(startLocation.lineStartOffset)
@@ -93,10 +88,9 @@ ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocat
{
}
-ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack& funcStack, VariableEnvironment& lexicalVariables, CodeFeatures features, int numConstants)
+ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
: StatementNode(endLocation)
- , ParserArenaRoot(parserArena)
- , VariableEnvironmentNode(lexicalVariables)
+ , ParserArenaRefCounted(vm)
, m_startLineNumber(startLocation.line)
, m_startStartOffset(startLocation.startOffset)
, m_startLineStartOffset(startLocation.lineStartOffset)
@@ -105,8 +99,12 @@ ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocat
, m_numConstants(numConstants)
, m_statements(children)
{
- m_varDeclarations.swap(varEnvironment);
- m_functionStack.swap(funcStack);
+ m_arena.swap(*vm->parserArena);
+ if (varStack)
+ m_varStack.swap(*varStack);
+ if (funcStack)
+ m_functionStack.swap(*funcStack);
+ m_capturedVariables.swap(capturedVariables);
}
StatementNode* ScopeNode::singleStatement() const
@@ -116,88 +114,121 @@ StatementNode* ScopeNode::singleStatement() const
// ------------------------------ ProgramNode -----------------------------
-ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack& funcStack, VariableEnvironment& lexicalVariables, FunctionParameters*, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, funcStack, lexicalVariables, features, numConstants)
+inline ProgramNode::ProgramNode(VM* vm, 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)
+ : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, 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, FunctionParameters*, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, funcStack, lexicalVariables, features, numConstants)
- , m_startColumn(startColumn)
- , m_endColumn(endColumn)
+PassRefPtr<ProgramNode> ProgramNode::create(VM* vm, 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)
{
+ RefPtr<ProgramNode> node = new ProgramNode(vm, startLocation, endLocation, startColumn, endColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
+
+ return node.release();
}
// ------------------------------ EvalNode -----------------------------
-EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack& funcStack, VariableEnvironment& lexicalVariables, FunctionParameters*, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, funcStack, lexicalVariables, features, numConstants)
+inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
, m_endColumn(endColumn)
{
}
-// ------------------------------ FunctionMetadataNode -----------------------------
+PassRefPtr<EvalNode> EvalNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+{
+ RefPtr<EvalNode> node = new EvalNode(vm, startLocation, endLocation, endColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
+
+ return node.release();
+}
+
+// ------------------------------ FunctionBodyNode -----------------------------
-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)
+PassRefPtr<FunctionParameters> FunctionParameters::create(ParameterNode* firstParameter)
{
- ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
- ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
+ unsigned parameterCount = 0;
+ for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
+ ++parameterCount;
+
+ size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(DeconstructionPatternNode*) * parameterCount;
+ void* slot = fastMalloc(objectSize);
+ return adoptRef(new (slot) FunctionParameters(firstParameter, parameterCount));
}
-void FunctionMetadataNode::finishParsing(const SourceCode& source, const Identifier& ident, enum FunctionMode functionMode)
+FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size)
+ : m_size(size)
{
- m_source = source;
- m_ident = ident;
- m_functionMode = functionMode;
+ unsigned i = 0;
+ for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) {
+ auto pattern = parameter->pattern();
+ pattern->ref();
+ patterns()[i++] = pattern;
+ }
}
-void FunctionMetadataNode::setEndPosition(JSTextPosition position)
+FunctionParameters::~FunctionParameters()
{
- m_lastLine = position.line;
- m_endColumn = position.offset - position.lineStartOffset;
+ for (unsigned i = 0; i < m_size; ++i)
+ patterns()[i]->deref();
}
-// ------------------------------ FunctionNode -----------------------------
+inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
+ : ScopeNode(vm, startLocation, endLocation, inStrictContext)
+ , m_startColumn(startColumn)
+ , m_endColumn(endColumn)
+{
+}
-FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack& funcStack, VariableEnvironment& lexicalVariables, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
- : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varEnvironment, funcStack, lexicalVariables, features, numConstants)
- , m_parameters(parameters)
+inline FunctionBodyNode::FunctionBodyNode(VM* vm, 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)
+ : ScopeNode(vm, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
, m_startColumn(startColumn)
, m_endColumn(endColumn)
{
}
-void FunctionNode::finishParsing(const Identifier& ident, enum FunctionMode functionMode)
+void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident, FunctionNameIsInScopeToggle functionNameIsInScopeToggle)
+{
+ setSource(source);
+ finishParsing(FunctionParameters::create(firstParameter), ident, functionNameIsInScopeToggle);
+}
+
+void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident, FunctionNameIsInScopeToggle functionNameIsInScopeToggle)
{
ASSERT(!source().isNull());
+ m_parameters = parameters;
m_ident = ident;
- m_functionMode = functionMode;
+ m_functionNameIsInScopeToggle = functionNameIsInScopeToggle;
+}
+
+FunctionBodyNode* FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
+{
+ return new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn, inStrictContext);
}
-VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment& lexicalVariables)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(VM* vm, 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)
{
- m_lexicalVariables.swap(lexicalVariables);
+ RefPtr<FunctionBodyNode> node = new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn , children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
+
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
+
+ return node.release();
+}
+
+void FunctionBodyNode::setEndPosition(JSTextPosition position)
+{
+ m_lastLine = position.line;
+ m_endColumn = position.offset - position.lineStartOffset;
}
} // namespace JSC