full-codegen.cc revision 7f4d5bd8c03935e2c0cd412e561b8fc5a6a880ae
1d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Copyright 2009 the V8 project authors. All rights reserved. 2d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Redistribution and use in source and binary forms, with or without 3d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// modification, are permitted provided that the following conditions are 4d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// met: 5d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// 6d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// * Redistributions of source code must retain the above copyright 7d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// notice, this list of conditions and the following disclaimer. 8d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// * Redistributions in binary form must reproduce the above 9d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// copyright notice, this list of conditions and the following 10d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// disclaimer in the documentation and/or other materials provided 11d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// with the distribution. 12d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// * Neither the name of Google Inc. nor the names of its 13d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// contributors may be used to endorse or promote products derived 14d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// from this software without specific prior written permission. 15d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// 16d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 28d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "v8.h" 29d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 30d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "codegen-inl.h" 31d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "compiler.h" 32d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "full-codegen.h" 336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "scopes.h" 34d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "stub-cache.h" 35d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "debug.h" 36402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "liveedit.h" 37d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 { 39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal { 40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 41d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define BAILOUT(reason) \ 42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke do { \ 43d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_trace_bailout) { \ 44d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke PrintF("%s\n", reason); \ 45d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } \ 46d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke has_supported_syntax_ = false; \ 47d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return; \ 48d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } while (false) 49d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 50d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 51d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define CHECK_BAILOUT \ 52d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke do { \ 53d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!has_supported_syntax_) return; \ 54d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } while (false) 55d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 56d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 57d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) { 58d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Scope* scope = fun->scope(); 59d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitDeclarations(scope->declarations()); 60d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 61d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 62d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(fun->body()); 63d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 64d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 65d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 66d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclarations( 67d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Declaration*>* decls) { 68d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < decls->length(); i++) { 69d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(decls->at(i)); 70d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 71d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 72d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 73d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 74d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 75d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) { 76d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0, len = stmts->length(); i < len; i++) { 77d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmts->at(i)); 78d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 79d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 80d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 81d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 82d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 83d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) { 84d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = decl->proxy()->AsProperty(); 85d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (prop != NULL) { 86d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 87d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 88d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 89d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 90d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (decl->fun() != NULL) { 91d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(decl->fun()); 92d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 93d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 94d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 95d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 96d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBlock(Block* stmt) { 97d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 98d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 99d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitExpressionStatement( 102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ExpressionStatement* stmt) { 103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->expression()); 104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) { 108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) { 113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->condition()); 114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->then_statement()); 116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->else_statement()); 118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) { 122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) { 127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) { 132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->expression()); 133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithEnterStatement( 137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke WithEnterStatement* stmt) { 138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->expression()); 139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) { 143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) { 148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("SwitchStatement"); 149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { 153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->cond()); 154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) { 160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->cond()); 161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) { 167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!FLAG_always_full_compiler) BAILOUT("ForStatement"); 168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->cond()); 174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) { 185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("ForInStatement"); 186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) { 190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->catch_block()); 193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryFinallyStatement( 197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryFinallyStatement* stmt) { 198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDebuggerStatement( 205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DebuggerStatement* stmt) { 206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) { 211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid FullCodeGenSyntaxChecker::VisitSharedFunctionInfoLiteral( 2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SharedFunctionInfoLiteral* expr) { 2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block BAILOUT("SharedFunctionInfoLiteral"); 218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitConditional(Conditional* expr) { 222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->condition()); 223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->then_expression()); 225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->else_expression()); 227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSlot(Slot* expr) { 231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) { 236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitLiteral(Literal* expr) { 241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) { 246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) { 251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); 252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0, len = properties->length(); i < len; i++) { 254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ObjectLiteral::Property* property = properties->at(i); 255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (property->IsCompileTimeValue()) continue; 256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(property->key()); 257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(property->value()); 259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) { 265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Expression*>* subexprs = expr->values(); 266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0, len = subexprs->length(); i < len; i++) { 267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* subexpr = subexprs->at(i); 268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (subexpr->AsLiteral() != NULL) continue; 269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(subexpr); 271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 274d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCatchExtensionObject( 277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CatchExtensionObject* expr) { 278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->key()); 279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->value()); 281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) { 285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Token::Value op = expr->op(); 286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (op == Token::INIT_CONST) BAILOUT("initialize constant"); 287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = expr->target()->AsProperty(); 290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(var == NULL || prop == NULL); 291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var != NULL) { 292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var->mode() == Variable::CONST) BAILOUT("Assignment to const"); 293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // All other variables are supported. 294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (prop != NULL) { 295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This is a throw reference error. 301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("non-variable/non-property assignment"); 302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->value()); 305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThrow(Throw* expr) { 309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->exception()); 310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitProperty(Property* expr) { 314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->obj()); 315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->key()); 317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCall(Call* expr) { 321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* fun = expr->expression(); 322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Expression*>* args = expr->arguments(); 323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = fun->AsVariableProxy()->AsVariable(); 324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for supported calls 326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var != NULL && var->is_possibly_eval()) { 327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("call to the identifier 'eval'"); 328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (var != NULL && !var->is_this() && var->is_global()) { 329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Calls to global variables are supported. 330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (var != NULL && var->slot() != NULL && 331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke var->slot()->type() == Slot::LOOKUP) { 332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("call to a lookup slot"); 333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (fun->AsProperty() != NULL) { 334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = fun->AsProperty(); 335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 340d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Otherwise the call is supported if the function expression is. 341d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(fun); 342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check all arguments to the call. 344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < args->length(); i++) { 345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(args->at(i)); 346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) { 352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->expression()); 353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Expression*>* args = expr->arguments(); 355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check all arguments to the call 356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < args->length(); i++) { 357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(args->at(i)); 358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 362d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 363d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) { 364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for inline runtime call 365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (expr->name()->Get(0) == '_' && 366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) { 367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("inlined runtime call"); 368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check all arguments to the call. (Relies on TEMP meaning STACK.) 370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < expr->arguments()->length(); i++) { 371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->arguments()->at(i)); 372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) { 378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (expr->op()) { 379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::ADD: 3804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case Token::BIT_NOT: 381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::NOT: 3824515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case Token::SUB: 383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::TYPEOF: 384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::VOID: 385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->expression()); 386d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 387d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::DELETE: 388d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("UnaryOperation: DELETE"); 389d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke default: 390d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 393d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 395d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) { 396d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 397d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = expr->expression()->AsProperty(); 398d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(var == NULL || prop == NULL); 399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var != NULL) { 400d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // All global variables are supported. 401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!var->is_global()) { 402d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(var->slot() != NULL); 403d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot::Type type = var->slot()->type(); 404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (type == Slot::LOOKUP) { 405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("CountOperation with lookup slot"); 406d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (prop != NULL) { 409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This is a throw reference error. 415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("CountOperation non-variable/non-property expression"); 416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) { 421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->left()); 422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->right()); 424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) { 428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->left()); 429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->right()); 431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) { 435d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef BAILOUT 439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef CHECK_BAILOUT 440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Statement* stmt) { 4437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt); 4447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Expression* expr) { 4487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr); 4497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDeclaration(Declaration* decl) { 4537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBlock(Block* stmt) { 4577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitExpressionStatement( 4617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ExpressionStatement* stmt) { 4627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if expression is breakable. 4637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 4647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) { 4687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) { 4727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the condition is breakable the if statement is breakable. 4737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->condition()); 4747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitContinueStatement( 4787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ContinueStatement* stmt) { 4797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { 4837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { 4877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Return is breakable if the expression is. 4887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 4897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWithEnterStatement( 4937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch WithEnterStatement* stmt) { 4947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 4957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 4967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWithExitStatement( 4997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch WithExitStatement* stmt) { 5007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { 5047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Switch statements breakable if the tag expression is. 5057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->tag()); 5067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { 5107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark do while as breakable to avoid adding a break slot in front of it. 5117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 5127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) { 5167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark while statements breakable if the condition expression is. 5177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 5187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForStatement(ForStatement* stmt) { 5227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for statements breakable if the condition expression is. 5237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (stmt->cond() != NULL) { 5247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 5257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 5267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) { 5307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for in statements breakable if the enumerable expression is. 5317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->enumerable()); 5327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryCatchStatement( 5367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryCatchStatement* stmt) { 5377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try catch as breakable to avoid adding a break slot in front of it. 5387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 5397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryFinallyStatement( 5437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryFinallyStatement* stmt) { 5447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try finally as breakable to avoid adding a break slot in front of it. 5457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 5467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDebuggerStatement( 5507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebuggerStatement* stmt) { 5517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The debugger statement is breakable. 5527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 5537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) { 5577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSharedFunctionInfoLiteral( 5617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SharedFunctionInfoLiteral* expr) { 5627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitConditional(Conditional* expr) { 5667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSlot(Slot* expr) { 5707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) { 5747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitLiteral(Literal* expr) { 5787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) { 5827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) { 5867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { 5907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCatchExtensionObject( 5947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CatchExtensionObject* expr) { 5957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 5967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitAssignment(Assignment* expr) { 5997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If assigning to a property (including a global property) the assignment is 6007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. 6017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 6027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Property* prop = expr->target()->AsProperty(); 6037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (prop != NULL || (var != NULL && var->is_global())) { 6047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 6057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return; 6067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Otherwise the assignment is breakable if the assigned value is. 6097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->value()); 6107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThrow(Throw* expr) { 6147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Throw is breakable if the expression is. 6157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->exception()); 6167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitProperty(Property* expr) { 6207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Property load is breakable. 6217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 6227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCall(Call* expr) { 6267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls both through IC and call stub are breakable. 6277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 6287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallNew(CallNew* expr) { 6327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls through new are breakable. 6337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 6347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) { 6387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) { 6427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 6437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCountOperation(CountOperation* expr) { 6477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 6487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) { 6527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 6537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->right()); 6547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) { 6587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 6597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->right()); 6607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) { 6647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 667d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm()) 668d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuHandle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) { 6703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Script> script = info->script(); 671d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!script->IsUndefined() && !script->source()->IsUndefined()) { 672d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = String::cast(script->source())->length(); 673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Counters::total_full_codegen_source_size.Increment(len); 674d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 6753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CodeGenerator::MakeCodePrologue(info); 676d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kInitialBufferSize = 4 * KB; 677d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke MacroAssembler masm(NULL, kInitialBufferSize); 678402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 6793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FullCodeGenerator cgen(&masm); 6803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu cgen.Generate(info, PRIMARY); 681d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (cgen.HasStackOverflow()) { 682d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(!Top::has_pending_exception()); 683d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return Handle<Code>::null(); 684d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 685d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); 6866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 687d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 688d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 689d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 690d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::SlotOffset(Slot* slot) { 691d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(slot != NULL); 692d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Offset is negative because higher indexes are at lower addresses. 693d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int offset = -slot->index() * kPointerSize; 694d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Adjust by a (parameter or local) base offset. 695d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (slot->type()) { 696d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::PARAMETER: 6973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu offset += (scope()->num_parameters() + 1) * kPointerSize; 698d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 699d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOCAL: 700d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += JavaScriptFrameConstants::kLocal0Offset; 701d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 702d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::CONTEXT: 703d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOOKUP: 704d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 705d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 706d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return offset; 707d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 708d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 709d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 710d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDeclarations( 711d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Declaration*>* declarations) { 712d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int length = declarations->length(); 713d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int globals = 0; 714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < length; i++) { 715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot* slot = var->slot(); 718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If it was not possible to allocate the variable at compile 720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // time, we need to "declare" it at runtime to make sure it 721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // actually exists in the local context. 722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { 723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitDeclaration(decl); 724d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 725d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Count global variables and functions for later processing 726d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke globals++; 727d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 728d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 729d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 730d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Compute array of global variable and function declarations. 731d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Do nothing in case of no declared global functions or variables. 732d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (globals > 0) { 733d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED); 734d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int j = 0, i = 0; i < length; i++) { 735d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 736d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 737d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot* slot = var->slot(); 738d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 739d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { 740d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *(var->name())); 741d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (decl->fun() == NULL) { 742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var->mode() == Variable::CONST) { 743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // In case this is const property use the hole. 744d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_the_hole(j++); 745d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 746d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_undefined(j++); 747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 748d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 7496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function = 7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Compiler::BuildFunctionInfo(decl->fun(), script(), this); 751d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for stack-overflow exception. 752d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (HasStackOverflow()) return; 753d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *function); 754d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 755d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 756d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 757d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Invoke the platform-dependent code generator to do the actual 758d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // declaration the global variables and functions. 759d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeclareGlobals(array); 760d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 761d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 762d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 763d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 764d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 765d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 766d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, fun->start_position()); 767d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 769d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 771d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 772d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, fun->end_position()); 774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 777d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 778d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) { 779d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 7807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 7817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (!Debugger::IsDebuggerActive()) { 7827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 7837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 7847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if the statement will be breakable without adding a debug break 7857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // slot. 7867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch BreakableStatementChecker checker; 7877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch checker.Check(stmt); 7887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Record the statement position right here if the statement is not 7897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. For breakable statements the actual recording of the 7907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // position will be postponed to the breakable code (typically an IC). 7917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch bool position_recorded = CodeGenerator::RecordPositions( 7927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch masm_, stmt->statement_pos(), !checker.is_breakable()); 7937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the position recording did record a new position generate a debug 7947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // break slot to make the statement breakable. 7957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (position_recorded) { 7967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Debug::GenerateSlot(masm_); 7977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 7987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 7997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 800d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 8017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 8027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 8037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 8047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 8057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 8067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) { 8077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (FLAG_debug_info) { 8087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 8097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (!Debugger::IsDebuggerActive()) { 8107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodeGenerator::RecordPositions(masm_, pos); 8117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 8127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if the expression will be breakable without adding a debug break 8137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // slot. 8147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch BreakableStatementChecker checker; 8157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch checker.Check(expr); 8167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Record a statement position right here if the expression is not 8177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. For breakable expressions the actual recording of the 8187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // position will be postponed to the breakable code (typically an IC). 8197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // NOTE this will record a statement position for something which might 8207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // not be a statement. As stepping in the debugger will only stop at 8217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // statement positions this is used for e.g. the condition expression of 8227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // a do while loop. 8237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch bool position_recorded = CodeGenerator::RecordPositions( 8247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch masm_, pos, !checker.is_breakable()); 8257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the position recording did record a new position generate a debug 8267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // break slot to make the statement breakable. 8277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (position_recorded) { 8287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Debug::GenerateSlot(masm_); 8297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 8307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 8317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 8327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodeGenerator::RecordPositions(masm_, pos); 8337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 834d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 835d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 836d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 837d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 838d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(int pos) { 839d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 840d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, pos); 841d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 842d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 843d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 844d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 845d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetSourcePosition(int pos) { 846d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info && pos != RelocInfo::kNoPosition) { 847d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke masm_->RecordPosition(pos); 848d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 849d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 850d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 851d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 8527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) { 8537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Handle<String> name = expr->name(); 8547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (strcmp("_IsSmi", *name->ToCString()) == 0) { 8557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsSmi(expr->arguments()); 8567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_IsNonNegativeSmi", *name->ToCString()) == 0) { 8577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsNonNegativeSmi(expr->arguments()); 8587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_IsObject", *name->ToCString()) == 0) { 8597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsObject(expr->arguments()); 8607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_IsUndetectableObject", *name->ToCString()) == 0) { 8617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsUndetectableObject(expr->arguments()); 8627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_IsFunction", *name->ToCString()) == 0) { 8637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsFunction(expr->arguments()); 8647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_IsArray", *name->ToCString()) == 0) { 8657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsArray(expr->arguments()); 8667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_IsRegExp", *name->ToCString()) == 0) { 8677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsRegExp(expr->arguments()); 8687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_IsConstructCall", *name->ToCString()) == 0) { 8697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitIsConstructCall(expr->arguments()); 8707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_ObjectEquals", *name->ToCString()) == 0) { 8717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitObjectEquals(expr->arguments()); 8727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_Arguments", *name->ToCString()) == 0) { 8737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitArguments(expr->arguments()); 8747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_ArgumentsLength", *name->ToCString()) == 0) { 8757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitArgumentsLength(expr->arguments()); 8767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_ClassOf", *name->ToCString()) == 0) { 8777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitClassOf(expr->arguments()); 8787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_Log", *name->ToCString()) == 0) { 8797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitLog(expr->arguments()); 8807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_RandomHeapNumber", *name->ToCString()) == 0) { 8817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitRandomHeapNumber(expr->arguments()); 8827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_SubString", *name->ToCString()) == 0) { 8837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitSubString(expr->arguments()); 8847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_RegExpExec", *name->ToCString()) == 0) { 8857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitRegExpExec(expr->arguments()); 8867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_ValueOf", *name->ToCString()) == 0) { 8877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitValueOf(expr->arguments()); 8887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_SetValueOf", *name->ToCString()) == 0) { 8897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitSetValueOf(expr->arguments()); 8907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_NumberToString", *name->ToCString()) == 0) { 8917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitNumberToString(expr->arguments()); 8927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_StringCharFromCode", *name->ToCString()) == 0) { 8937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitStringCharFromCode(expr->arguments()); 8947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_StringCharCodeAt", *name->ToCString()) == 0) { 8957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitStringCharCodeAt(expr->arguments()); 8967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_StringCharAt", *name->ToCString()) == 0) { 8977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitStringCharAt(expr->arguments()); 8987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_StringAdd", *name->ToCString()) == 0) { 8997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitStringAdd(expr->arguments()); 9007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_StringCompare", *name->ToCString()) == 0) { 9017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitStringCompare(expr->arguments()); 9027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_MathPow", *name->ToCString()) == 0) { 9037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitMathPow(expr->arguments()); 9047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_MathSin", *name->ToCString()) == 0) { 9057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitMathSin(expr->arguments()); 9067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_MathCos", *name->ToCString()) == 0) { 9077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitMathCos(expr->arguments()); 9087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_MathSqrt", *name->ToCString()) == 0) { 9097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitMathSqrt(expr->arguments()); 9107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_CallFunction", *name->ToCString()) == 0) { 9117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitCallFunction(expr->arguments()); 9127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_RegExpConstructResult", *name->ToCString()) == 0) { 9137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitRegExpConstructResult(expr->arguments()); 9147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_SwapElements", *name->ToCString()) == 0) { 9157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitSwapElements(expr->arguments()); 9167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else if (strcmp("_GetFromCache", *name->ToCString()) == 0) { 9177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitGetFromCache(expr->arguments()); 9187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 9197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch UNREACHABLE(); 9207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 9217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 9227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label eval_right, done; 926d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 927d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Set up the appropriate context for the left subexpression based 928d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // on the operation and our own context. Initially assume we can 929d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // inherit both true and false labels from our context. 930d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (expr->op() == Token::OR) { 931d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (context_) { 932d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kUninitialized: 933d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 934d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kEffect: 935d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &done, &eval_right); 936d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 937d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValue: 938d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValueControl(expr->left(), 939d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 940d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &done, 941d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right); 942d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 943d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTest: 944d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), true_label_, &eval_right); 945d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 946d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValueTest: 947d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValueControl(expr->left(), 948d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 949d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke true_label_, 950d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right); 951d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 952d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTestValue: 953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), true_label_, &eval_right); 954d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 955d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 956d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 957d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_EQ(Token::AND, expr->op()); 958d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (context_) { 959d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kUninitialized: 960d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 961d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kEffect: 962d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &eval_right, &done); 963d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 964d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValue: 965d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControlValue(expr->left(), 966d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right, 968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &done); 969d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 970d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTest: 971d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &eval_right, false_label_); 972d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 973d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValueTest: 974d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &eval_right, false_label_); 975d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 976d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTestValue: 977d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControlValue(expr->left(), 978d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 979d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right, 980d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke false_label_); 981d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 982d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 983d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 984d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 985d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&eval_right); 986d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->right()); 987d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 988d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 989d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 990d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 991d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 992d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) { 993d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Block"); 994d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Breakable nested_statement(this, stmt); 995d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 996d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 997d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(nested_statement.break_target()); 998d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 999d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1000d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1001d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 1002d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ExpressionStatement"); 1003d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1004d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForEffect(stmt->expression()); 1005d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1006d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1007d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1008d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 1009d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ EmptyStatement"); 1010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1012d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1013d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1014d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 1015d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ IfStatement"); 1016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1017d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label then_part, else_part, done; 1018d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1019d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Do not worry about optimizing for empty then or else bodies. 1020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->condition(), &then_part, &else_part); 1021d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&then_part); 1023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->then_statement()); 1024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1025d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1026d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&else_part); 1027d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->else_statement()); 1028d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1029d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1030d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1031d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1032d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1033d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 1034d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ContinueStatement"); 1035d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1036d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1037d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 1038d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsContinueTarget(stmt->target())) { 1039d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 1040d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 1041d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1042d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1043d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1044d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration* loop = current->AsIteration(); 1045d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(loop->continue_target()); 1046d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1047d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1048d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1049d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 1050d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ BreakStatement"); 1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1053d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsBreakTarget(stmt->target())) { 1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 1056d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 1057d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1058d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1059d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1060d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Breakable* target = current->AsBreakable(); 1061d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(target->break_target()); 1062d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1063d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1064d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1065d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1066d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ReturnStatement"); 1067d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1068d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* expr = stmt->expression(); 1069d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr, kAccumulator); 1070d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1071d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Exit all nested statements. 1072d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1073d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 1074d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (current != NULL) { 1075d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 1076d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 1077d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1078d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1079d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 10807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitReturnSequence(); 1081d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1082d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1083d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1084d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { 1085d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WithEnterStatement"); 1086d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1087d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1088d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(stmt->expression(), kStack); 1089d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->is_catch_block()) { 1090d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kPushCatchContext, 1); 1091d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 1092d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kPushContext, 1); 1093d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1094d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Both runtime calls return the new context in both the context and the 1095d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // result registers. 1096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Update local stack frame context field. 1098d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1099d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) { 1103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WithExitStatement"); 1104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Pop context. 1107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Update local stack frame context field. 1109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DoWhileStatement"); 1115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label body, stack_limit_hit, stack_check_success; 1117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ StackLimitCheck(&stack_limit_hit); 1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_check_success); 1127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.continue_target()); 11297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 11307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Record the position of the do while condition and make sure it is possible 11317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // to break on the condition. 11327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(stmt->cond(), stmt->condition_position()); 11337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 1135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_limit_hit); 1137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StackCheckStub stack_stub; 1138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallStub(&stack_stub); 1139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&stack_check_success); 1140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 1142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WhileStatement"); 1149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label body, stack_limit_hit, stack_check_success; 1150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop. 1155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(loop_statement.continue_target()); 1156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.continue_target()); 11617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Emit the statement position here as this is where the while statement code 11627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // starts. 11637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1164f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ StackLimitCheck(&stack_limit_hit); 1167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_check_success); 1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 1170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_limit_hit); 1172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StackCheckStub stack_stub; 1173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallStub(&stack_stub); 1174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&stack_check_success); 1175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 1177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ForStatement"); 1183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label test, body, stack_limit_hit, stack_check_success; 1184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 1187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 1188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop (even if empty). 1192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&test); 1193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.continue_target()); 1198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 1201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 1202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&test); 12057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Emit the statement position here as this is where the for statement code 12067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // starts. 12077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ StackLimitCheck(&stack_limit_hit); 1211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_check_success); 1212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 1214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 1215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 1216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&body); 1217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_limit_hit); 1220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StackCheckStub stack_stub; 1221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallStub(&stack_stub); 1222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&stack_check_success); 1223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 1225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryCatchStatement"); 1231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try block adds a handler to the exception handler chain 1233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // before entering, and removes it again when exiting normally. 1234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If an exception is thrown during execution of the try block, 1235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // control is passed to the handler, which also consumes the handler. 1236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // At this point, the exception is in a register, and store it in 1237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // the temporary local variable (prints as ".catch-var") before 1238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the catch block. The catch block has been rewritten 1239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // to introduce a new scope to bind the catch variable and to remove 1240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // that scope again afterwards. 1241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label try_handler_setup, catch_entry, done; 1243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 1244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code, exception in result register. 1245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Store exception in local .catch variable before executing catch block. 1247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The catch variable is *always* a variable proxy for a local variable. 1249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable(); 1250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_NOT_NULL(catch_var); 1251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot* variable_slot = catch_var->slot(); 1252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_NOT_NULL(variable_slot); 1253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_EQ(Slot::LOCAL, variable_slot->type()); 1254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(SlotOffset(variable_slot), result_register()); 1255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->catch_block()); 1258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try block code. Sets up the exception handler chain. 1261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 1262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryCatch try_block(this, &catch_entry); 1264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 1265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryFinallyStatement"); 1274d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try finally is compiled by setting up a try-handler on the stack while 1276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the try body, and removing it again afterwards. 1277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try-finally construct can enter the finally block in three ways: 1279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1. By exiting the try-block normally. This removes the try-handler and 1280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // calls the finally block code before continuing. 1281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 2. By exiting the try-block with a function-local control flow transfer 1282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (break/continue/return). The site of the, e.g., break removes the 1283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // try handler and calls the finally block code before continuing 1284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // its outward control transfer. 1285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 3. by exiting the try-block with a thrown exception. 1286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This can happen in nested function calls. It traverses the try-handler 1287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // chain and consumes the try-handler entry before jumping to the 1288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // handler code. The handler code then calls the finally-block before 1289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // rethrowing the exception. 1290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The finally block must assume a return address on top of the stack 1292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (or in the link register on ARM chips) and a value (return value or 1293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception) in the result register (rax/eax/r0), both of which must 1294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // be preserved. The return address isn't GC-safe, so it should be 1295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // cooked before GC. 1296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label finally_entry; 1297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label try_handler_setup; 1298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup the try-handler chain. Use a call to 1300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Jump to try-handler setup and try-block code. Use call to put try-handler 1301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // address on stack. 1302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 1303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code. Return address of call is pushed on handler stack. 1304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This code is only executed during stack-handler traversal when an 1306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception is thrown. The execption is in the result register, which 1307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // is retained by the finally block. 1308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Call the finally block and then rethrow the exception. 1309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ push(result_register()); 1311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kReThrow, 1); 1312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&finally_entry); 1315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Finally block implementation. 1317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Finally finally_block(this); 1318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnterFinallyBlock(); 1319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 1320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ExitFinallyBlock(); // Return to the calling code. 1321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 1324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup try handler (stack pointer registers). 1326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryFinally try_block(this, &finally_entry); 1327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); 1328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Execute the finally block on the way out. 1332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 1338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DebuggerStatement"); 1339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 13404515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 1341402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu __ DebugBreak(); 1342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Ignore the return value. 1343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 1344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) { 1348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Conditional"); 1349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label true_case, false_case, done; 1350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->condition(), &true_case, &false_case); 1351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&true_case); 13537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->then_expression(), 13547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->then_expression_position()); 1355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->then_expression()); 1356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, jump to done. 1357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (context_ == Expression::kEffect || context_ == Expression::kValue) { 1358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&false_case); 13627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->else_expression(), 13637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->else_expression_position()); 1364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->else_expression()); 1365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, merge it with true case here. 1366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (context_ == Expression::kEffect || context_ == Expression::kValue) { 1367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitSlot(Slot* expr) { 1373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Slots do not appear directly in the AST. 1374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 1375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) { 1379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Literal"); 1380d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Apply(context_, expr); 1381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1382d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1384f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ FunctionLiteral"); 1386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1387f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Build the function boilerplate and instantiate it. 1388f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<SharedFunctionInfo> function_info = 1389f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Compiler::BuildFunctionInfo(expr, script(), this); 1390f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (HasStackOverflow()) return; 1391f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke EmitNewClosure(function_info); 1392f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1393f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1394f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1395f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitSharedFunctionInfoLiteral( 1396f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke SharedFunctionInfoLiteral* expr) { 1397f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); 1398f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke EmitNewClosure(expr->shared_function_info()); 1399f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1400f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1401f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1402d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 1403d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Call runtime routine to allocate the catch extension object and 1404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // assign the exception value to the catch variable. 1405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ CatchExtensionObject"); 1406d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr->key(), kStack); 1407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr->value(), kStack); 1408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Create catch extension object. 1409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 1410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Apply(context_, result_register()); 1411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) { 1415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Throw"); 1416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr->exception(), kStack); 1417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kThrow, 1); 1418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Never returns here. 1419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryFinally::Exit(int stack_depth) { 1423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 1424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(finally_entry_); 1427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return 0; 1428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryCatch::Exit(int stack_depth) { 1432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 1433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1435d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return 0; 1436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __ 1439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} } // namespace v8::internal 1442