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