X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/14957cd040308e3eeec43d26bae5d76da13fcd85..4be4e30906bcb8ee30b4d189205cb70bad6707ce:/parser/Nodes.cpp diff --git a/parser/Nodes.cpp b/parser/Nodes.cpp index 34aa674..97ffaa1 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 @@ -33,7 +33,7 @@ #include "JIT.h" #include "JSFunction.h" #include "JSGlobalObject.h" -#include "JSStaticScopeObject.h" +#include "JSNameScope.h" #include "LabelScope.h" #include "Lexer.h" #include "Operations.h" @@ -52,10 +52,13 @@ namespace JSC { // ------------------------------ StatementNode -------------------------------- -void StatementNode::setLoc(int firstLine, int lastLine) +void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset) { - m_line = firstLine; + m_lineNumber = firstLine; m_lastLine = lastLine; + m_startOffset = startOffset; + m_lineStartOffset = lineStartOffset; + ASSERT(m_startOffset >= m_lineStartOffset); } // ------------------------------ SourceElements -------------------------------- @@ -73,122 +76,146 @@ StatementNode* SourceElements::singleStatement() const return size == 1 ? m_statements[0] : 0; } -// -----------------------------ScopeNodeData --------------------------- - -ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants) - : m_numConstants(numConstants) - , m_statements(statements) -{ - m_arena.swap(arena); - if (varStack) - m_varStack.swap(*varStack); - if (funcStack) - m_functionStack.swap(*funcStack); - m_capturedVariables.swap(capturedVariables); -} - // ------------------------------ ScopeNode ----------------------------- -ScopeNode::ScopeNode(JSGlobalData* globalData, bool inStrictContext) - : StatementNode(globalData) - , ParserArenaRefCounted(globalData) +ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext) + : StatementNode(endLocation) + , ParserArenaRefCounted(vm) + , 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, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants) - : StatementNode(globalData) - , ParserArenaRefCounted(globalData) - , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, capturedVariables, 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) + , ParserArenaRefCounted(vm) + , 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(*vm->parserArena); + if (varStack) + m_varStack.swap(*varStack); + if (funcStack) + m_functionStack.swap(*funcStack); + m_capturedVariables.swap(capturedVariables); } StatementNode* ScopeNode::singleStatement() const { - return m_data->m_statements ? m_data->m_statements->singleStatement() : 0; + return m_statements ? m_statements->singleStatement() : 0; } // ------------------------------ ProgramNode ----------------------------- -inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) - : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants) +inline ProgramNode::ProgramNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, 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) { } -PassRefPtr ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) +PassRefPtr ProgramNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) { - RefPtr node = new ProgramNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants); + RefPtr node = new ProgramNode(vm, startLocation, endLocation, startColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants); - ASSERT(node->data()->m_arena.last() == node); - node->data()->m_arena.removeLast(); - ASSERT(!node->data()->m_arena.contains(node.get())); + ASSERT(node->m_arena.last() == node); + node->m_arena.removeLast(); + ASSERT(!node->m_arena.contains(node.get())); return node.release(); } // ------------------------------ EvalNode ----------------------------- -inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) - : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants) +inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, 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) { } -PassRefPtr EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) +PassRefPtr EvalNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) { - RefPtr node = new EvalNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants); + RefPtr node = new EvalNode(vm, startLocation, endLocation, children, varStack, funcStack, capturedVariables, source, features, numConstants); - ASSERT(node->data()->m_arena.last() == node); - node->data()->m_arena.removeLast(); - ASSERT(!node->data()->m_arena.contains(node.get())); + 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) +PassRefPtr 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(StringImpl*) * parameterCount; + void* slot = fastMalloc(objectSize); + return adoptRef(new (slot) FunctionParameters(firstParameter, parameterCount)); +} + +FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size) + : m_size(size) +{ + unsigned i = 0; + for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) + new (&identifiers()[i++]) Identifier(parameter->ident()); +} + +FunctionParameters::~FunctionParameters() +{ + for (unsigned i = 0; i < m_size; ++i) + identifiers()[i].~Identifier(); } -inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, bool inStrictContext) - : ScopeNode(globalData, inStrictContext) +inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext) + : ScopeNode(vm, startLocation, endLocation, inStrictContext) + , m_startColumn(startColumn) { } -inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) - : ScopeNode(globalData, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants) +inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, 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) { } -void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident) +void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident, FunctionNameIsInScopeToggle functionNameIsInScopeToggle) { setSource(source); - finishParsing(FunctionParameters::create(firstParameter), ident); + finishParsing(FunctionParameters::create(firstParameter), ident, functionNameIsInScopeToggle); } -void FunctionBodyNode::finishParsing(PassRefPtr parameters, const Identifier& ident) +void FunctionBodyNode::finishParsing(PassRefPtr parameters, const Identifier& ident, FunctionNameIsInScopeToggle functionNameIsInScopeToggle) { ASSERT(!source().isNull()); m_parameters = parameters; m_ident = ident; + m_functionNameIsInScopeToggle = functionNameIsInScopeToggle; } -FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, bool inStrictContext) +FunctionBodyNode* FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, bool inStrictContext) { - return new FunctionBodyNode(globalData, inStrictContext); + return new FunctionBodyNode(vm, startLocation, endLocation, startColumn, inStrictContext); } -PassRefPtr FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) +PassRefPtr FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) { - RefPtr node = new FunctionBodyNode(globalData, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants); + RefPtr node = new FunctionBodyNode(vm, startLocation, endLocation, startColumn, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants); - ASSERT(node->data()->m_arena.last() == node); - node->data()->m_arena.removeLast(); - ASSERT(!node->data()->m_arena.contains(node.get())); + ASSERT(node->m_arena.last() == node); + node->m_arena.removeLast(); + ASSERT(!node->m_arena.contains(node.get())); return node.release(); }