full-codegen.cc revision 69a99ed0b2b2ef69d393c371b03db3a98aaf880e
18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 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 308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#include "codegen.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" 3869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "scopeinfo.h" 39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "stub-cache.h" 40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 41d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 { 42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal { 43d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Statement* stmt) { 457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt); 467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Expression* expr) { 507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr); 517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDeclaration(Declaration* decl) { 557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBlock(Block* stmt) { 597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitExpressionStatement( 637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ExpressionStatement* stmt) { 647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if expression is breakable. 657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) { 707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) { 747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the condition is breakable the if statement is breakable. 757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->condition()); 767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitContinueStatement( 807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ContinueStatement* stmt) { 817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { 857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { 897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Return is breakable if the expression is. 907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { 957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid BreakableStatementChecker::VisitExitContextStatement( 1003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ExitContextStatement* 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::VisitAssignment(Assignment* expr) { 1917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If assigning to a property (including a global property) the assignment is 1927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. 1937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Property* prop = expr->target()->AsProperty(); 1957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (prop != NULL || (var != NULL && var->is_global())) { 1967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return; 1987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 1997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Otherwise the assignment is breakable if the assigned value is. 2017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->value()); 2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThrow(Throw* expr) { 2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Throw is breakable if the expression is. 2077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->exception()); 2087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitProperty(Property* expr) { 2127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Property load is breakable. 2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCall(Call* expr) { 2187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls both through IC and call stub are breakable. 2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallNew(CallNew* expr) { 2247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls through new are breakable. 2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) { 2307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) { 2347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCountOperation(CountOperation* expr) { 2397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) { 2447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2457d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch if (expr->op() != Token::AND && 2467d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch expr->op() != Token::OR) { 2477d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch Visit(expr->right()); 2487d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch } 2497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 25280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid BreakableStatementChecker::VisitCompareToNull(CompareToNull* expr) { 25380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(expr->expression()); 25480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 25580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 25680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 2577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) { 2587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->right()); 2607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) { 2647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm()) 268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 269f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool FullCodeGenerator::MakeCode(CompilationInfo* info) { 27044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = info->isolate(); 2713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Script> script = info->script(); 272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!script->IsUndefined() && !script->source()->IsUndefined()) { 273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = String::cast(script->source())->length(); 27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_full_codegen_source_size()->Increment(len); 275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_codegen) { 277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("Full Compiler - "); 278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CodeGenerator::MakeCodePrologue(info); 280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kInitialBufferSize = 4 * KB; 2818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize); 282b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 283b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch masm.positions_recorder()->StartGDBJITLineInfoRecording(); 284b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 285402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 2863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu FullCodeGenerator cgen(&masm); 287756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick cgen.Generate(info); 288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (cgen.HasStackOverflow()) { 28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!isolate->has_pending_exception()); 290f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return false; 291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned table_offset = cgen.EmitStackCheckTable(); 293f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); 295f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_optimizable(info->IsOptimizable()); 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cgen.PopulateDeoptimizationData(code); 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_allow_osr_at_loop_nesting_level(0); 3001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block code->set_stack_check_table_offset(table_offset); 301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CodeGenerator::PrintCode(code, info); 302f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info->SetCode(code); // may be an empty handle. 303b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 3041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (FLAG_gdbjit && !code.is_null()) { 305b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJITLineInfo* lineinfo = 306b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch masm.positions_recorder()->DetachGDBJITLineInfo(); 307b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 308b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJIT(RegisterDetailedLineInfo(*code, lineinfo)); 309b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 310b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 311f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return !code.is_null(); 312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned FullCodeGenerator::EmitStackCheckTable() { 316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The stack check table consists of a length (in number of entries) 317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // field, and then a sequence of entries. Each entry is a pair of AST id 318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and code-relative pc offset. 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm()->Align(kIntSize); 320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned offset = masm()->pc_offset(); 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned length = stack_checks_.length(); 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(length); 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (unsigned i = 0; i < length; ++i) { 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(stack_checks_[i].id); 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(stack_checks_[i].pc_and_state); 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return offset; 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fill in the deoptimization information. 333b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); 334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info_->HasDeoptimizationSupport()) return; 335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = bailout_entries_.length(); 336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<DeoptimizationOutputData> data = 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()-> 33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block NewDeoptimizationOutputData(length, TENURED); 339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; i++) { 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id)); 341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state)); 342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_deoptimization_data(*data); 344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::PrepareForBailout(Expression* node, State state) { 348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(node->id(), state); 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::RecordJSReturnSite(Call* call) { 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We record the offset of the function return so we can rebuild the frame 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // if the function was inlined, i.e., this is the return address in the 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // inlined function's frame. 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The state is ignored. We defensively set it to TOS_REG, which is the 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // real state of the unoptimized code at the return site. 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(call->ReturnId(), TOS_REG); 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // In debug builds, mark the return so we can verify that this function 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // was called. 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!call->return_is_recorded_); 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch call->return_is_recorded_ = true; 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::PrepareForBailoutForId(int id, State state) { 370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There's no need to prepare this code for bailouts from already optimized 371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code or code that can't be optimized. 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!FLAG_deopt || !info_->HasDeoptimizationSupport()) return; 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned pc_and_state = 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StateField::encode(state) | PcField::encode(masm_->pc_offset()); 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutEntry entry = { id, pc_and_state }; 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Assert that we don't have multiple bailout entries for the same node. 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < bailout_entries_.length(); i++) { 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (bailout_entries_.at(i).id == entry.id) { 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AstPrinter printer; 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("%s", printer.PrintProgram(info_->function())); 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNREACHABLE(); 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // DEBUG 386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bailout_entries_.Add(entry); 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::RecordStackCheck(int ast_id) { 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The pc offset does not need to be encoded and packed together with a 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // state. 393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutEntry entry = { ast_id, masm_->pc_offset() }; 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch stack_checks_.Add(entry); 395b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 396b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 398d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::SlotOffset(Slot* slot) { 399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ASSERT(slot != NULL); 400d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Offset is negative because higher indexes are at lower addresses. 401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int offset = -slot->index() * kPointerSize; 402d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Adjust by a (parameter or local) base offset. 403d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke switch (slot->type()) { 404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::PARAMETER: 4053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch offset += (info_->scope()->num_parameters() + 1) * kPointerSize; 406d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOCAL: 408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke offset += JavaScriptFrameConstants::kLocal0Offset; 409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke break; 410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::CONTEXT: 411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke case Slot::LOOKUP: 412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke UNREACHABLE(); 413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return offset; 415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 41880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenbool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { 41980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Inline smi case inside loops, but not division and modulo which 42080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // are too complicated and take up too much space. 4210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (op == Token::DIV ||op == Token::MOD) return false; 4220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (FLAG_always_inline_smi_code) return true; 4230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return loop_depth_ > 0; 42480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 42580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 42680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4270d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::Plug(Register reg) const { 4280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4310d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 4320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 4330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4360d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(Register reg) const { 4370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ push(reg); 43869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch codegen()->increment_stack_height(); 4390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4420d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(Register reg) const { 4430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 4440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch codegen()->DoTest(this); 4470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4500d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PlugTOS() const { 4510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Drop(1); 45269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch codegen()->decrement_stack_height(); 4530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4560d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 4570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ pop(result_register()); 45869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch codegen()->decrement_stack_height(); 4590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4620d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PlugTOS() const { 4630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4660d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PlugTOS() const { 4670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 4680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ pop(result_register()); 46969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch codegen()->decrement_stack_height(); 470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch codegen()->DoTest(this); 4720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4750d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PrepareTest( 4760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 4770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 4780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 4790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 4800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 4810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // In an effect context, the true and the false case branch to the 4820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // same label. 4830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *if_false = *fall_through = materialize_true; 4840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4870d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PrepareTest( 4880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 4890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 4900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 4910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 4920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 4930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 4940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 4950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4980d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PrepareTest( 4990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 5050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 5060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5090d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PrepareTest( 5100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = true_label_; 5160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = false_label_; 5170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *fall_through = fall_through_; 51880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 51980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 52080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::DoTest(const TestContext* context) { 5223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(context->condition(), 5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->true_label(), 5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->false_label(), 5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->fall_through()); 5263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 529d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDeclarations( 530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Declaration*>* declarations) { 531d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int length = declarations->length(); 532d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int globals = 0; 533d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int i = 0; i < length; i++) { 534d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 535d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 5360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Slot* slot = var->AsSlot(); 537d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 538d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If it was not possible to allocate the variable at compile 539d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // time, we need to "declare" it at runtime to make sure it 540d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // actually exists in the local context. 541d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { 542d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitDeclaration(decl); 543d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 544d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Count global variables and functions for later processing 545d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke globals++; 546d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 547d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 548d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Compute array of global variable and function declarations. 550d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Do nothing in case of no declared global functions or variables. 551d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (globals > 0) { 55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> array = 55344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->factory()->NewFixedArray(2 * globals, TENURED); 554d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int j = 0, i = 0; i < length; i++) { 555d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 556d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 5570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Slot* slot = var->AsSlot(); 558d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 559d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { 560d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *(var->name())); 561d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (decl->fun() == NULL) { 562d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (var->mode() == Variable::CONST) { 563d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // In case this is const property use the hole. 564d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_the_hole(j++); 565d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 566d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_undefined(j++); 567d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 568d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function = 570f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Compiler::BuildFunctionInfo(decl->fun(), script()); 571d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for stack-overflow exception. 572f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (function.is_null()) { 573f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SetStackOverflow(); 574f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return; 575f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 576d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *function); 577d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 578d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 579d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 580d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Invoke the platform-dependent code generator to do the actual 581d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // declaration the global variables and functions. 582d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeclareGlobals(array); 583d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 584d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 585d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 586d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 587d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 5883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, fun->start_position()); 589d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 590d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 591d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 592d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); 594d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 595d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 596d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 597d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) { 5987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 5993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!isolate()->debugger()->IsDebuggerActive()) { 6003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 6013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 6023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the statement will be breakable without adding a debug break 6033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot. 6043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakableStatementChecker checker; 6053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch checker.Check(stmt); 6063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Record the statement position right here if the statement is not 6073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breakable. For breakable statements the actual recording of the 6083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // position will be postponed to the breakable code (typically an IC). 6093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool position_recorded = CodeGenerator::RecordPositions( 6103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch masm_, stmt->statement_pos(), !checker.is_breakable()); 6113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the position recording did record a new position generate a debug 6123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // break slot to make the statement breakable. 6133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (position_recorded) { 6143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Debug::GenerateSlot(masm_); 6157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 6183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 6197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 6207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 6217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 6237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) { 6247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 6253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!isolate()->debugger()->IsDebuggerActive()) { 6263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, pos); 6273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 6283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the expression will be breakable without adding a debug break 6293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot. 6303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakableStatementChecker checker; 6313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch checker.Check(expr); 6323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Record a statement position right here if the expression is not 6333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breakable. For breakable expressions the actual recording of the 6343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // position will be postponed to the breakable code (typically an IC). 6353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // NOTE this will record a statement position for something which might 6363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // not be a statement. As stepping in the debugger will only stop at 6373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // statement positions this is used for e.g. the condition expression of 6383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // a do while loop. 6393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool position_recorded = CodeGenerator::RecordPositions( 6403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch masm_, pos, !checker.is_breakable()); 6413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the position recording did record a new position generate a debug 6423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // break slot to make the statement breakable. 6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (position_recorded) { 6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Debug::GenerateSlot(masm_); 6457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 6483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, pos); 6497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 650d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 651d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 652d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 653d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(int pos) { 6543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, pos); 655d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 656d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 657d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::SetSourcePosition(int pos) { 6593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (pos != RelocInfo::kNoPosition) { 660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm_->positions_recorder()->RecordPosition(pos); 661d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 662d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 663d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 664d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// Lookup table for code generators for special runtime calls which are 6660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// generated inline. 6670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 6680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen &FullCodeGenerator::Emit##Name, 669791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 6700d5e116f6aee03185f237311a943491bb079a768Kristian Monsenconst FullCodeGenerator::InlineFunctionGenerator 6710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::kInlineFunctionGenerators[] = { 6720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 6730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 6740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 6750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#undef INLINE_FUNCTION_GENERATOR_ADDRESS 6760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6780d5e116f6aee03185f237311a943491bb079a768Kristian MonsenFullCodeGenerator::InlineFunctionGenerator 6790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { 680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int lookup_index = 681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction); 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(lookup_index >= 0); 683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(static_cast<size_t>(lookup_index) < 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ARRAY_SIZE(kInlineFunctionGenerators)); 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return kInlineFunctionGenerators[lookup_index]; 6860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 6870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 6890d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* node) { 6900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ZoneList<Expression*>* args = node->arguments(); 69144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const Runtime::Function* function = node->function(); 6920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(function != NULL); 6930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(function->intrinsic_type == Runtime::INLINE); 6940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen InlineFunctionGenerator generator = 6950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FindInlineFunctionGenerator(function->function_id); 6960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ((*this).*(generator))(args); 69780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 69880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 69980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 70080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 7013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (expr->op()) { 70280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::COMMA: 7033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitComma(expr); 70480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::OR: 70580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::AND: 7063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitLogicalExpression(expr); 70780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen default: 7083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitArithmeticExpression(expr); 70980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 7107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 7117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitComma(BinaryOperation* expr) { 7143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, "[ Comma"); 7153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForEffect(expr->left()); 716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (context()->IsTest()) ForwardBailoutToChild(expr); 7173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitInCurrentContext(expr->right()); 718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 7213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { 7223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_logical_and = expr->op() == Token::AND; 7233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR"); 7243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* left = expr->left(); 7253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* right = expr->right(); 7263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int right_id = expr->RightId(); 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label done; 7280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (context()->IsTest()) { 7303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label eval_right; 7313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const TestContext* test = TestContext::cast(context()); 7323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 7333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &eval_right, test->false_label(), &eval_right); 7343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 7353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, test->true_label(), &eval_right, &eval_right); 7363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 7383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&eval_right); 7393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ForwardBailoutToChild(expr); 7403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (context()->IsAccumulatorValue()) { 7423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(left); 7433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We want the value in the accumulator for the test, and on the stack in 7443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // case we need it. 7453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ push(result_register()); 7463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label discard, restore; 7473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 7483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 7493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &discard, &restore, &restore); 7503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 7513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &restore, &discard, &restore); 7523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&restore); 7543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ pop(result_register()); 7553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ jmp(&done); 7563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&discard); 7573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Drop(1); 7583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 7593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (context()->IsStackValue()) { 7613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(left); 7623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We want the value in the accumulator for the test, and on the stack in 7633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // case we need it. 7643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ push(result_register()); 7653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label discard; 7663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); 7673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 7683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &discard, &done, &discard); 7693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 7703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &done, &discard, &discard); 7713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&discard); 7733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Drop(1); 7743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 7750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 7773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(context()->IsEffect()); 7783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label eval_right; 7793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 7803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &eval_right, &done, &eval_right); 7813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 7823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &done, &eval_right, &eval_right); 7833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 7853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&eval_right); 7860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 7873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitInCurrentContext(right); 7893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&done); 7900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 7910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 79280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 7933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 7943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Token::Value op = expr->op(); 7953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, "[ ArithmeticExpression"); 7963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* left = expr->left(); 7973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* right = expr->right(); 7983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OverwriteMode mode = 7993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch left->ResultOverwriteAllowed() 8003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ? OVERWRITE_LEFT 8013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE); 80280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForStackValue(left); 8043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(right); 80580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SetSourcePosition(expr->position()); 8073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (ShouldInlineSmiCase(op)) { 8083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitInlineSmiBinaryOp(expr, op, mode, left, right); 8090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 8103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitBinaryOp(expr, op, mode); 8110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 8120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 8130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::ForwardBailoutToChild(Expression* expr) { 816b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info_->HasDeoptimizationSupport()) return; 817b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(context()->IsTest()); 818b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(expr == forward_bailout_stack_->expr()); 819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch forward_bailout_pending_ = forward_bailout_stack_; 820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 822b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 8233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitInCurrentContext(Expression* expr) { 8243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (context()->IsTest()) { 8253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ForwardBailoutStack stack(expr, forward_bailout_pending_); 8263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ForwardBailoutStack* saved = forward_bailout_stack_; 8273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch forward_bailout_pending_ = NULL; 8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch forward_bailout_stack_ = &stack; 8293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Visit(expr); 8303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch forward_bailout_stack_ = saved; 8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(forward_bailout_pending_ == NULL); 8333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Visit(expr); 8343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch State state = context()->IsAccumulatorValue() ? TOS_REG : NO_REGISTERS; 8353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailout(expr, state); 8363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Forwarding bailouts to children is a one shot operation. It should have 8373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // been processed at this point. 8383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(forward_bailout_pending_ == NULL); 8393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 840b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 842b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 843d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) { 844d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Block"); 845d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Breakable nested_statement(this, stmt); 846d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 847b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 84869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Scope* saved_scope = scope(); 84969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (stmt->block_scope() != NULL) { 85069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { Comment cmnt(masm_, "[ Extend block context"); 85169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch scope_ = stmt->block_scope(); 85269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ Push(scope_->GetSerializedScopeInfo()); 85369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch PushFunctionArgumentForContextAllocation(); 85469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ CallRuntime(Runtime::kPushBlockContext, 2); 85569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 85669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 85769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 85869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { Comment cmnt(masm_, "[ Declarations"); 85969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch VisitDeclarations(scope_->declarations()); 86069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 86169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 8621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 863d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 86469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch scope_ = saved_scope; 86569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(nested_statement.break_label()); 866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 867d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 868d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 869d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 870d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 871d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ExpressionStatement"); 872d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 873d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForEffect(stmt->expression()); 874d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 875d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 876d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 877d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 878d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ EmptyStatement"); 879d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 880d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 881d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 882d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 883d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 884d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ IfStatement"); 885d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 886d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label then_part, else_part, done; 887d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 88880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (stmt->HasElseStatement()) { 88980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); 890b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 89180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 89280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 89380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ jmp(&done); 894d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 89680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&else_part); 89780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->else_statement()); 89880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else { 89980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &done, &then_part); 900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 90180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 90280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 90580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 906d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 9073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); 908d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 909d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 910d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 911d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 912d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ContinueStatement"); 913d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 914d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 915d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 91669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 917db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When continuing, we clobber the unpredictable value in the accumulator 918db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 919db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 920db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 921db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 922d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsContinueTarget(stmt->target())) { 92369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 92669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (context_length > 0) { 92769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (context_length > 0) { 92869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 92969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch --context_length; 93069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 93169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 93269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 93369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 934d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 93569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ jmp(current->AsIteration()->continue_label()); 936d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 937d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 938d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 939d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 940d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ BreakStatement"); 941d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 942d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 943d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 94469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 945db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When breaking, we clobber the unpredictable value in the accumulator 946db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 947db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 948db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 949db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 950d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsBreakTarget(stmt->target())) { 95169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 952d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 95469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (context_length > 0) { 95569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (context_length > 0) { 95669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 95769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch --context_length; 95869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 95969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 96069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 96169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 962d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 96369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ jmp(current->AsBreakable()->break_label()); 964d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 965d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 966d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ReturnStatement"); 969d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 970d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* expr = stmt->expression(); 9710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForAccumulatorValue(expr); 972d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 973d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Exit all nested statements. 974d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 975d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 97669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 977d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (current != NULL) { 97869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 979d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 980d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 981d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 9827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitReturnSequence(); 983d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 984d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 985d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 98669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { 98769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Comment cmnt(masm_, "[ WithStatement"); 988d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 989d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 9900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(stmt->expression()); 9913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushFunctionArgumentForContextAllocation(); 9923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ CallRuntime(Runtime::kPushWithContext, 2); 99369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch decrement_stack_height(); 99469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 99569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 99669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { WithOrCatch body(this); 99769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Visit(stmt->statement()); 99869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 99969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 100069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Pop context. 100169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 100269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Update local stack frame context field. 1003d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1004d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1005d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1006d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 10073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitExitContextStatement(ExitContextStatement* stmt) { 10083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, "[ ExitContextStatement"); 1009d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Pop context. 1012d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1013d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Update local stack frame context field. 1014d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1015d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1017d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1018d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1019d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DoWhileStatement"); 1020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label body, stack_check; 1022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1025d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1026d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1027d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1028d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 102980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Record the position of the do while condition and make sure it is 103080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // possible to break on the condition. 103169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 1032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 10337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(stmt->cond(), stmt->condition_position()); 103480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 1035b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &stack_check, 103669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 1037b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &stack_check); 10387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check stack before looping. 1040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&stack_check); 1042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EmitStackCheck(stmt); 1043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&body); 1044d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 104669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1047d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1048d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1049d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1050d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WhileStatement"); 1053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label test, body; 1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1056d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1057d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1058d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop. 1059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&test); 1060d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1062d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1063d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 106480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 106580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Emit the statement position here as this is where the while 106680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // statement code starts. 106769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 10687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1069f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1070d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EmitStackCheck(stmt); 1072d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&test); 107480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 107580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen &body, 107669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 107769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label()); 1078d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1079b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 108069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1081d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1082d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1083d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1084d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1085d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1086d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ForStatement"); 1087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label test, body; 1088d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1089d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1090d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 1091d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 1092d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1093d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1094d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1095d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop (even if empty). 1096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&test); 1097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1099d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 110369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 1104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 1106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 1107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 110980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Emit the statement position here as this is where the for 111080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // statement code starts. 11117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch EmitStackCheck(stmt); 1115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&test); 1117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 111880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 111980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen &body, 112069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 112169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label()); 1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&body); 1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 112769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryCatchStatement"); 1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try block adds a handler to the exception handler chain 1136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // before entering, and removes it again when exiting normally. 1137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If an exception is thrown during execution of the try block, 1138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // control is passed to the handler, which also consumes the handler. 1139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // At this point, the exception is in a register, and store it in 1140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // the temporary local variable (prints as ".catch-var") before 1141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the catch block. The catch block has been rewritten 1142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // to introduce a new scope to bind the catch variable and to remove 1143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // that scope again afterwards. 1144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 114569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Label try_handler_setup, done; 1146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 1147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code, exception in result register. 1148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 11493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Extend the context before executing the catch block. 11503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { Comment cmnt(masm_, "[ Extend catch context"); 11513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Push(stmt->variable()->name()); 11523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ push(result_register()); 11533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushFunctionArgumentForContextAllocation(); 11543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ CallRuntime(Runtime::kPushCatchContext, 3); 11553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 11563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context_register()); 1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 11593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Scope* saved_scope = scope(); 11603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch scope_ = stmt->scope(); 11613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(scope_->declarations()->is_empty()); 116269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { WithOrCatch body(this); 116369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Visit(stmt->catch_block()); 116469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 11653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch scope_ = saved_scope; 1166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try block code. Sets up the exception handler chain. 1169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 1170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 117169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const int delta = StackHandlerConstants::kSize / kPointerSize; 117269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch TryCatch try_block(this); 1173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 117469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch increment_stack_height(delta); 1175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 117769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch decrement_stack_height(delta); 1178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryFinallyStatement"); 1185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try finally is compiled by setting up a try-handler on the stack while 1187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the try body, and removing it again afterwards. 1188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try-finally construct can enter the finally block in three ways: 1190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1. By exiting the try-block normally. This removes the try-handler and 1191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // calls the finally block code before continuing. 1192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 2. By exiting the try-block with a function-local control flow transfer 1193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (break/continue/return). The site of the, e.g., break removes the 1194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // try handler and calls the finally block code before continuing 1195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // its outward control transfer. 1196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 3. by exiting the try-block with a thrown exception. 1197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This can happen in nested function calls. It traverses the try-handler 1198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // chain and consumes the try-handler entry before jumping to the 1199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // handler code. The handler code then calls the finally-block before 1200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // rethrowing the exception. 1201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The finally block must assume a return address on top of the stack 1203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (or in the link register on ARM chips) and a value (return value or 1204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception) in the result register (rax/eax/r0), both of which must 1205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // be preserved. The return address isn't GC-safe, so it should be 1206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // cooked before GC. 1207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label finally_entry; 1208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label try_handler_setup; 120969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const int original_stack_height = stack_height(); 1210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup the try-handler chain. Use a call to 1212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Jump to try-handler setup and try-block code. Use call to put try-handler 1213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // address on stack. 1214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&try_handler_setup); 1215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try handler code. Return address of call is pushed on handler stack. 1216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This code is only executed during stack-handler traversal when an 121869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // exception is thrown. The exception is in the result register, which 1219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // is retained by the finally block. 122069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Call the finally block and then rethrow the exception if it returns. 1221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ push(result_register()); 1223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kReThrow, 1); 1224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&finally_entry); 1227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Finally block implementation. 1229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Finally finally_block(this); 1230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke EnterFinallyBlock(); 123169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch set_stack_height(original_stack_height + Finally::kElementCount); 1232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 1233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ExitFinallyBlock(); // Return to the calling code. 1234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&try_handler_setup); 1237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 1238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Setup try handler (stack pointer registers). 123969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const int delta = StackHandlerConstants::kSize / kPointerSize; 1240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TryFinally try_block(this, &finally_entry); 1241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); 124269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch set_stack_height(original_stack_height + delta); 1243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 124569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch set_stack_height(original_stack_height); 1246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1247db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // Execute the finally block on the way out. Clobber the unpredictable 1248db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // value in the accumulator with one that's safe for GC. The finally 1249db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // block will unconditionally preserve the accumulator on the stack. 1250db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 1257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DebuggerStatement"); 1258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 12594515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 1260402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu __ DebugBreak(); 1261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Ignore the return value. 1262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 1263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) { 1267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Conditional"); 1268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label true_case, false_case, done; 126980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&true_case); 12737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->then_expression(), 12747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->then_expression_position()); 127569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int start_stack_height = stack_height(); 1276f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (context()->IsTest()) { 1277f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const TestContext* for_test = TestContext::cast(context()); 1278f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch VisitForControl(expr->then_expression(), 1279f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->true_label(), 1280f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->false_label(), 1281f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch NULL); 1282f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 12833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitInCurrentContext(expr->then_expression()); 1284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&false_case); 128969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch set_stack_height(start_stack_height); 1290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (context()->IsTest()) ForwardBailoutToChild(expr); 12917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->else_expression(), 12927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->else_expression_position()); 12933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitInCurrentContext(expr->else_expression()); 1294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, merge it with true case here. 12950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!context()->IsTest()) { 1296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) { 1302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Literal"); 13030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen context()->Plug(expr->handle()); 1304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1307f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1308f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ FunctionLiteral"); 1309f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1310f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Build the function boilerplate and instantiate it. 1311f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<SharedFunctionInfo> function_info = 1312f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Compiler::BuildFunctionInfo(expr, script()); 1313f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (function_info.is_null()) { 1314f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SetStackOverflow(); 1315f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return; 1316f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 13178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang EmitNewClosure(function_info, expr->pretenure()); 1318f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1319f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1320f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1321f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitSharedFunctionInfoLiteral( 1322f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke SharedFunctionInfoLiteral* expr) { 1323f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); 13248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang EmitNewClosure(expr->shared_function_info(), false); 1325f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1326f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1327f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) { 1329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Throw"); 133069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Throw has no effect on the stack height or the current expression context. 133169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Usually the expression context is null, because throw is a statement. 13320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(expr->exception()); 1333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kThrow, 1); 133469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch decrement_stack_height(); 1335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Never returns here. 1336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 133969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochFullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( 134069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int* stack_depth, 134169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int* context_length) { 1342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 134369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ Drop(*stack_depth); 1344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 134569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch *stack_depth = 0; 134669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return previous_; 1347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 134980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 13503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool FullCodeGenerator::TryLiteralCompare(CompareOperation* compare, 13513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label* if_true, 13523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label* if_false, 13533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label* fall_through) { 13543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression *expr; 13553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> check; 13563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (compare->IsLiteralCompareTypeof(&expr, &check)) { 13573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitLiteralCompareTypeof(expr, check, if_true, if_false, fall_through); 13583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 13593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 13603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (compare->IsLiteralCompareUndefined(&expr)) { 13623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitLiteralCompareUndefined(expr, if_true, if_false, fall_through); 13633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 13643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 13653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 13673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 13683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __ 1371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} } // namespace v8::internal 1374