diff options
Diffstat (limited to 'Source/JavaScriptCore/parser/Nodes.cpp')
-rw-r--r-- | Source/JavaScriptCore/parser/Nodes.cpp | 159 |
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 |