1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ast.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "func-name-inferrer.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopes.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "rewriter.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass AstOptimizer: public AstVisitor {
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit AstOptimizer() : has_function_literal_(false) {}
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit AstOptimizer(Handle<String> enclosing_name)
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : has_function_literal_(false) {
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    func_name_inferrer_.PushEnclosingName(enclosing_name);
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Optimize(ZoneList<Statement*>* statements);
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Used for loop condition analysis.  Cleared before visiting a loop
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // condition, set when a function literal is visited.
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool has_function_literal_;
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper object for function name inferring.
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FuncNameInferrer func_name_inferrer_;
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helpers
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void OptimizeArguments(ZoneList<Expression*>* arguments);
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Node visitors.
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEF_VISIT(type) \
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void Visit##type(type* node);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  AST_NODE_LIST(DEF_VISIT)
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_VISIT
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DISALLOW_COPY_AND_ASSIGN(AstOptimizer);
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::Optimize(ZoneList<Statement*>* statements) {
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int len = statements->length();
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < len; i++) {
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(statements->at(i));
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::OptimizeArguments(ZoneList<Expression*>* arguments) {
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < arguments->length(); i++) {
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(arguments->at(i));
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitBlock(Block* node) {
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Optimize(node->statements());
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitExpressionStatement(ExpressionStatement* node) {
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitIfStatement(IfStatement* node) {
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->condition());
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->then_statement());
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->HasElseStatement()) {
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->else_statement());
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstOptimizer::VisitDoWhileStatement(DoWhileStatement* node) {
1043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->cond());
1053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->body());
1063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
1073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstOptimizer::VisitWhileStatement(WhileStatement* node) {
1103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  has_function_literal_ = false;
1113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->cond());
1123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  node->may_have_function_literal_ = has_function_literal_;
1133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->body());
1143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
1153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstOptimizer::VisitForStatement(ForStatement* node) {
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->init() != NULL) {
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->init());
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->cond() != NULL) {
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    has_function_literal_ = false;
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->cond());
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    node->may_have_function_literal_ = has_function_literal_;
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Visit(node->body());
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->next() != NULL) {
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->next());
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitForInStatement(ForInStatement* node) {
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->each());
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->enumerable());
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->body());
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstOptimizer::VisitTryCatchStatement(TryCatchStatement* node) {
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->try_block());
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->catch_var());
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->catch_block());
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid AstOptimizer::VisitTryFinallyStatement(TryFinallyStatement* node) {
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->try_block());
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->finally_block());
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitSwitchStatement(SwitchStatement* node) {
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->tag());
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < node->cases()->length(); i++) {
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CaseClause* clause = node->cases()->at(i);
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!clause->is_default()) {
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Visit(clause->label());
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Optimize(clause->statements());
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitContinueStatement(ContinueStatement* node) {
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitBreakStatement(BreakStatement* node) {
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitDeclaration(Declaration* node) {
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Will not be reached by the current optimizations.
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitEmptyStatement(EmptyStatement* node) {
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitReturnStatement(ReturnStatement* node) {
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitWithEnterStatement(WithEnterStatement* node) {
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitWithExitStatement(WithExitStatement* node) {
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitDebuggerStatement(DebuggerStatement* node) {
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitFunctionLiteral(FunctionLiteral* node) {
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  has_function_literal_ = true;
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->name()->length() == 0) {
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Anonymous function.
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    func_name_inferrer_.AddFunction(node);
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitFunctionBoilerplateLiteral(
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FunctionBoilerplateLiteral* node) {
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitConditional(Conditional* node) {
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->condition());
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->then_expression());
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->else_expression());
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitSlot(Slot* node) {
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitVariableProxy(VariableProxy* node) {
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Variable* var = node->AsVariable();
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (var != NULL) {
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (var->type()->IsKnown()) {
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->type()->CopyFrom(var->type());
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else if (node->type()->IsLikelySmi()) {
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      var->type()->SetAsLikelySmi();
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!var->is_this() &&
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        !Heap::result_symbol()->Equals(*var->name())) {
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      func_name_inferrer_.PushName(var->name());
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitLiteral(Literal* node) {
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> literal = node->handle();
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (literal->IsSmi()) {
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    node->type()->SetAsLikelySmi();
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (literal->IsString()) {
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<String> lit_str(Handle<String>::cast(literal));
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!Heap::prototype_symbol()->Equals(*lit_str)) {
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      func_name_inferrer_.PushName(lit_str);
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitRegExpLiteral(RegExpLiteral* node) {
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitArrayLiteral(ArrayLiteral* node) {
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < node->values()->length(); i++) {
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->values()->at(i));
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitObjectLiteral(ObjectLiteral* node) {
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < node->properties()->length(); i++) {
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    scoped_fni.Enter();
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->properties()->at(i)->key());
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(node->properties()->at(i)->value());
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitCatchExtensionObject(CatchExtensionObject* node) {
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->key());
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->value());
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitAssignment(Assignment* node) {
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (node->op()) {
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::INIT_VAR:
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::INIT_CONST:
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN:
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // No type can be infered from the general assignment.
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Don't infer if it is "a = function(){...}();"-like expression.
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->value()->AsCall() == NULL) {
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        scoped_fni.Enter();
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_OR:
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_XOR:
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_AND:
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHL:
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SAR:
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHR:
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->type()->SetAsLikelySmiIfUnknown();
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->target()->type()->SetAsLikelySmiIfUnknown();
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->value()->type()->SetAsLikelySmiIfUnknown();
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_ADD:
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SUB:
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MUL:
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_DIV:
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MOD:
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->type()->IsLikelySmi()) {
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->target()->type()->SetAsLikelySmiIfUnknown();
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->value()->type()->SetAsLikelySmiIfUnknown();
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default:
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      UNREACHABLE();
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->target());
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->value());
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (node->op()) {
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::INIT_VAR:
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::INIT_CONST:
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN:
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Pure assignment copies the type from the value.
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->type()->CopyFrom(node->value()->type());
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_OR:
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_XOR:
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_BIT_AND:
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHL:
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SAR:
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SHR:
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Should have been setup above already.
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_ADD:
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_SUB:
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MUL:
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_DIV:
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ASSIGN_MOD:
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->type()->IsUnknown()) {
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if (node->target()->type()->IsLikelySmi() ||
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            node->value()->type()->IsLikelySmi()) {
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          node->type()->SetAsLikelySmi();
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default:
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      UNREACHABLE();
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Since this is an assignment. We have to propagate this node's type to the
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // variable.
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VariableProxy* proxy = node->target()->AsVariableProxy();
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (proxy != NULL) {
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Variable* var = proxy->AsVariable();
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (var != NULL) {
370e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      StaticType* var_type = var->type();
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (var_type->IsUnknown()) {
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        var_type->CopyFrom(node->type());
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } else if (var_type->IsLikelySmi()) {
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // We do not reset likely types to Unknown.
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitThrow(Throw* node) {
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->exception());
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitProperty(Property* node) {
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->obj());
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->key());
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitCall(Call* node) {
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  OptimizeArguments(node->arguments());
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitCallNew(CallNew* node) {
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  OptimizeArguments(node->arguments());
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitCallRuntime(CallRuntime* node) {
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (Factory::InitializeVarGlobal_symbol()->Equals(*node->name()) &&
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->arguments()->length() >= 2 &&
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->arguments()->at(1)->AsFunctionLiteral() != NULL) {
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      scoped_fni.Enter();
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  OptimizeArguments(node->arguments());
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitCountOperation(CountOperation* node) {
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Count operations assume that they work on Smis.
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  node->type()->SetAsLikelySmiIfUnknown();
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  node->expression()->type()->SetAsLikelySmiIfUnknown();
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->expression());
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Depending on the operation we can propagate this node's type down the
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // AST nodes.
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  switch (node->op()) {
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::COMMA:
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::OR:
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::AND:
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::BIT_OR:
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::BIT_XOR:
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::BIT_AND:
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::SHL:
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::SAR:
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::SHR:
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->type()->SetAsLikelySmiIfUnknown();
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->left()->type()->SetAsLikelySmiIfUnknown();
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->right()->type()->SetAsLikelySmiIfUnknown();
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::ADD:
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::SUB:
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::MUL:
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::DIV:
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    case Token::MOD:
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->type()->IsLikelySmi()) {
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->left()->type()->SetAsLikelySmiIfUnknown();
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->right()->type()->SetAsLikelySmiIfUnknown();
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    default:
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      UNREACHABLE();
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->left());
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->right());
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // After visiting the operand nodes we have to check if this node's type
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // can be updated. If it does, then we can push that information down
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // towards the leafs again if the new information is an upgrade over the
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // previous type of the operand nodes.
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->type()->IsUnknown()) {
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (node->left()->type()->IsLikelySmi() ||
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->right()->type()->IsLikelySmi()) {
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->type()->SetAsLikelySmi();
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (node->type()->IsLikelySmi()) {
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // The type of this node changed to LIKELY_SMI. Propagate this knowledge
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // down through the nodes.
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->left()->type()->IsUnknown()) {
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->left()->type()->SetAsLikelySmi();
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Visit(node->left());
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->right()->type()->IsUnknown()) {
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->right()->type()->SetAsLikelySmi();
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Visit(node->right());
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitCompareOperation(CompareOperation* node) {
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->type()->IsKnown()) {
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Propagate useful information down towards the leafs.
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    node->left()->type()->SetAsLikelySmiIfUnknown();
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    node->right()->type()->SetAsLikelySmiIfUnknown();
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->left());
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->right());
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // After visiting the operand nodes we have to check if this node's type
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // can be updated. If it does, then we can push that information down
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // towards the leafs again if the new information is an upgrade over the
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // previous type of the operand nodes.
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (node->type()->IsUnknown()) {
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (node->left()->type()->IsLikelySmi() ||
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->right()->type()->IsLikelySmi()) {
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      node->type()->SetAsLikelySmi();
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (node->type()->IsLikelySmi()) {
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // The type of this node changed to LIKELY_SMI. Propagate this knowledge
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // down through the nodes.
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->left()->type()->IsUnknown()) {
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->left()->type()->SetAsLikelySmi();
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Visit(node->left());
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (node->right()->type()->IsUnknown()) {
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        node->right()->type()->SetAsLikelySmi();
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Visit(node->right());
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid AstOptimizer::VisitThisFunction(ThisFunction* node) {
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Processor: public AstVisitor {
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit Processor(VariableProxy* result)
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : result_(result),
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        result_assigned_(false),
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        is_set_(false),
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        in_try_(false) {
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Process(ZoneList<Statement*>* statements);
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result_assigned() const  { return result_assigned_; }
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VariableProxy* result_;
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We are not tracking result usage via the result_'s use
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // counts (we leave the accurate computation to the
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // usage analyzer). Instead we simple remember if
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // there was ever an assignment to result_.
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result_assigned_;
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // To avoid storing to .result all the time, we eliminate some of
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the stores by keeping track of whether or not we're sure .result
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // will be overwritten anyway. This is a bit more tricky than what I
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // was hoping for
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_set_;
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool in_try_;
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* SetResult(Expression* value) {
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result_assigned_ = true;
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return new Assignment(Token::ASSIGN, result_, value,
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          RelocInfo::kNoPosition);
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Node visitors.
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEF_VISIT(type) \
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual void Visit##type(type* node);
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  AST_NODE_LIST(DEF_VISIT)
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_VISIT
5683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
5693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void VisitIterationStatement(IterationStatement* stmt);
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::Process(ZoneList<Statement*>* statements) {
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = statements->length() - 1; i >= 0; --i) {
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Visit(statements->at(i));
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitBlock(Block* node) {
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // An initializer block is the rewritten form of a variable declaration
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with initialization expressions. The initializer block contains the
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // list of assignments corresponding to the initialization expressions.
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // While unclear from the spec (ECMA-262, 3rd., 12.2), the value of
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a variable declaration with initialization expression is 'undefined'
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // with some JS VMs: For instance, using smjs, print(eval('var x = 7'))
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // returns 'undefined'. To obtain the same behavior with v8, we need
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to prevent rewriting in that case.
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!node->is_initializer_block()) Process(node->statements());
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitExpressionStatement(ExpressionStatement* node) {
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Rewrite : <x>; -> .result = <x>;
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!is_set_) {
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    node->set_expression(SetResult(node->expression()));
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!in_try_) is_set_ = true;
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitIfStatement(IfStatement* node) {
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Rewrite both then and else parts (reversed).
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool save = is_set_;
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->else_statement());
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool set_after_then = is_set_;
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_set_ = save;
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->then_statement());
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_set_ = is_set_ && set_after_then;
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Processor::VisitIterationStatement(IterationStatement* node) {
6143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Rewrite the body.
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool set_after_loop = is_set_;
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->body());
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_set_ = is_set_ && set_after_loop;
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Processor::VisitDoWhileStatement(DoWhileStatement* node) {
6223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  VisitIterationStatement(node);
6233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
6243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Processor::VisitWhileStatement(WhileStatement* node) {
6273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  VisitIterationStatement(node);
6283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
6293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Processor::VisitForStatement(ForStatement* node) {
6323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  VisitIterationStatement(node);
6333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
6343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitForInStatement(ForInStatement* node) {
6373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  VisitIterationStatement(node);
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Processor::VisitTryCatchStatement(TryCatchStatement* node) {
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Rewrite both try and catch blocks (reversed order).
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool set_after_catch = is_set_;
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->catch_block());
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_set_ = is_set_ && set_after_catch;
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool save = in_try_;
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  in_try_ = true;
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->try_block());
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  in_try_ = save;
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Processor::VisitTryFinallyStatement(TryFinallyStatement* node) {
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Rewrite both try and finally block (reversed order).
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->finally_block());
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool save = in_try_;
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  in_try_ = true;
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Visit(node->try_block());
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  in_try_ = save;
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitSwitchStatement(SwitchStatement* node) {
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Rewrite statements in all case clauses in reversed order.
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<CaseClause*>* clauses = node->cases();
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool set_after_switch = is_set_;
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = clauses->length() - 1; i >= 0; --i) {
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CaseClause* clause = clauses->at(i);
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Process(clause->statements());
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_set_ = is_set_ && set_after_switch;
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitContinueStatement(ContinueStatement* node) {
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_set_ = false;
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitBreakStatement(BreakStatement* node) {
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_set_ = false;
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Do nothing:
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitDeclaration(Declaration* node) {}
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitEmptyStatement(EmptyStatement* node) {}
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitReturnStatement(ReturnStatement* node) {}
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitWithEnterStatement(WithEnterStatement* node) {}
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitWithExitStatement(WithExitStatement* node) {}
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitDebuggerStatement(DebuggerStatement* node) {}
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Expressions are never visited yet.
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitFunctionLiteral(FunctionLiteral* node) {
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitFunctionBoilerplateLiteral(
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FunctionBoilerplateLiteral* node) {
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitConditional(Conditional* node) {
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitSlot(Slot* node) {
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitVariableProxy(VariableProxy* node) {
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitLiteral(Literal* node) {
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitRegExpLiteral(RegExpLiteral* node) {
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitArrayLiteral(ArrayLiteral* node) {
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitObjectLiteral(ObjectLiteral* node) {
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitCatchExtensionObject(CatchExtensionObject* node) {
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitAssignment(Assignment* node) {
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitThrow(Throw* node) {
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitProperty(Property* node) {
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitCall(Call* node) {
775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitCallNew(CallNew* node) {
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitCallRuntime(CallRuntime* node) {
787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitUnaryOperation(UnaryOperation* node) {
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitCountOperation(CountOperation* node) {
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitBinaryOperation(BinaryOperation* node) {
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitCompareOperation(CompareOperation* node) {
811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Processor::VisitThisFunction(ThisFunction* node) {
817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  USE(node);
818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Rewriter::Process(FunctionLiteral* function) {
823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HistogramTimerScope timer(&Counters::rewriting);
824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Scope* scope = function->scope();
825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (scope->is_function_scope()) return true;
826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Statement*>* body = function->body();
828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (body->is_empty()) return true;
829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VariableProxy* result = scope->NewTemporary(Factory::result_symbol());
831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Processor processor(result);
832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  processor.Process(body);
833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (processor.HasStackOverflow()) return false;
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (processor.result_assigned()) body->Add(new ReturnStatement(result));
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Rewriter::Optimize(FunctionLiteral* function) {
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Statement*>* body = function->body();
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (FLAG_optimize_ast && !body->is_empty()) {
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    HistogramTimerScope timer(&Counters::ast_optimization);
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    AstOptimizer optimizer(function->name());
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    optimizer.Optimize(body);
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (optimizer.HasStackOverflow()) {
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return false;
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
856