X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/parser/Nodes.cpp diff --git a/parser/Nodes.cpp b/parser/Nodes.cpp index c32e4c7..93a63a4 100644 --- a/parser/Nodes.cpp +++ b/parser/Nodes.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) -* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. +* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * Copyright (C) 2007 Eric Seidel @@ -27,16 +27,15 @@ #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 "JSStaticScopeObject.h" +#include "JSNameScope.h" #include "LabelScope.h" #include "Lexer.h" -#include "Operations.h" +#include "JSCInlines.h" #include "Parser.h" #include "PropertyNameArray.h" #include "RegExpObject.h" @@ -52,10 +51,11 @@ namespace JSC { // ------------------------------ StatementNode -------------------------------- -void StatementNode::setLoc(int firstLine, int lastLine) +void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset) { - m_lineNumber = firstLine; m_lastLine = lastLine; + m_position = JSTextPosition(firstLine, startOffset, lineStartOffset); + ASSERT(m_position.offset >= m_position.lineStartOffset); } // ------------------------------ SourceElements -------------------------------- @@ -64,39 +64,49 @@ void SourceElements::append(StatementNode* statement) { if (statement->isEmptyStatement()) return; - m_statements.append(statement); + + if (!m_head) { + m_head = statement; + m_tail = statement; + return; + } + + m_tail->setNext(statement); + m_tail = statement; } StatementNode* SourceElements::singleStatement() const { - size_t size = m_statements.size(); - return size == 1 ? m_statements[0] : 0; + return m_head == m_tail ? m_head : nullptr; } // ------------------------------ ScopeNode ----------------------------- -ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext) - : StatementNode(lineNumber) - , ParserArenaRefCounted(globalData) +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_numConstants(0) , m_statements(0) { } -ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants) - : StatementNode(lineNumber) - , ParserArenaRefCounted(globalData) +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) + : StatementNode(endLocation) + , ParserArenaRoot(parserArena) + , m_startLineNumber(startLocation.line) + , m_startStartOffset(startLocation.startOffset) + , m_startLineStartOffset(startLocation.lineStartOffset) , m_features(features) , m_source(source) , m_numConstants(numConstants) , m_statements(children) { - m_arena.swap(*globalData->parserArena); - if (varStack) - m_varStack.swap(*varStack); - if (funcStack) - m_functionStack.swap(*funcStack); + m_varStack.swap(varStack); + m_functionStack.swap(funcStack); m_capturedVariables.swap(capturedVariables); } @@ -107,85 +117,103 @@ StatementNode* ScopeNode::singleStatement() const // ------------------------------ ProgramNode ----------------------------- -inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) - : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants) +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) + : ScopeNode(parserArena, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants) + , m_startColumn(startColumn) + , m_endColumn(endColumn) { } -PassRefPtr ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) +void ProgramNode::setClosedVariables(Vector>&& closedVariables) { - RefPtr node = new ProgramNode(globalData, lineNumber, 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(); + m_closedVariables = WTF::move(closedVariables); } // ------------------------------ EvalNode ----------------------------- -inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) - : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants) +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) + : ScopeNode(parserArena, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants) + , m_endColumn(endColumn) { } -PassRefPtr EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) -{ - RefPtr node = new EvalNode(globalData, lineNumber, 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 ----------------------------- -FunctionParameters::FunctionParameters(ParameterNode* firstParameter) +Ref FunctionParameters::create(ParameterNode* firstParameter) { + unsigned parameterCount = 0; for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) - append(parameter->ident()); + ++parameterCount; + + size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(DestructuringPatternNode*) * parameterCount; + void* slot = fastMalloc(objectSize); + return adoptRef(*new (slot) FunctionParameters(firstParameter, parameterCount)); } -inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext) - : ScopeNode(globalData, lineNumber, inStrictContext) +FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size) + : m_size(size) { + unsigned i = 0; + for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) { + auto pattern = parameter->pattern(); + pattern->ref(); + patterns()[i++] = pattern; + } } -inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) - : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants) +FunctionParameters::~FunctionParameters() { + for (unsigned i = 0; i < m_size; ++i) + patterns()[i]->deref(); } -void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident) +FunctionBodyNode::FunctionBodyNode( + ParserArena&, const JSTokenLocation& startLocation, + const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, + int functionKeywordStart, int functionNameStart, int parametersStart, + bool isInStrictContext, ConstructorKind constructorKind) + : StatementNode(endLocation) + , m_startColumn(startColumn) + , m_endColumn(endColumn) + , m_functionKeywordStart(functionKeywordStart) + , m_functionNameStart(functionNameStart) + , m_parametersStart(parametersStart) + , m_startStartOffset(startLocation.startOffset) + , m_isInStrictContext(isInStrictContext) + , m_constructorKind(static_cast(constructorKind)) { - setSource(source); - finishParsing(FunctionParameters::create(firstParameter), ident); + ASSERT(m_constructorKind == static_cast(constructorKind)); } -void FunctionBodyNode::finishParsing(PassRefPtr parameters, const Identifier& ident) +void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident, enum FunctionMode functionMode) { - ASSERT(!source().isNull()); - m_parameters = parameters; + m_source = source; + m_parameters = FunctionParameters::create(firstParameter); m_ident = ident; + m_functionMode = functionMode; } -FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, bool inStrictContext) +void FunctionBodyNode::setEndPosition(JSTextPosition position) { - return new FunctionBodyNode(globalData, lineNumber, inStrictContext); + m_lastLine = position.line; + m_endColumn = position.offset - position.lineStartOffset; } -PassRefPtr FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) -{ - RefPtr node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants); +// ------------------------------ FunctionNode ----------------------------- - ASSERT(node->m_arena.last() == node); - node->m_arena.removeLast(); - ASSERT(!node->m_arena.contains(node.get())); +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) + : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants) + , m_startColumn(startColumn) + , m_endColumn(endColumn) +{ +} - return node.release(); +void FunctionNode::finishParsing(PassRefPtr parameters, const Identifier& ident, enum FunctionMode functionMode) +{ + ASSERT(!source().isNull()); + m_parameters = parameters; + m_ident = ident; + m_functionMode = functionMode; } } // namespace JSC