Home | History | Annotate | Download | only in parser
      1 /*
      2 *  Copyright (C) 1999-2002 Harri Porten (porten (at) kde.org)
      3 *  Copyright (C) 2001 Peter Kelly (pmk (at) post.com)
      4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich (at) uwaterloo.ca)
      6 *  Copyright (C) 2007 Maks Orlovich
      7 *  Copyright (C) 2007 Eric Seidel <eric (at) webkit.org>
      8 *
      9 *  This library is free software; you can redistribute it and/or
     10 *  modify it under the terms of the GNU Library General Public
     11 *  License as published by the Free Software Foundation; either
     12 *  version 2 of the License, or (at your option) any later version.
     13 *
     14 *  This library is distributed in the hope that it will be useful,
     15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17 *  Library General Public License for more details.
     18 *
     19 *  You should have received a copy of the GNU Library General Public License
     20 *  along with this library; see the file COPYING.LIB.  If not, write to
     21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     22 *  Boston, MA 02110-1301, USA.
     23 *
     24 */
     25 
     26 #include "config.h"
     27 #include "Nodes.h"
     28 #include "NodeConstructors.h"
     29 
     30 #include "BytecodeGenerator.h"
     31 #include "CallFrame.h"
     32 #include "Debugger.h"
     33 #include "JIT.h"
     34 #include "JSFunction.h"
     35 #include "JSGlobalObject.h"
     36 #include "JSStaticScopeObject.h"
     37 #include "LabelScope.h"
     38 #include "Lexer.h"
     39 #include "Operations.h"
     40 #include "Parser.h"
     41 #include "PropertyNameArray.h"
     42 #include "RegExpObject.h"
     43 #include "SamplingTool.h"
     44 #include <wtf/Assertions.h>
     45 #include <wtf/RefCountedLeakCounter.h>
     46 #include <wtf/Threading.h>
     47 
     48 using namespace WTF;
     49 
     50 namespace JSC {
     51 
     52 
     53 // ------------------------------ StatementNode --------------------------------
     54 
     55 void StatementNode::setLoc(int firstLine, int lastLine)
     56 {
     57     m_line = firstLine;
     58     m_lastLine = lastLine;
     59 }
     60 
     61 // ------------------------------ SourceElements --------------------------------
     62 
     63 void SourceElements::append(StatementNode* statement)
     64 {
     65     if (statement->isEmptyStatement())
     66         return;
     67     m_statements.append(statement);
     68 }
     69 
     70 StatementNode* SourceElements::singleStatement() const
     71 {
     72     size_t size = m_statements.size();
     73     return size == 1 ? m_statements[0] : 0;
     74 }
     75 
     76 // -----------------------------ScopeNodeData ---------------------------
     77 
     78 ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants)
     79     : m_numConstants(numConstants)
     80     , m_statements(statements)
     81 {
     82     m_arena.swap(arena);
     83     if (varStack)
     84         m_varStack.swap(*varStack);
     85     if (funcStack)
     86         m_functionStack.swap(*funcStack);
     87     m_capturedVariables.swap(capturedVariables);
     88 }
     89 
     90 // ------------------------------ ScopeNode -----------------------------
     91 
     92 ScopeNode::ScopeNode(JSGlobalData* globalData, bool inStrictContext)
     93     : StatementNode(globalData)
     94     , ParserArenaRefCounted(globalData)
     95     , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
     96 {
     97 }
     98 
     99 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
    100     : StatementNode(globalData)
    101     , ParserArenaRefCounted(globalData)
    102     , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, capturedVariables, numConstants)))
    103     , m_features(features)
    104     , m_source(source)
    105 {
    106 }
    107 
    108 StatementNode* ScopeNode::singleStatement() const
    109 {
    110     return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
    111 }
    112 
    113 // ------------------------------ ProgramNode -----------------------------
    114 
    115 inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    116     : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
    117 {
    118 }
    119 
    120 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    121 {
    122     RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
    123 
    124     ASSERT(node->data()->m_arena.last() == node);
    125     node->data()->m_arena.removeLast();
    126     ASSERT(!node->data()->m_arena.contains(node.get()));
    127 
    128     return node.release();
    129 }
    130 
    131 // ------------------------------ EvalNode -----------------------------
    132 
    133 inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    134     : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
    135 {
    136 }
    137 
    138 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    139 {
    140     RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
    141 
    142     ASSERT(node->data()->m_arena.last() == node);
    143     node->data()->m_arena.removeLast();
    144     ASSERT(!node->data()->m_arena.contains(node.get()));
    145 
    146     return node.release();
    147 }
    148 
    149 // ------------------------------ FunctionBodyNode -----------------------------
    150 
    151 FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
    152 {
    153     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
    154         append(parameter->ident());
    155 }
    156 
    157 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, bool inStrictContext)
    158     : ScopeNode(globalData, inStrictContext)
    159 {
    160 }
    161 
    162 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
    163     : ScopeNode(globalData, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
    164 {
    165 }
    166 
    167 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident)
    168 {
    169     setSource(source);
    170     finishParsing(FunctionParameters::create(firstParameter), ident);
    171 }
    172 
    173 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident)
    174 {
    175     ASSERT(!source().isNull());
    176     m_parameters = parameters;
    177     m_ident = ident;
    178 }
    179 
    180 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, bool inStrictContext)
    181 {
    182     return new FunctionBodyNode(globalData, inStrictContext);
    183 }
    184 
    185 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
    186 {
    187     RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
    188 
    189     ASSERT(node->data()->m_arena.last() == node);
    190     node->data()->m_arena.removeLast();
    191     ASSERT(!node->data()->m_arena.contains(node.get()));
    192 
    193     return node.release();
    194 }
    195 
    196 } // namespace JSC
    197