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