1 | /*
|
---|
2 | * Copyright (C) 1999-2002 Harri Porten ([email protected])
|
---|
3 | * Copyright (C) 2001 Peter Kelly ([email protected])
|
---|
4 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
|
---|
5 | * Copyright (C) 2007 Cameron Zwarich ([email protected])
|
---|
6 | * Copyright (C) 2007 Maks Orlovich
|
---|
7 | * Copyright (C) 2007 Eric Seidel <[email protected]>
|
---|
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, 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(adoptPtr(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
|
---|