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 inline 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, 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 }
     88 
     89 // ------------------------------ ScopeNode -----------------------------
     90 
     91 ScopeNode::ScopeNode(JSGlobalData* globalData)
     92     : StatementNode(globalData)
     93     , ParserArenaRefCounted(globalData)
     94     , m_features(NoFeatures)
     95 {
     96 }
     97 
     98 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
     99     : StatementNode(globalData)
    100     , ParserArenaRefCounted(globalData)
    101     , m_data(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, numConstants))
    102     , m_features(features)
    103     , m_source(source)
    104 {
    105 }
    106 
    107 StatementNode* ScopeNode::singleStatement() const
    108 {
    109     return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
    110 }
    111 
    112 // ------------------------------ ProgramNode -----------------------------
    113 
    114 inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
    115     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
    116 {
    117 }
    118 
    119 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
    120 {
    121     RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
    122 
    123     ASSERT(node->data()->m_arena.last() == node);
    124     node->data()->m_arena.removeLast();
    125     ASSERT(!node->data()->m_arena.contains(node.get()));
    126 
    127     return node.release();
    128 }
    129 
    130 // ------------------------------ EvalNode -----------------------------
    131 
    132 inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
    133     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
    134 {
    135 }
    136 
    137 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
    138 {
    139     RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
    140 
    141     ASSERT(node->data()->m_arena.last() == node);
    142     node->data()->m_arena.removeLast();
    143     ASSERT(!node->data()->m_arena.contains(node.get()));
    144 
    145     return node.release();
    146 }
    147 
    148 // ------------------------------ FunctionBodyNode -----------------------------
    149 
    150 FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
    151 {
    152     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
    153         append(parameter->ident());
    154 }
    155 
    156 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
    157     : ScopeNode(globalData)
    158 {
    159 }
    160 
    161 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
    162     : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
    163 {
    164 }
    165 
    166 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident)
    167 {
    168     setSource(source);
    169     finishParsing(FunctionParameters::create(firstParameter), ident);
    170 }
    171 
    172 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident)
    173 {
    174     ASSERT(!source().isNull());
    175     m_parameters = parameters;
    176     m_ident = ident;
    177 }
    178 
    179 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
    180 {
    181     return new FunctionBodyNode(globalData);
    182 }
    183 
    184 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
    185 {
    186     RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
    187 
    188     ASSERT(node->data()->m_arena.last() == node);
    189     node->data()->m_arena.removeLast();
    190     ASSERT(!node->data()->m_arena.contains(node.get()));
    191 
    192     return node.release();
    193 }
    194 
    195 } // namespace JSC
    196