full-codegen.cc revision 44f0eee88ff00398ff7f715fab053374d808c90d
1b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Copyright 2010 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" 32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "debug.h" 33d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "full-codegen.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "liveedit.h" 3580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#include "macro-assembler.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "prettyprinter.h" 376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "scopes.h" 38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "stub-cache.h" 39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 { 41d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal { 42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Statement* stmt) { 447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt); 457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Expression* expr) { 497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr); 507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDeclaration(Declaration* decl) { 547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBlock(Block* stmt) { 587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitExpressionStatement( 627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ExpressionStatement* stmt) { 637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if expression is breakable. 647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) { 697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) { 737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the condition is breakable the if statement is breakable. 747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->condition()); 757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitContinueStatement( 797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ContinueStatement* stmt) { 807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { 847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { 887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Return is breakable if the expression is. 897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWithEnterStatement( 947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch WithEnterStatement* stmt) { 957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWithExitStatement( 1007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch WithExitStatement* stmt) { 1017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { 1057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Switch statements breakable if the tag expression is. 1067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->tag()); 1077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { 1117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark do while as breakable to avoid adding a break slot in front of it. 1127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) { 1177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark while statements breakable if the condition expression is. 1187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 1197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForStatement(ForStatement* stmt) { 1237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for statements breakable if the condition expression is. 1247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (stmt->cond() != NULL) { 1257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 1267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 1277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) { 1317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for in statements breakable if the enumerable expression is. 1327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->enumerable()); 1337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryCatchStatement( 1377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryCatchStatement* stmt) { 1387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try catch as breakable to avoid adding a break slot in front of it. 1397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryFinallyStatement( 1447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryFinallyStatement* stmt) { 1457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try finally as breakable to avoid adding a break slot in front of it. 1467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDebuggerStatement( 1517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebuggerStatement* stmt) { 1527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The debugger statement is breakable. 1537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) { 1587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSharedFunctionInfoLiteral( 1627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SharedFunctionInfoLiteral* expr) { 1637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitConditional(Conditional* expr) { 1677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) { 1717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitLiteral(Literal* expr) { 1757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) { 1797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) { 1837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { 1877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCatchExtensionObject( 1917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CatchExtensionObject* expr) { 1927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitAssignment(Assignment* expr) { 1967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If assigning to a property (including a global property) the assignment is 1977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. 1987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 1997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Property* prop = expr->target()->AsProperty(); 2007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (prop != NULL || (var != NULL && var->is_global())) { 2017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return; 2037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 2047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Otherwise the assignment is breakable if the assigned value is. 2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->value()); 2077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThrow(Throw* expr) { 2117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Throw is breakable if the expression is. 2127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->exception()); 2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 21680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid BreakableStatementChecker::VisitIncrementOperation( 21780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen IncrementOperation* expr) { 21880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen UNREACHABLE(); 21980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 22080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 22180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitProperty(Property* expr) { 2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Property load is breakable. 2247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCall(Call* expr) { 2297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls both through IC and call stub are breakable. 2307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallNew(CallNew* expr) { 2357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls through new are breakable. 2367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) { 2417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) { 2457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCountOperation(CountOperation* expr) { 2507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) { 2557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->right()); 2577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 26080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid BreakableStatementChecker::VisitCompareToNull(CompareToNull* expr) { 26180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(expr->expression()); 26280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 26380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 26480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 2657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) { 2667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->right()); 2687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) { 2727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm()) 276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 277f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool FullCodeGenerator::MakeCode(CompilationInfo* info) { 27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = info->isolate(); 2793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Script> script = info->script(); 280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!script->IsUndefined() && !script->source()->IsUndefined()) { 281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = String::cast(script->source())->length(); 28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_full_codegen_source_size()->Increment(len); 283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_codegen) { 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("Full Compiler - "); 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CodeGenerator::MakeCodePrologue(info); 288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kInitialBufferSize = 4 * KB; 289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke MacroAssembler masm(NULL, kInitialBufferSize); 290b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 291b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch masm.positions_recorder()->StartGDBJITLineInfoRecording(); 292b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 293402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 2943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FullCodeGenerator cgen(&masm); 295756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick cgen.Generate(info); 296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (cgen.HasStackOverflow()) { 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!isolate->has_pending_exception()); 298f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return false; 299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned table_offset = cgen.EmitStackCheckTable(); 301f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); 303f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_optimizable(info->IsOptimizable()); 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cgen.PopulateDeoptimizationData(code); 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_allow_osr_at_loop_nesting_level(0); 3081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block code->set_stack_check_table_offset(table_offset); 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CodeGenerator::PrintCode(code, info); 310f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info->SetCode(code); // may be an empty handle. 311b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 3121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (FLAG_gdbjit && !code.is_null()) { 313b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJITLineInfo* lineinfo = 314b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch masm.positions_recorder()->DetachGDBJITLineInfo(); 315b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 316b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJIT(RegisterDetailedLineInfo(*code, lineinfo)); 317b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 318b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 319f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return !code.is_null(); 320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned FullCodeGenerator::EmitStackCheckTable() { 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The stack check table consists of a length (in number of entries) 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // field, and then a sequence of entries. Each entry is a pair of AST id 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and code-relative pc offset. 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm()->Align(kIntSize); 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm()->RecordComment("[ Stack check table"); 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned offset = masm()->pc_offset(); 330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned length = stack_checks_.length(); 331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(length); 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (unsigned i = 0; i < length; ++i) { 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(stack_checks_[i].id); 334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(stack_checks_[i].pc_and_state); 335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm()->RecordComment("]"); 337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return offset; 338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { 342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fill in the deoptimization information. 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); 344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info_->HasDeoptimizationSupport()) return; 345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = bailout_entries_.length(); 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<DeoptimizationOutputData> data = 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()-> 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block NewDeoptimizationOutputData(length, TENURED); 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; i++) { 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id)); 351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state)); 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_deoptimization_data(*data); 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::PrepareForBailout(AstNode* node, State state) { 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(node->id(), state); 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::RecordJSReturnSite(Call* call) { 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We record the offset of the function return so we can rebuild the frame 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // if the function was inlined, i.e., this is the return address in the 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // inlined function's frame. 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The state is ignored. We defensively set it to TOS_REG, which is the 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // real state of the unoptimized code at the return site. 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(call->ReturnId(), TOS_REG); 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // In debug builds, mark the return so we can verify that this function 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // was called. 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!call->return_is_recorded_); 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch call->return_is_recorded_ = true; 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::PrepareForBailoutForId(int id, State state) { 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There's no need to prepare this code for bailouts from already optimized 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code or code that can't be optimized. 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!FLAG_deopt || !info_->HasDeoptimizationSupport()) return; 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned pc_and_state = 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StateField::encode(state) | PcField::encode(masm_->pc_offset()); 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutEntry entry = { id, pc_and_state }; 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Assert that we don't have multiple bailout entries for the same node. 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < bailout_entries_.length(); i++) { 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (bailout_entries_.at(i).id == entry.id) { 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AstPrinter printer; 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("%s", printer.PrintProgram(info_->function())); 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // DEBUG 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bailout_entries_.Add(entry); 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::RecordStackCheck(int ast_id) { 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The pc offset does not need to be encoded and packed together with a 402b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // state. 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutEntry entry = { ast_id, masm_->pc_offset() }; 404b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch stack_checks_.Add(entry); 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::SlotOffset(Slot* slot) { 409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(slot != NULL); 410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Offset is negative because higher indexes are at lower addresses. 411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int offset = -slot->index() * kPointerSize; 412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Adjust by a (parameter or local) base offset. 413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (slot->type()) { 414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::PARAMETER: 4153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu offset += (scope()->num_parameters() + 1) * kPointerSize; 416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOCAL: 418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += JavaScriptFrameConstants::kLocal0Offset; 419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::CONTEXT: 421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOOKUP: 422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return offset; 425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 42880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenbool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { 42980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Inline smi case inside loops, but not division and modulo which 43080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // are too complicated and take up too much space. 4310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (op == Token::DIV ||op == Token::MOD) return false; 4320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (FLAG_always_inline_smi_code) return true; 4330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return loop_depth_ > 0; 43480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 43580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 43680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4370d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::Plug(Register reg) const { 4380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4410d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 4420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 4430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4460d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(Register reg) const { 4470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ push(reg); 4480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4510d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(Register reg) const { 4520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 4530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->DoTest(true_label_, false_label_, fall_through_); 4560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4590d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PlugTOS() const { 4600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Drop(1); 4610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4640d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 4650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ pop(result_register()); 4660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4690d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PlugTOS() const { 4700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4730d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PlugTOS() const { 4740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 4750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ pop(result_register()); 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->DoTest(true_label_, false_label_, fall_through_); 4780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4810d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PrepareTest( 4820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 4830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 4840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 4850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 4860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 4870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // In an effect context, the true and the false case branch to the 4880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // same label. 4890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *if_false = *fall_through = materialize_true; 4900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4930d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PrepareTest( 4940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 4950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 4960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 4970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 4980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 4990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 5000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5040d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PrepareTest( 5050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 5110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 5120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5150d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PrepareTest( 5160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = true_label_; 5220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = false_label_; 5230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *fall_through = fall_through_; 52480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 52580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 52680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 527d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDeclarations( 528d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Declaration*>* declarations) { 529d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int length = declarations->length(); 530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int globals = 0; 531d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < length; i++) { 532d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 533d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 5340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Slot* slot = var->AsSlot(); 535d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 536d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If it was not possible to allocate the variable at compile 537d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // time, we need to "declare" it at runtime to make sure it 538d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // actually exists in the local context. 539d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { 540d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitDeclaration(decl); 541d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 542d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Count global variables and functions for later processing 543d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke globals++; 544d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 545d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 546d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 547d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Compute array of global variable and function declarations. 548d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Do nothing in case of no declared global functions or variables. 549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (globals > 0) { 55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> array = 55144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->NewFixedArray(2 * globals, TENURED); 552d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int j = 0, i = 0; i < length; i++) { 553d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 554d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 5550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Slot* slot = var->AsSlot(); 556d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 557d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { 558d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *(var->name())); 559d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (decl->fun() == NULL) { 560d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var->mode() == Variable::CONST) { 561d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // In case this is const property use the hole. 562d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_the_hole(j++); 563d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 564d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_undefined(j++); 565d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 566d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function = 568f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Compiler::BuildFunctionInfo(decl->fun(), script()); 569d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for stack-overflow exception. 570f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (function.is_null()) { 571f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SetStackOverflow(); 572f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return; 573f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 574d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *function); 575d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 576d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 577d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 578d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Invoke the platform-dependent code generator to do the actual 579d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // declaration the global variables and functions. 580d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeclareGlobals(array); 581d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 582d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 583d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 584d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 585d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 586d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 587d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, fun->start_position()); 588d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 589d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 590d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 591d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 592d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 593d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 594bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); 595d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 596d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 597d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 598d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 599d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) { 600d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 6017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate()->debugger()->IsDebuggerActive()) { 6037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 6047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 6057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if the statement will be breakable without adding a debug break 6067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // slot. 6077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch BreakableStatementChecker checker; 6087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch checker.Check(stmt); 6097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Record the statement position right here if the statement is not 6107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. For breakable statements the actual recording of the 6117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // position will be postponed to the breakable code (typically an IC). 6127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch bool position_recorded = CodeGenerator::RecordPositions( 6137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch masm_, stmt->statement_pos(), !checker.is_breakable()); 6147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the position recording did record a new position generate a debug 6157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // break slot to make the statement breakable. 6167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (position_recorded) { 6177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Debug::GenerateSlot(masm_); 6187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 621d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 6227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 6237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) { 6287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (FLAG_debug_info) { 6297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 63044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate()->debugger()->IsDebuggerActive()) { 6317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodeGenerator::RecordPositions(masm_, pos); 6327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 6337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if the expression will be breakable without adding a debug break 6347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // slot. 6357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch BreakableStatementChecker checker; 6367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch checker.Check(expr); 6377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Record a statement position right here if the expression is not 6387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. For breakable expressions the actual recording of the 6397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // position will be postponed to the breakable code (typically an IC). 6407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // NOTE this will record a statement position for something which might 6417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // not be a statement. As stepping in the debugger will only stop at 6427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // statement positions this is used for e.g. the condition expression of 6437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // a do while loop. 6447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch bool position_recorded = CodeGenerator::RecordPositions( 6457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch masm_, pos, !checker.is_breakable()); 6467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the position recording did record a new position generate a debug 6477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // break slot to make the statement breakable. 6487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (position_recorded) { 6497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Debug::GenerateSlot(masm_); 6507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 6537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodeGenerator::RecordPositions(masm_, pos); 6547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 655d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 656d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 657d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 658d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 659d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(int pos) { 660d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info) { 661d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CodeGenerator::RecordPositions(masm_, pos); 662d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 663d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 664d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 665d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::SetSourcePosition(int pos) { 667d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (FLAG_debug_info && pos != RelocInfo::kNoPosition) { 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm_->positions_recorder()->RecordPosition(pos); 669d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 670d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 671d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 672d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// Lookup table for code generators for special runtime calls which are 6740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// generated inline. 6750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 6760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen &FullCodeGenerator::Emit##Name, 677791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 6780d5e116f6aee03185f237311a943491bb079a768Kristian Monsenconst FullCodeGenerator::InlineFunctionGenerator 6790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::kInlineFunctionGenerators[] = { 6800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 6810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 6820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 6830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#undef INLINE_FUNCTION_GENERATOR_ADDRESS 6840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6860d5e116f6aee03185f237311a943491bb079a768Kristian MonsenFullCodeGenerator::InlineFunctionGenerator 6870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { 688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int lookup_index = 689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction); 690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(lookup_index >= 0); 691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(static_cast<size_t>(lookup_index) < 692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ARRAY_SIZE(kInlineFunctionGenerators)); 693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return kInlineFunctionGenerators[lookup_index]; 6940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 6950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6970d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) { 6980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ZoneList<Expression*>* args = node->arguments(); 6990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Handle<String> name = node->name(); 70044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = node->function(); 7010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(function != NULL); 7020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(function->intrinsic_type == Runtime::INLINE); 7030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen InlineFunctionGenerator generator = 7040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FindInlineFunctionGenerator(function->function_id); 7050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ((*this).*(generator))(args); 70680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 70780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 70880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 70980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 71080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Comment cmnt(masm_, "[ BinaryOperation"); 71180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Token::Value op = expr->op(); 71280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Expression* left = expr->left(); 71380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Expression* right = expr->right(); 71480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 71580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen OverwriteMode mode = NO_OVERWRITE; 71680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (left->ResultOverwriteAllowed()) { 71780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen mode = OVERWRITE_LEFT; 71880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else if (right->ResultOverwriteAllowed()) { 71980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen mode = OVERWRITE_RIGHT; 72080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 72180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen switch (op) { 72380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::COMMA: 72480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForEffect(left); 725b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (context()->IsTest()) ForwardBailoutToChild(expr); 726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch context()->HandleExpression(right); 72780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen break; 72880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 72980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::OR: 73080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::AND: 73180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen EmitLogicalOperation(expr); 73280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen break; 73380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 73480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::ADD: 73580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::SUB: 73680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::DIV: 73780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::MOD: 73880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::MUL: 73980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::BIT_OR: 74080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::BIT_AND: 74180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::BIT_XOR: 74280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::SHL: 74380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::SHR: 74480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::SAR: { 745e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Load both operands. 746e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch VisitForStackValue(left); 747e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch VisitForAccumulatorValue(right); 74880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 74980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen SetSourcePosition(expr->position()); 75080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (ShouldInlineSmiCase(op)) { 751e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch EmitInlineSmiBinaryOp(expr, op, mode, left, right); 75280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else { 7530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen EmitBinaryOp(op, mode); 75480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 75580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen break; 75680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 75780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 75880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen default: 75980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen UNREACHABLE(); 76080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 7617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 7627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 764d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 765d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label eval_right, done; 766d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 7670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen context()->EmitLogicalLeft(expr, &eval_right, &done); 768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->RightId(), NO_REGISTERS); 770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&eval_right); 771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (context()->IsTest()) ForwardBailoutToChild(expr); 772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch context()->HandleExpression(expr->right()); 773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 777d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 7780d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr, 7790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* eval_right, 7800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* done) const { 7810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (expr->op() == Token::OR) { 7820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->VisitForControl(expr->left(), done, eval_right, eval_right); 7830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 7840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(expr->op() == Token::AND); 7850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->VisitForControl(expr->left(), eval_right, done, eval_right); 7860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 7870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 7880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7900d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::EmitLogicalLeft( 7910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen BinaryOperation* expr, 7920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* eval_right, 7930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* done) const { 794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HandleExpression(expr->left()); 7950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // We want the value in the accumulator for the test, and on the stack in case 7960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // we need it. 79780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ push(result_register()); 7980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label discard, restore; 7990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (expr->op() == Token::OR) { 800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 8010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->DoTest(&restore, &discard, &restore); 8020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 8030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(expr->op() == Token::AND); 804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 8050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->DoTest(&discard, &restore, &restore); 8060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 8070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ bind(&restore); 8080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ pop(result_register()); 8090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ jmp(done); 8100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ bind(&discard); 8110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Drop(1); 8120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 8130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 81480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8150d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::EmitLogicalLeft( 8160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen BinaryOperation* expr, 8170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* eval_right, 8180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* done) const { 8190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->VisitForAccumulatorValue(expr->left()); 8200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // We want the value in the accumulator for the test, and on the stack in case 8210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // we need it. 8220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ push(result_register()); 82380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Label discard; 8240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (expr->op() == Token::OR) { 825b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 8260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->DoTest(done, &discard, &discard); 8270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 8280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(expr->op() == Token::AND); 829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 8300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->DoTest(&discard, done, &discard); 83180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 83280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&discard); 83380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ Drop(1); 83480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 83580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 83680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8370d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::EmitLogicalLeft(BinaryOperation* expr, 8380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* eval_right, 8390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* done) const { 8400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (expr->op() == Token::OR) { 8410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->VisitForControl(expr->left(), 8420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen true_label_, eval_right, eval_right); 8430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 8440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(expr->op() == Token::AND); 8450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen codegen()->VisitForControl(expr->left(), 8460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen eval_right, false_label_, eval_right); 8470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 8480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 8490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::ForwardBailoutToChild(Expression* expr) { 852b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info_->HasDeoptimizationSupport()) return; 853b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(context()->IsTest()); 854b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(expr == forward_bailout_stack_->expr()); 855b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch forward_bailout_pending_ = forward_bailout_stack_; 856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 857b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 858b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 859b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::EffectContext::HandleExpression( 860b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Expression* expr) const { 861b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->HandleInNonTestContext(expr, NO_REGISTERS); 862b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 863b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 864b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 865b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::AccumulatorValueContext::HandleExpression( 866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Expression* expr) const { 867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->HandleInNonTestContext(expr, TOS_REG); 868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 869b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 870b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 871b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::StackValueContext::HandleExpression( 872b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Expression* expr) const { 873b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->HandleInNonTestContext(expr, NO_REGISTERS); 874b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 875b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 876b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 877b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::TestContext::HandleExpression(Expression* expr) const { 878b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->VisitInTestContext(expr); 879b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 880b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 881b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::HandleInNonTestContext(Expression* expr, State state) { 883b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(forward_bailout_pending_ == NULL); 884b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AstVisitor::Visit(expr); 885b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailout(expr, state); 886b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Forwarding bailouts to children is a one shot operation. It 887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // should have been processed at this point. 888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(forward_bailout_pending_ == NULL); 889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::VisitInTestContext(Expression* expr) { 893b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ForwardBailoutStack stack(expr, forward_bailout_pending_); 894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ForwardBailoutStack* saved = forward_bailout_stack_; 895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch forward_bailout_pending_ = NULL; 896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch forward_bailout_stack_ = &stack; 897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AstVisitor::Visit(expr); 898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch forward_bailout_stack_ = saved; 899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 902d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) { 903d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Block"); 904d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Breakable nested_statement(this, stmt); 905d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 9071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 908d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 909d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(nested_statement.break_target()); 910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 911d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 912d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 913d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 914d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 915d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ExpressionStatement"); 916d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 917d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForEffect(stmt->expression()); 918d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 919d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 920d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 921d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 922d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ EmptyStatement"); 923d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 926d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 927d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 928d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ IfStatement"); 929d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 930d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label then_part, else_part, done; 931d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 93280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (stmt->HasElseStatement()) { 93380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); 934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 93580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 93680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 93780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ jmp(&done); 938d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 939b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 94080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&else_part); 94180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->else_statement()); 94280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else { 94380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &done, &then_part); 944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 94580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 94680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 948b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 94980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 950d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->id(), NO_REGISTERS); 952d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 954d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 955d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 956d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ContinueStatement"); 957d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 958d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 959d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 960db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When continuing, we clobber the unpredictable value in the accumulator 961db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 962db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 963db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 964db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 965d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsContinueTarget(stmt->target())) { 966d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 969d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 970d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 971d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration* loop = current->AsIteration(); 972d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(loop->continue_target()); 973d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 974d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 975d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 976d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 977d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ BreakStatement"); 978d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 979d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 980d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 981db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When breaking, we clobber the unpredictable value in the accumulator 982db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 983db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 984db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 985db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 986d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsBreakTarget(stmt->target())) { 987d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 988d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 989d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 990d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 991d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 992d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Breakable* target = current->AsBreakable(); 993d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(target->break_target()); 994d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 995d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 996d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 997d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 998d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ReturnStatement"); 999d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1000d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* expr = stmt->expression(); 10010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForAccumulatorValue(expr); 1002d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1003d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Exit all nested statements. 1004d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1005d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 1006d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (current != NULL) { 1007d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke stack_depth = current->Exit(stack_depth); 1008d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke current = current->outer(); 1009d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 10127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitReturnSequence(); 1013d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1014d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1015d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { 1017d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WithEnterStatement"); 1018d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1019d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 10200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(stmt->expression()); 1021d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->is_catch_block()) { 1022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kPushCatchContext, 1); 1023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 1024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kPushContext, 1); 1025d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1026d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Both runtime calls return the new context in both the context and the 1027d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // result registers. 1028d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1029d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Update local stack frame context field. 1030d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1031d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1032d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1033d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1034d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) { 1035d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WithExitStatement"); 1036d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1037d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1038d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Pop context. 1039d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1040d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Update local stack frame context field. 1041d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1042d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1043d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1044d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1045d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1046d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DoWhileStatement"); 1047d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label body, stack_check; 1049d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1050d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1053d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 105680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Record the position of the do while condition and make sure it is 105780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // possible to break on the condition. 1058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(loop_statement.continue_target()); 1059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 10607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(stmt->cond(), stmt->condition_position()); 106180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 1062b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &stack_check, 106380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen loop_statement.break_target(), 1064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &stack_check); 10657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check stack before looping. 1067b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&stack_check); 1069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EmitStackCheck(stmt); 1070b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&body); 1071d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(loop_statement.break_target()); 1074d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1075d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1076d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1077d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1078d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1079d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WhileStatement"); 1080b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label test, body; 1081d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1082d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1083d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1084d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1085d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop. 1086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&test); 1087d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1089d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1090d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 109180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 109280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Emit the statement position here as this is where the while 109380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // statement code starts. 1094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(loop_statement.continue_target()); 10957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1096f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EmitStackCheck(stmt); 1099d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&test); 110180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 110280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen &body, 110380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen loop_statement.break_target(), 110480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen loop_statement.break_target()); 1105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 1108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ForStatement"); 1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label test, body; 1115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 1118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 1119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop (even if empty). 1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&test); 1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.continue_target()); 1131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 1133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 113680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Emit the statement position here as this is where the for 113780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // statement code starts. 11387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EmitStackCheck(stmt); 1142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&test); 1144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 114580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 114680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen &body, 114780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen loop_statement.break_target(), 114880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen loop_statement.break_target()); 1149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 1150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&body); 1151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(loop_statement.break_target()); 1155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryCatchStatement"); 1161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try block adds a handler to the exception handler chain 1163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // before entering, and removes it again when exiting normally. 1164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If an exception is thrown during execution of the try block, 1165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // control is passed to the handler, which also consumes the handler. 1166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // At this point, the exception is in a register, and store it in 1167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // the temporary local variable (prints as ".catch-var") before 1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the catch block. The catch block has been rewritten 1169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // to introduce a new scope to bind the catch variable and to remove 1170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // that scope again afterwards. 1171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label try_handler_setup, catch_entry, done; 1173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 1174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code, exception in result register. 1175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Store exception in local .catch variable before executing catch block. 1177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The catch variable is *always* a variable proxy for a local variable. 1179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable(); 1180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_NOT_NULL(catch_var); 11810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Slot* variable_slot = catch_var->AsSlot(); 1182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_NOT_NULL(variable_slot); 1183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT_EQ(Slot::LOCAL, variable_slot->type()); 1184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(SlotOffset(variable_slot), result_register()); 1185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->catch_block()); 1188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try block code. Sets up the exception handler chain. 1191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 1192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryCatch try_block(this, &catch_entry); 1194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 1195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryFinallyStatement"); 1204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try finally is compiled by setting up a try-handler on the stack while 1206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the try body, and removing it again afterwards. 1207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try-finally construct can enter the finally block in three ways: 1209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1. By exiting the try-block normally. This removes the try-handler and 1210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // calls the finally block code before continuing. 1211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 2. By exiting the try-block with a function-local control flow transfer 1212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (break/continue/return). The site of the, e.g., break removes the 1213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // try handler and calls the finally block code before continuing 1214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // its outward control transfer. 1215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 3. by exiting the try-block with a thrown exception. 1216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This can happen in nested function calls. It traverses the try-handler 1217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // chain and consumes the try-handler entry before jumping to the 1218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // handler code. The handler code then calls the finally-block before 1219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // rethrowing the exception. 1220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The finally block must assume a return address on top of the stack 1222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (or in the link register on ARM chips) and a value (return value or 1223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception) in the result register (rax/eax/r0), both of which must 1224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // be preserved. The return address isn't GC-safe, so it should be 1225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // cooked before GC. 1226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label finally_entry; 1227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label try_handler_setup; 1228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup the try-handler chain. Use a call to 1230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Jump to try-handler setup and try-block code. Use call to put try-handler 1231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // address on stack. 1232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 1233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code. Return address of call is pushed on handler stack. 1234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This code is only executed during stack-handler traversal when an 1236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception is thrown. The execption is in the result register, which 1237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // is retained by the finally block. 1238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Call the finally block and then rethrow the exception. 1239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ push(result_register()); 1241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kReThrow, 1); 1242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&finally_entry); 1245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Finally block implementation. 1247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Finally finally_block(this); 1248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnterFinallyBlock(); 1249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 1250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ExitFinallyBlock(); // Return to the calling code. 1251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 1254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup try handler (stack pointer registers). 1256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryFinally try_block(this, &finally_entry); 1257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); 1258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1261db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // Execute the finally block on the way out. Clobber the unpredictable 1262db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // value in the accumulator with one that's safe for GC. The finally 1263db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // block will unconditionally preserve the accumulator on the stack. 1264db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 1271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DebuggerStatement"); 1272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 12734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 1274402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu __ DebugBreak(); 1275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Ignore the return value. 1276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 1277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) { 1281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Conditional"); 1282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label true_case, false_case, done; 128380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&true_case); 12877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->then_expression(), 12887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->then_expression_position()); 1289f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (context()->IsTest()) { 1290f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const TestContext* for_test = TestContext::cast(context()); 1291f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch VisitForControl(expr->then_expression(), 1292f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->true_label(), 1293f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->false_label(), 1294f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch NULL); 1295f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 1296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch context()->HandleExpression(expr->then_expression()); 1297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&false_case); 1302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (context()->IsTest()) ForwardBailoutToChild(expr); 13037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->else_expression(), 13047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->else_expression_position()); 1305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch context()->HandleExpression(expr->else_expression()); 1306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, merge it with true case here. 13070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!context()->IsTest()) { 1308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) { 1314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Literal"); 13150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen context()->Plug(expr->handle()); 1316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1319f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1320f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ FunctionLiteral"); 1321f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1322f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Build the function boilerplate and instantiate it. 1323f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<SharedFunctionInfo> function_info = 1324f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Compiler::BuildFunctionInfo(expr, script()); 1325f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (function_info.is_null()) { 1326f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SetStackOverflow(); 1327f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return; 1328f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 13298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang EmitNewClosure(function_info, expr->pretenure()); 1330f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1331f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1332f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1333f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitSharedFunctionInfoLiteral( 1334f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke SharedFunctionInfoLiteral* expr) { 1335f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); 13368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang EmitNewClosure(expr->shared_function_info(), false); 1337f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1338f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1339f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1340d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 1341d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Call runtime routine to allocate the catch extension object and 1342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // assign the exception value to the catch variable. 1343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ CatchExtensionObject"); 13440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(expr->key()); 13450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(expr->value()); 1346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Create catch extension object. 1347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 13480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen context()->Plug(result_register()); 1349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) { 1353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Throw"); 13540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(expr->exception()); 1355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kThrow, 1); 1356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Never returns here. 1357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 136080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid FullCodeGenerator::VisitIncrementOperation(IncrementOperation* expr) { 136180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen UNREACHABLE(); 136280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 136380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 136480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryFinally::Exit(int stack_depth) { 1366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 1367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(finally_entry_); 1370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return 0; 1371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryCatch::Exit(int stack_depth) { 1375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 1376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 1378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return 0; 1379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1380d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 138180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1382d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __ 1383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} } // namespace v8::internal 1386