full-codegen.cc revision d91b9f7d46489a9ee00f9cb415630299c76a502b
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" 33d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "stub-cache.h" 34d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "debug.h" 35d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 36d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 { 37d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal { 38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define BAILOUT(reason) \ 40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke do { \ 41d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_trace_bailout) { \ 42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke PrintF("%s\n", reason); \ 43d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } \ 44d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke has_supported_syntax_ = false; \ 45d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return; \ 46d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } while (false) 47d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 48d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 49d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define CHECK_BAILOUT \ 50d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke do { \ 51d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!has_supported_syntax_) return; \ 52d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } while (false) 53d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 54d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 55d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) { 56d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Scope* scope = fun->scope(); 57d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 58d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (scope->num_heap_slots() > 0) { 59d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // We support functions with a local context if they do not have 60d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // parameters that need to be copied into the context. 61d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0, len = scope->num_parameters(); i < len; i++) { 62d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot* slot = scope->parameter(i)->slot(); 63d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (slot != NULL && slot->type() == Slot::CONTEXT) { 64d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("Function has context-allocated parameters."); 65d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 66d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 67d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 68d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 69d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitDeclarations(scope->declarations()); 70d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 71d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 72d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(fun->body()); 73d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 74d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 75d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 76d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclarations( 77d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Declaration*>* decls) { 78d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < decls->length(); i++) { 79d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(decls->at(i)); 80d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 81d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 82d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 83d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 84d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 85d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) { 86d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0, len = stmts->length(); i < len; i++) { 87d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmts->at(i)); 88d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 89d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 90d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 91d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 92d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 93d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) { 94d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = decl->proxy()->AsProperty(); 95d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (prop != NULL) { 96d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 97d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 98d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 99d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (decl->fun() != NULL) { 101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(decl->fun()); 102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBlock(Block* stmt) { 107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitExpressionStatement( 112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ExpressionStatement* stmt) { 113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->expression()); 114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) { 118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) { 123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->condition()); 124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->then_statement()); 126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->else_statement()); 128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) { 132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) { 137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) { 142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->expression()); 143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithEnterStatement( 147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke WithEnterStatement* stmt) { 148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->expression()); 149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) { 153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) { 158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("SwitchStatement"); 159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { 163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->cond()); 164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) { 170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->cond()); 171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) { 177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!FLAG_always_full_compiler) BAILOUT("ForStatement"); 178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->cond()); 184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) { 195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("ForInStatement"); 196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) { 200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->catch_block()); 203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryFinallyStatement( 207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryFinallyStatement* stmt) { 208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDebuggerStatement( 215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DebuggerStatement* stmt) { 216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) { 221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitFunctionBoilerplateLiteral( 226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FunctionBoilerplateLiteral* expr) { 227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("FunctionBoilerplateLiteral"); 228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitConditional(Conditional* expr) { 232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->condition()); 233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->then_expression()); 235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->else_expression()); 237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSlot(Slot* expr) { 241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) { 246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitLiteral(Literal* expr) { 251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) { 256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) { 261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); 262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0, len = properties->length(); i < len; i++) { 264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ObjectLiteral::Property* property = properties->at(i); 265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (property->IsCompileTimeValue()) continue; 266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(property->key()); 267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(property->value()); 269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 274d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) { 275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Expression*>* subexprs = expr->values(); 276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0, len = subexprs->length(); i < len; i++) { 277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* subexpr = subexprs->at(i); 278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (subexpr->AsLiteral() != NULL) continue; 279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(subexpr); 281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCatchExtensionObject( 287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CatchExtensionObject* expr) { 288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->key()); 289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->value()); 291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) { 295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Token::Value op = expr->op(); 296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (op == Token::INIT_CONST) BAILOUT("initialize constant"); 297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = expr->target()->AsProperty(); 300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(var == NULL || prop == NULL); 301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var != NULL) { 302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var->mode() == Variable::CONST) BAILOUT("Assignment to const"); 303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // All other variables are supported. 304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (prop != NULL) { 305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This is a throw reference error. 311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("non-variable/non-property assignment"); 312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->value()); 315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThrow(Throw* expr) { 319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->exception()); 320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitProperty(Property* expr) { 324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->obj()); 325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->key()); 327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCall(Call* expr) { 331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* fun = expr->expression(); 332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Expression*>* args = expr->arguments(); 333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = fun->AsVariableProxy()->AsVariable(); 334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for supported calls 336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var != NULL && var->is_possibly_eval()) { 337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("call to the identifier 'eval'"); 338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (var != NULL && !var->is_this() && var->is_global()) { 339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Calls to global variables are supported. 340d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (var != NULL && var->slot() != NULL && 341d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke var->slot()->type() == Slot::LOOKUP) { 342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("call to a lookup slot"); 343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (fun->AsProperty() != NULL) { 344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = fun->AsProperty(); 345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Otherwise the call is supported if the function expression is. 351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(fun); 352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check all arguments to the call. 354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < args->length(); i++) { 355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(args->at(i)); 356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) { 362d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->expression()); 363d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Expression*>* args = expr->arguments(); 365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check all arguments to the call 366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < args->length(); i++) { 367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(args->at(i)); 368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) { 374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for inline runtime call 375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (expr->name()->Get(0) == '_' && 376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) { 377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("inlined runtime call"); 378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check all arguments to the call. (Relies on TEMP meaning STACK.) 380d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < expr->arguments()->length(); i++) { 381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->arguments()->at(i)); 382d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 386d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 387d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) { 388d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (expr->op()) { 389d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::ADD: 390d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::NOT: 391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::TYPEOF: 392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::VOID: 393d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->expression()); 394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 395d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::BIT_NOT: 396d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("UnaryOperation: BIT_NOT"); 397d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::DELETE: 398d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("UnaryOperation: DELETE"); 399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Token::SUB: 400d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("UnaryOperation: SUB"); 401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke default: 402d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 403d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 406d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) { 408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = expr->expression()->AsProperty(); 410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(var == NULL || prop == NULL); 411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var != NULL) { 412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // All global variables are supported. 413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!var->is_global()) { 414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(var->slot() != NULL); 415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot::Type type = var->slot()->type(); 416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (type == Slot::LOOKUP) { 417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("CountOperation with lookup slot"); 418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else if (prop != NULL) { 421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->obj()); 422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(prop->key()); 424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This is a throw reference error. 427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke BAILOUT("CountOperation non-variable/non-property expression"); 428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) { 433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->left()); 434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 435d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->right()); 436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) { 440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->left()); 441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_BAILOUT; 442d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->right()); 443d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 444d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 445d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 446d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) { 447d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Supported. 448d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 449d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 450d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef BAILOUT 451d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef CHECK_BAILOUT 452d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 453d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 454d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm()) 455d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 456d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeHandle<Code> FullCodeGenerator::MakeCode(FunctionLiteral* fun, 457d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Handle<Script> script, 458d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool is_eval) { 459d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!script->IsUndefined() && !script->source()->IsUndefined()) { 460d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = String::cast(script->source())->length(); 461d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Counters::total_full_codegen_source_size.Increment(len); 462d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 463d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::MakeCodePrologue(fun); 464d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kInitialBufferSize = 4 * KB; 465d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke MacroAssembler masm(NULL, kInitialBufferSize); 466d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FullCodeGenerator cgen(&masm, script, is_eval); 467d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke cgen.Generate(fun); 468d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (cgen.HasStackOverflow()) { 469d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(!Top::has_pending_exception()); 470d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return Handle<Code>::null(); 471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 472d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); 473d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script); 474d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 475d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 476d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 477d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::SlotOffset(Slot* slot) { 478d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(slot != NULL); 479d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Offset is negative because higher indexes are at lower addresses. 480d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int offset = -slot->index() * kPointerSize; 481d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Adjust by a (parameter or local) base offset. 482d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (slot->type()) { 483d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::PARAMETER: 484d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += (function_->scope()->num_parameters() + 1) * kPointerSize; 485d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 486d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOCAL: 487d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += JavaScriptFrameConstants::kLocal0Offset; 488d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 489d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::CONTEXT: 490d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOOKUP: 491d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 492d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 493d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return offset; 494d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 495d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 496d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 497d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDeclarations( 498d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Declaration*>* declarations) { 499d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int length = declarations->length(); 500d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int globals = 0; 501d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < length; i++) { 502d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 503d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 504d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot* slot = var->slot(); 505d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 506d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If it was not possible to allocate the variable at compile 507d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // time, we need to "declare" it at runtime to make sure it 508d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // actually exists in the local context. 509d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { 510d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitDeclaration(decl); 511d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 512d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Count global variables and functions for later processing 513d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke globals++; 514d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 515d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 516d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 517d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Compute array of global variable and function declarations. 518d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Do nothing in case of no declared global functions or variables. 519d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (globals > 0) { 520d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED); 521d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int j = 0, i = 0; i < length; i++) { 522d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 523d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 524d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot* slot = var->slot(); 525d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 526d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { 527d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *(var->name())); 528d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (decl->fun() == NULL) { 529d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var->mode() == Variable::CONST) { 530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // In case this is const property use the hole. 531d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_the_hole(j++); 532d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 533d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_undefined(j++); 534d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 535d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 536d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Handle<JSFunction> function = 537d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Compiler::BuildBoilerplate(decl->fun(), script_, this); 538d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for stack-overflow exception. 539d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (HasStackOverflow()) return; 540d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *function); 541d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 542d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 543d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 544d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Invoke the platform-dependent code generator to do the actual 545d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // declaration the global variables and functions. 546d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeclareGlobals(array); 547d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 548d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 550d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 551d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 552d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 553d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, fun->start_position()); 554d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 555d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 556d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 557d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 558d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 559d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 560d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, fun->end_position()); 561d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 562d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 563d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 564d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 565d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) { 566d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 567d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 568d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 569d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 570d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 571d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 572d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(int pos) { 573d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 574d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, pos); 575d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 576d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 577d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 578d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 579d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetSourcePosition(int pos) { 580d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info && pos != RelocInfo::kNoPosition) { 581d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke masm_->RecordPosition(pos); 582d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 583d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 584d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 585d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 586d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 587d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label eval_right, done; 588d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 589d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Set up the appropriate context for the left subexpression based 590d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // on the operation and our own context. Initially assume we can 591d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // inherit both true and false labels from our context. 592d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (expr->op() == Token::OR) { 593d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (context_) { 594d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kUninitialized: 595d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 596d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kEffect: 597d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &done, &eval_right); 598d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 599d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValue: 600d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValueControl(expr->left(), 601d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 602d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &done, 603d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right); 604d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 605d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTest: 606d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), true_label_, &eval_right); 607d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 608d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValueTest: 609d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValueControl(expr->left(), 610d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 611d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke true_label_, 612d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right); 613d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 614d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTestValue: 615d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), true_label_, &eval_right); 616d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 617d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 618d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 619d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_EQ(Token::AND, expr->op()); 620d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (context_) { 621d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kUninitialized: 622d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 623d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kEffect: 624d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &eval_right, &done); 625d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 626d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValue: 627d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControlValue(expr->left(), 628d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 629d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right, 630d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &done); 631d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 632d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTest: 633d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &eval_right, false_label_); 634d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 635d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kValueTest: 636d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->left(), &eval_right, false_label_); 637d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 638d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Expression::kTestValue: 639d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControlValue(expr->left(), 640d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_, 641d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke &eval_right, 642d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke false_label_); 643d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 644d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 645d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 646d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 647d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&eval_right); 648d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->right()); 649d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 650d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 651d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 652d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 653d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 654d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) { 655d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Block"); 656d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Breakable nested_statement(this, stmt); 657d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 658d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 659d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(nested_statement.break_target()); 660d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 661d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 662d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 663d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 664d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ExpressionStatement"); 665d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 666d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForEffect(stmt->expression()); 667d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 668d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 669d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 670d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 671d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ EmptyStatement"); 672d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 674d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 675d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 676d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 677d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ IfStatement"); 678d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 679d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label then_part, else_part, done; 680d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 681d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Do not worry about optimizing for empty then or else bodies. 682d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->condition(), &then_part, &else_part); 683d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 684d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&then_part); 685d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->then_statement()); 686d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 687d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 688d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&else_part); 689d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->else_statement()); 690d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 691d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 692d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 693d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 694d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 695d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 696d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ContinueStatement"); 697d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 698d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 699d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 700d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsContinueTarget(stmt->target())) { 701d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 702d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 703d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 704d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 705d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 706d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration* loop = current->AsIteration(); 707d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(loop->continue_target()); 708d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 709d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 710d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 711d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 712d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ BreakStatement"); 713d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsBreakTarget(stmt->target())) { 717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Breakable* target = current->AsBreakable(); 723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(target->break_target()); 724d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 725d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 726d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 727d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 728d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ReturnStatement"); 729d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 730d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* expr = stmt->expression(); 731d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr, kAccumulator); 732d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 733d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Exit all nested statements. 734d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 735d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 736d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (current != NULL) { 737d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 738d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 739d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 740d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 741d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitReturnSequence(stmt->statement_pos()); 743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 744d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 745d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 746d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { 747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WithEnterStatement"); 748d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 749d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 750d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(stmt->expression(), kStack); 751d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->is_catch_block()) { 752d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kPushCatchContext, 1); 753d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 754d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kPushContext, 1); 755d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 756d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Both runtime calls return the new context in both the context and the 757d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // result registers. 758d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 759d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Update local stack frame context field. 760d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 761d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 762d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 763d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 764d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) { 765d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WithExitStatement"); 766d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 767d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Pop context. 769d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke LoadContextField(context_register(), Context::PREVIOUS_INDEX); 770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Update local stack frame context field. 771d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 772d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 777d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 778d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 779d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 780d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 781d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DoWhileStatement"); 782d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 783d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label body, stack_limit_hit, stack_check_success; 784d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 785d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 786d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 787d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 788d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 789d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 790d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 791d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 792d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ StackLimitCheck(&stack_limit_hit); 793d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_check_success); 794d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 795d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.continue_target()); 796d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt->condition_position()); 797d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 798d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 799d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_limit_hit); 800d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StackCheckStub stack_stub; 801d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallStub(&stack_stub); 802d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&stack_check_success); 803d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 804d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 805d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 806d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 807d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 808d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 809d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 810d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 811d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WhileStatement"); 812d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 813d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label body, stack_limit_hit, stack_check_success; 814d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 815d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 816d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 817d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 818d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop. 819d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(loop_statement.continue_target()); 820d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 821d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 822d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 823d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 824d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.continue_target()); 825d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 826d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ StackLimitCheck(&stack_limit_hit); 827d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_check_success); 828d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 829d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 830d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 831d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_limit_hit); 832d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StackCheckStub stack_stub; 833d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallStub(&stack_stub); 834d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&stack_check_success); 835d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 836d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 837d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 838d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 839d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 840d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 841d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 842d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ForStatement"); 843d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 844d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label test, body, stack_limit_hit, stack_check_success; 845d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 846d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 847d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 848d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 849d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 850d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 851d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 852d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop (even if empty). 853d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&test); 854d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 855d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 856d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 857d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 858d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.continue_target()); 859d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 860d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 861d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 862d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 863d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 864d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 865d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&test); 866d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 867d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 868d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ StackLimitCheck(&stack_limit_hit); 869d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_check_success); 870d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 871d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 872d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 873d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 874d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&body); 875d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 876d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 877d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&stack_limit_hit); 878d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StackCheckStub stack_stub; 879d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallStub(&stack_stub); 880d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&stack_check_success); 881d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 882d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 883d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 884d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 885d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 886d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 887d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 888d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 889d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 890d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 891d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 892d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 893d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryCatchStatement"); 894d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 895d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try block adds a handler to the exception handler chain 896d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // before entering, and removes it again when exiting normally. 897d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If an exception is thrown during execution of the try block, 898d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // control is passed to the handler, which also consumes the handler. 899d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // At this point, the exception is in a register, and store it in 900d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // the temporary local variable (prints as ".catch-var") before 901d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the catch block. The catch block has been rewritten 902d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // to introduce a new scope to bind the catch variable and to remove 903d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // that scope again afterwards. 904d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 905d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label try_handler_setup, catch_entry, done; 906d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 907d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code, exception in result register. 908d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 909d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Store exception in local .catch variable before executing catch block. 910d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 911d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The catch variable is *always* a variable proxy for a local variable. 912d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable(); 913d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_NOT_NULL(catch_var); 914d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Slot* variable_slot = catch_var->slot(); 915d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_NOT_NULL(variable_slot); 916d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_EQ(Slot::LOCAL, variable_slot->type()); 917d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(SlotOffset(variable_slot), result_register()); 918d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 919d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 920d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->catch_block()); 921d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 922d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 923d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try block code. Sets up the exception handler chain. 924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 926d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryCatch try_block(this, &catch_entry); 927d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 928d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 929d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 930d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 931d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 932d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 933d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 934d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 935d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 936d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryFinallyStatement"); 937d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 938d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try finally is compiled by setting up a try-handler on the stack while 939d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the try body, and removing it again afterwards. 940d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 941d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try-finally construct can enter the finally block in three ways: 942d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1. By exiting the try-block normally. This removes the try-handler and 943d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // calls the finally block code before continuing. 944d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 2. By exiting the try-block with a function-local control flow transfer 945d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (break/continue/return). The site of the, e.g., break removes the 946d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // try handler and calls the finally block code before continuing 947d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // its outward control transfer. 948d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 3. by exiting the try-block with a thrown exception. 949d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This can happen in nested function calls. It traverses the try-handler 950d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // chain and consumes the try-handler entry before jumping to the 951d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // handler code. The handler code then calls the finally-block before 952d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // rethrowing the exception. 953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 954d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The finally block must assume a return address on top of the stack 955d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (or in the link register on ARM chips) and a value (return value or 956d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception) in the result register (rax/eax/r0), both of which must 957d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // be preserved. The return address isn't GC-safe, so it should be 958d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // cooked before GC. 959d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label finally_entry; 960d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label try_handler_setup; 961d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 962d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup the try-handler chain. Use a call to 963d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Jump to try-handler setup and try-block code. Use call to put try-handler 964d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // address on stack. 965d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 966d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code. Return address of call is pushed on handler stack. 967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This code is only executed during stack-handler traversal when an 969d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception is thrown. The execption is in the result register, which 970d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // is retained by the finally block. 971d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Call the finally block and then rethrow the exception. 972d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 973d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ push(result_register()); 974d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kReThrow, 1); 975d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 976d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 977d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&finally_entry); 978d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 979d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Finally block implementation. 980d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Finally finally_block(this); 981d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnterFinallyBlock(); 982d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 983d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ExitFinallyBlock(); // Return to the calling code. 984d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 985d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 986d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 987d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 988d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup try handler (stack pointer registers). 989d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryFinally try_block(this, &finally_entry); 990d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); 991d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 992d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 993d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 994d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Execute the finally block on the way out. 995d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 996d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 997d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 998d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 999d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1000d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 1001d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DebuggerStatement"); 1002d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1003d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kDebugBreak, 0); 1004d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Ignore the return value. 1005d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 1006d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1007d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1008d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1009d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitFunctionBoilerplateLiteral( 1010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FunctionBoilerplateLiteral* expr) { 1011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 1012d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1013d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1014d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1015d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) { 1016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Conditional"); 1017d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label true_case, false_case, done; 1018d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForControl(expr->condition(), &true_case, &false_case); 1019d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&true_case); 1021d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->then_expression()); 1022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, jump to done. 1023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (context_ == Expression::kEffect || context_ == Expression::kValue) { 1024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1025d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1026d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1027d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&false_case); 1028d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(expr->else_expression()); 1029d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, merge it with true case here. 1030d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (context_ == Expression::kEffect || context_ == Expression::kValue) { 1031d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1032d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1033d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1034d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1035d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1036d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitSlot(Slot* expr) { 1037d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Slots do not appear directly in the AST. 1038d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 1039d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1040d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1041d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1042d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) { 1043d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Literal"); 1044d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Apply(context_, expr); 1045d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1046d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1047d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1048d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitAssignment(Assignment* expr) { 1049d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Assignment"); 1050d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(expr->op() != Token::INIT_CONST); 1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Left-hand side can only be a property, a global or a (parameter or local) 1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1053d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke LhsKind assign_type = VARIABLE; 1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Property* prop = expr->target()->AsProperty(); 1056d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (prop != NULL) { 1057d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke assign_type = 1058d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 1059d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1060d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1061d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Evaluate LHS expression. 1062d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (assign_type) { 1063d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case VARIABLE: 1064d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Nothing to do here. 1065d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1066d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case NAMED_PROPERTY: 1067d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(prop->obj(), kStack); 1068d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1069d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case KEYED_PROPERTY: 1070d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(prop->obj(), kStack); 1071d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(prop->key(), kStack); 1072d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1073d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1074d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1075d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If we have a compound assignment: Get value of LHS expression and 1076d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // store in on top of the stack. 1077d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (expr->is_compound()) { 1078d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Location saved_location = location_; 1079d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_ = kStack; 1080d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (assign_type) { 1081d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case VARIABLE: 1082d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitVariableLoad(expr->target()->AsVariableProxy()->var(), 1083d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression::kValue); 1084d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1085d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case NAMED_PROPERTY: 1086d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitNamedPropertyLoad(prop); 1087d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ push(result_register()); 1088d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1089d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case KEYED_PROPERTY: 1090d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitKeyedPropertyLoad(prop); 1091d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ push(result_register()); 1092d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1093d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1094d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_ = saved_location; 1095d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Evaluate RHS expression. 1098d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* rhs = expr->value(); 1099d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(rhs, kAccumulator); 1100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If we have a compound assignment: Apply operator. 1102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (expr->is_compound()) { 1103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Location saved_location = location_; 1104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_ = kAccumulator; 1105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitBinaryOp(expr->binary_op(), Expression::kValue); 1106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke location_ = saved_location; 1107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Record source position before possible IC call. 1110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetSourcePosition(expr->position()); 1111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Store the value. 1113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (assign_type) { 1114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case VARIABLE: 1115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke context_); 1117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case NAMED_PROPERTY: 1119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitNamedPropertyAssignment(expr); 1120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case KEYED_PROPERTY: 1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EmitKeyedPropertyAssignment(expr); 1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 1129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Call runtime routine to allocate the catch extension object and 1130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // assign the exception value to the catch variable. 1131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ CatchExtensionObject"); 1132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr->key(), kStack); 1133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr->value(), kStack); 1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Create catch extension object. 1135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 1136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Apply(context_, result_register()); 1137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) { 1141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Throw"); 1142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForValue(expr->exception(), kStack); 1143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kThrow, 1); 1144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Never returns here. 1145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryFinally::Exit(int stack_depth) { 1149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 1150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(finally_entry_); 1153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return 0; 1154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryCatch::Exit(int stack_depth) { 1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 1159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return 0; 1162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __ 1166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} } // namespace v8::internal 1169