1/* 2* Copyright (C) 1999-2002 Harri Porten (porten@kde.org) 3* Copyright (C) 2001 Peter Kelly (pmk@post.com) 4* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 5* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) 6* Copyright (C) 2007 Maks Orlovich 7* Copyright (C) 2007 Eric Seidel <eric@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 48using namespace WTF; 49 50namespace JSC { 51 52 53// ------------------------------ StatementNode -------------------------------- 54 55void StatementNode::setLoc(int firstLine, int lastLine) 56{ 57 m_line = firstLine; 58 m_lastLine = lastLine; 59} 60 61// ------------------------------ SourceElements -------------------------------- 62 63void SourceElements::append(StatementNode* statement) 64{ 65 if (statement->isEmptyStatement()) 66 return; 67 m_statements.append(statement); 68} 69 70StatementNode* SourceElements::singleStatement() const 71{ 72 size_t size = m_statements.size(); 73 return size == 1 ? m_statements[0] : 0; 74} 75 76// -----------------------------ScopeNodeData --------------------------- 77 78ScopeNodeData::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 92ScopeNode::ScopeNode(JSGlobalData* globalData, bool inStrictContext) 93 : StatementNode(globalData) 94 , ParserArenaRefCounted(globalData) 95 , m_features(inStrictContext ? StrictModeFeature : NoFeatures) 96{ 97} 98 99ScopeNode::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 108StatementNode* ScopeNode::singleStatement() const 109{ 110 return m_data->m_statements ? m_data->m_statements->singleStatement() : 0; 111} 112 113// ------------------------------ ProgramNode ----------------------------- 114 115inline 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 120PassRefPtr<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 133inline 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 138PassRefPtr<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 151FunctionParameters::FunctionParameters(ParameterNode* firstParameter) 152{ 153 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) 154 append(parameter->ident()); 155} 156 157inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, bool inStrictContext) 158 : ScopeNode(globalData, inStrictContext) 159{ 160} 161 162inline 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 167void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident) 168{ 169 setSource(source); 170 finishParsing(FunctionParameters::create(firstParameter), ident); 171} 172 173void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident) 174{ 175 ASSERT(!source().isNull()); 176 m_parameters = parameters; 177 m_ident = ident; 178} 179 180FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, bool inStrictContext) 181{ 182 return new FunctionBodyNode(globalData, inStrictContext); 183} 184 185PassRefPtr<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