full-codegen.cc revision 8f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitVariableDeclaration( 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableDeclaration* decl) { 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitFunctionDeclaration( 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionDeclaration* decl) { 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleDeclaration( 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ModuleDeclaration* decl) { 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitImportDeclaration( 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ImportDeclaration* decl) { 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitExportDeclaration( 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExportDeclaration* decl) { 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) { 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) { 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModulePath(ModulePath* module) { 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) { 857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBlock(Block* stmt) { 897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitExpressionStatement( 937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ExpressionStatement* stmt) { 947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if expression is breakable. 957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) { 1007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) { 1047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the condition is breakable the if statement is breakable. 1057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->condition()); 1067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitContinueStatement( 1107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ContinueStatement* stmt) { 1117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { 1157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { 1197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Return is breakable if the expression is. 1207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 1217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 12469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { 1257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 1267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { 1307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Switch statements breakable if the tag expression is. 1317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->tag()); 1327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { 1367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark do while as breakable to avoid adding a break slot in front of it. 1377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) { 1427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark while statements breakable if the condition expression is. 1437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 1447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForStatement(ForStatement* stmt) { 1487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for statements breakable if the condition expression is. 1497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (stmt->cond() != NULL) { 1507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 1517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 1527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) { 1567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for in statements breakable if the enumerable expression is. 1577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->enumerable()); 1587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryCatchStatement( 1627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryCatchStatement* stmt) { 1637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try catch as breakable to avoid adding a break slot in front of it. 1647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryFinallyStatement( 1697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryFinallyStatement* stmt) { 1707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try finally as breakable to avoid adding a break slot in front of it. 1717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDebuggerStatement( 1767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebuggerStatement* stmt) { 1777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The debugger statement is breakable. 1787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) { 1837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSharedFunctionInfoLiteral( 1877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SharedFunctionInfoLiteral* expr) { 1887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitConditional(Conditional* expr) { 1927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) { 1967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitLiteral(Literal* expr) { 2007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) { 2047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) { 2087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { 2127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitAssignment(Assignment* expr) { 2167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If assigning to a property (including a global property) the assignment is 2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. 218589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch VariableProxy* proxy = expr->target()->AsVariableProxy(); 2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Property* prop = expr->target()->AsProperty(); 220589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) { 2217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return; 2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 2247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Otherwise the assignment is breakable if the assigned value is. 2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->value()); 2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThrow(Throw* expr) { 2317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Throw is breakable if the expression is. 2327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->exception()); 2337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitProperty(Property* expr) { 2377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Property load is breakable. 2387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCall(Call* expr) { 2437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls both through IC and call stub are breakable. 2447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallNew(CallNew* expr) { 2497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls through new are breakable. 2507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) { 2557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) { 2597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCountOperation(CountOperation* expr) { 2647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) { 2697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2707d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch if (expr->op() != Token::AND && 2717d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch expr->op() != Token::OR) { 2727d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch Visit(expr->right()); 2737d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch } 2747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) { 2787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->right()); 2807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) { 2847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm()) 288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 289f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool FullCodeGenerator::MakeCode(CompilationInfo* info) { 29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = info->isolate(); 2913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Script> script = info->script(); 292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!script->IsUndefined() && !script->source()->IsUndefined()) { 293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = String::cast(script->source())->length(); 29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_full_codegen_source_size()->Increment(len); 295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_codegen) { 297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("Full Compiler - "); 298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 2993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu CodeGenerator::MakeCodePrologue(info); 300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kInitialBufferSize = 4 * KB; 3018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize); 302b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 303b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch masm.positions_recorder()->StartGDBJITLineInfoRecording(); 304b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 305402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FullCodeGenerator cgen(&masm, info); 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cgen.Generate(); 308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (cgen.HasStackOverflow()) { 30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!isolate->has_pending_exception()); 310f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return false; 311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned table_offset = cgen.EmitStackCheckTable(); 313f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 314589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Code::Flags flags = Code::ComputeFlags(Code::FUNCTION); 315f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_optimizable(info->IsOptimizable() && 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !info->function()->flags()->Contains(kDontOptimize)); 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_self_optimization_header(cgen.has_self_optimization_header_); 319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cgen.PopulateDeoptimizationData(code); 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cgen.PopulateTypeFeedbackInfo(code); 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cgen.PopulateTypeFeedbackCells(code); 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_handler_table(*cgen.handler_table()); 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 325589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch code->set_has_debug_break_slots( 326589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch info->isolate()->debugger()->IsDebuggerActive()); 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_compiled_optimizable(info->IsOptimizable()); 3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif // ENABLE_DEBUGGER_SUPPORT 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_allow_osr_at_loop_nesting_level(0); 3308f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch code->set_profiler_ticks(0); 3311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block code->set_stack_check_table_offset(table_offset); 332b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CodeGenerator::PrintCode(code, info); 3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->SetCode(code); // May be an empty handle. 3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!code.is_null()) { 3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate->runtime_profiler()->NotifyCodeGenerated(code->instruction_size()); 3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 337b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 3381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (FLAG_gdbjit && !code.is_null()) { 339b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJITLineInfo* lineinfo = 340b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch masm.positions_recorder()->DetachGDBJITLineInfo(); 341b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 342b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJIT(RegisterDetailedLineInfo(*code, lineinfo)); 343b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 344b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 345f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return !code.is_null(); 346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochunsigned FullCodeGenerator::EmitStackCheckTable() { 350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The stack check table consists of a length (in number of entries) 351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // field, and then a sequence of entries. Each entry is a pair of AST id 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and code-relative pc offset. 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm()->Align(kIntSize); 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned offset = masm()->pc_offset(); 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned length = stack_checks_.length(); 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(length); 357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (unsigned i = 0; i < length; ++i) { 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(stack_checks_[i].id); 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(stack_checks_[i].pc_and_state); 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return offset; 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fill in the deoptimization information. 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); 368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info_->HasDeoptimizationSupport()) return; 369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = bailout_entries_.length(); 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<DeoptimizationOutputData> data = isolate()->factory()-> 37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block NewDeoptimizationOutputData(length, TENURED); 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; i++) { 373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id)); 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state)); 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_deoptimization_data(*data); 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) { 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo(); 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->set_ic_total_count(ic_total_count_); 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!isolate()->heap()->InNewSpace(*info)); 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_type_feedback_info(*info); 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) { 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (type_feedback_cells_.is_empty()) return; 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = type_feedback_cells_.length(); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int array_size = TypeFeedbackCells::LengthOfFixedArray(length); 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<TypeFeedbackCells> cache = Handle<TypeFeedbackCells>::cast( 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->NewFixedArray(array_size, TENURED)); 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < length; i++) { 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cache->SetAstId(i, Smi::FromInt(type_feedback_cells_[i].ast_id)); 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cache->SetCell(i, *type_feedback_cells_[i].cell); 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells( 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *cache); 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::PrepareForBailout(Expression* node, State state) { 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(node->id(), state); 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::RecordJSReturnSite(Call* call) { 410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We record the offset of the function return so we can rebuild the frame 411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // if the function was inlined, i.e., this is the return address in the 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // inlined function's frame. 413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The state is ignored. We defensively set it to TOS_REG, which is the 415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // real state of the unoptimized code at the return site. 416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(call->ReturnId(), TOS_REG); 417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // In debug builds, mark the return so we can verify that this function 419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // was called. 420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!call->return_is_recorded_); 421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch call->return_is_recorded_ = true; 422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) { 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There's no need to prepare this code for bailouts from already optimized 428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code or code that can't be optimized. 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!info_->HasDeoptimizationSupport()) return; 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned pc_and_state = 431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StateField::encode(state) | PcField::encode(masm_->pc_offset()); 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Smi::IsValid(pc_and_state)); 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch BailoutEntry entry = { id, pc_and_state }; 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_enable_slow_asserts) { 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Assert that we don't have multiple bailout entries for the same node. 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < bailout_entries_.length(); i++) { 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (bailout_entries_.at(i).id == entry.id) { 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AstPrinter printer; 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("%s", printer.PrintProgram(info_->function())); 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif // DEBUG 446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bailout_entries_.Add(entry); 447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::RecordTypeFeedbackCell( 4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned id, Handle<JSGlobalPropertyCell> cell) { 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TypeFeedbackCellEntry entry = { id, cell }; 4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch type_feedback_cells_.Add(entry); 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::RecordStackCheck(unsigned ast_id) { 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The pc offset does not need to be encoded and packed together with a 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // state. 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(masm_->pc_offset() > 0); 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BailoutEntry entry = { ast_id, static_cast<unsigned>(masm_->pc_offset()) }; 462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch stack_checks_.Add(entry); 463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 46680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenbool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { 46780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Inline smi case inside loops, but not division and modulo which 46880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // are too complicated and take up too much space. 4690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (op == Token::DIV ||op == Token::MOD) return false; 4700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (FLAG_always_inline_smi_code) return true; 4710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return loop_depth_ > 0; 47280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 47380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 47480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4750d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::Plug(Register reg) const { 4760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4790d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 4800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 4810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4840d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(Register reg) const { 4850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ push(reg); 4860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4890d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(Register reg) const { 4900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 4910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 4933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch codegen()->DoTest(this); 4940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4970d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PlugTOS() const { 4980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Drop(1); 4990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5020d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 5030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ pop(result_register()); 5040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5070d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PlugTOS() const { 5080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5110d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PlugTOS() const { 5120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 5130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ pop(result_register()); 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 5153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch codegen()->DoTest(this); 5160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5190d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PrepareTest( 5200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // In an effect context, the true and the false case branch to the 5260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // same label. 5270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *if_false = *fall_through = materialize_true; 5280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5310d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PrepareTest( 5320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 5380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 5390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5420d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PrepareTest( 5430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 5490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 5500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5530d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PrepareTest( 5540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = true_label_; 5600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = false_label_; 5610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *fall_through = fall_through_; 56280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 56380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 56480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::DoTest(const TestContext* context) { 5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(context->condition(), 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->true_label(), 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->false_label(), 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->fall_through()); 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 573d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDeclarations( 574d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke ZoneList<Declaration*>* declarations) { 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int save_global_count = global_count_; 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch global_count_ = 0; 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AstVisitor::VisitDeclarations(declarations); 579d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 580589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Batch declare global functions and variables. 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (global_count_ > 0) { 58244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<FixedArray> array = 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->NewFixedArray(2 * global_count_, TENURED); 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = declarations->length(); 585d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (int j = 0, i = 0; i < length; i++) { 586d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Declaration* decl = declarations->at(i); 587d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Variable* var = decl->proxy()->var(); 588d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 589589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (var->IsUnallocated()) { 590d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *(var->name())); 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration(); 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fun_decl == NULL) { 5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (var->binding_needs_init()) { 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // In case this binding needs initialization use the hole. 595d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_the_hole(j++); 596d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 597d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set_undefined(j++); 598d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 599d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 6006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> function = 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Compiler::BuildFunctionInfo(fun_decl->fun(), script()); 602d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check for stack-overflow exception. 603f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (function.is_null()) { 604f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SetStackOverflow(); 605f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return; 606f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 607d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke array->set(j++, *function); 608d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 609d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 610d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 611d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Invoke the platform-dependent code generator to do the actual 612589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // declaration the global functions and variables. 613d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DeclareGlobals(array); 614d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch global_count_ = save_global_count; 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitDeclaration(decl->proxy(), decl->mode(), NULL); 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitDeclaration(decl->proxy(), decl->mode(), decl->fun()); 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* decl) { 6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitDeclaration(decl->proxy(), decl->mode(), NULL); 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) { 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitDeclaration(decl->proxy(), decl->mode(), NULL); 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) { 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg) 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg) 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) { 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg) 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitModulePath(ModulePath* module) { 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg) 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitModuleUrl(ModuleUrl* decl) { 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(rossberg) 662d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 663d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 664d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 665589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint FullCodeGenerator::DeclareGlobalsFlags() { 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode())); 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DeclareGlobalsEvalFlag::encode(is_eval()) | 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeclareGlobalsNativeFlag::encode(is_native()) | 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeclareGlobalsLanguageMode::encode(language_mode()); 670589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 671589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 672589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 6743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, fun->start_position()); 675d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 676d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 677d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 678d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 6793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); 680d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 681d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 682d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 683d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) { 6847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 6853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!isolate()->debugger()->IsDebuggerActive()) { 6863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 6873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 6883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the statement will be breakable without adding a debug break 6893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot. 6903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakableStatementChecker checker; 6913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch checker.Check(stmt); 6923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Record the statement position right here if the statement is not 6933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breakable. For breakable statements the actual recording of the 6943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // position will be postponed to the breakable code (typically an IC). 6953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool position_recorded = CodeGenerator::RecordPositions( 6963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch masm_, stmt->statement_pos(), !checker.is_breakable()); 6973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the position recording did record a new position generate a debug 6983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // break slot to make the statement breakable. 6993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (position_recorded) { 7003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Debug::GenerateSlot(masm_); 7017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 7023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 7043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 7057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 7067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 7077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) { 7107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT 7113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!isolate()->debugger()->IsDebuggerActive()) { 7123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, pos); 7133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 7143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the expression will be breakable without adding a debug break 7153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot. 7163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakableStatementChecker checker; 7173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch checker.Check(expr); 7183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Record a statement position right here if the expression is not 7193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breakable. For breakable expressions the actual recording of the 7203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // position will be postponed to the breakable code (typically an IC). 7213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // NOTE this will record a statement position for something which might 7223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // not be a statement. As stepping in the debugger will only stop at 7233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // statement positions this is used for e.g. the condition expression of 7243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // a do while loop. 7253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool position_recorded = CodeGenerator::RecordPositions( 7263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch masm_, pos, !checker.is_breakable()); 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the position recording did record a new position generate a debug 7283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // break slot to make the statement breakable. 7293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (position_recorded) { 7303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Debug::GenerateSlot(masm_); 7317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 7323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 7337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else 7343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, pos); 7357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif 736d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 737d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 738d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 739d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(int pos) { 7403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, pos); 741d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::SetSourcePosition(int pos) { 7453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (pos != RelocInfo::kNoPosition) { 746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm_->positions_recorder()->RecordPosition(pos); 747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 748d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 749d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 750d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 7510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// Lookup table for code generators for special runtime calls which are 7520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// generated inline. 7530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 7540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen &FullCodeGenerator::Emit##Name, 755791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 7560d5e116f6aee03185f237311a943491bb079a768Kristian Monsenconst FullCodeGenerator::InlineFunctionGenerator 7570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::kInlineFunctionGenerators[] = { 7580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 7590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 7600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 7610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#undef INLINE_FUNCTION_GENERATOR_ADDRESS 7620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7640d5e116f6aee03185f237311a943491bb079a768Kristian MonsenFullCodeGenerator::InlineFunctionGenerator 7650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { 766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int lookup_index = 767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction); 768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(lookup_index >= 0); 769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(static_cast<size_t>(lookup_index) < 770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ARRAY_SIZE(kInlineFunctionGenerators)); 771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return kInlineFunctionGenerators[lookup_index]; 7720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 7730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) { 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Runtime::Function* function = expr->function(); 7770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(function != NULL); 7780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen ASSERT(function->intrinsic_type == Runtime::INLINE); 7790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen InlineFunctionGenerator generator = 7800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FindInlineFunctionGenerator(function->function_id); 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ((*this).*(generator))(expr); 78280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 78380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 78480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 78580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 7863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (expr->op()) { 78780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::COMMA: 7883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitComma(expr); 78980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::OR: 79080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::AND: 7913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitLogicalExpression(expr); 79280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen default: 7933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitArithmeticExpression(expr); 79480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 7957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 7967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitInDuplicateContext(Expression* expr) { 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (context()->IsEffect()) { 8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForEffect(expr); 8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (context()->IsAccumulatorValue()) { 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForAccumulatorValue(expr); 8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (context()->IsStackValue()) { 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForStackValue(expr); 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (context()->IsTest()) { 8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const TestContext* test = TestContext::cast(context()); 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForControl(expr, test->true_label(), test->false_label(), 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch test->fall_through()); 8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitComma(BinaryOperation* expr) { 8143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, "[ Comma"); 8153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForEffect(expr->left()); 8163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(expr->right()); 817d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 818d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 819d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 8203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { 8213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_logical_and = expr->op() == Token::AND; 8223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR"); 8233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* left = expr->left(); 8243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* right = expr->right(); 8253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int right_id = expr->RightId(); 8263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label done; 8270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (context()->IsTest()) { 8293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label eval_right; 8303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const TestContext* test = TestContext::cast(context()); 8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 8323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &eval_right, test->false_label(), &eval_right); 8333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, test->true_label(), &eval_right, &eval_right); 8353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 8373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&eval_right); 8383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (context()->IsAccumulatorValue()) { 8403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(left); 8413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We want the value in the accumulator for the test, and on the stack in 8423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // case we need it. 8433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ push(result_register()); 8443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label discard, restore; 8453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 8463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &discard, &restore, &restore); 8473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &restore, &discard, &restore); 8493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&restore); 8513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ pop(result_register()); 8523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ jmp(&done); 8533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&discard); 8543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Drop(1); 8553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 8563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (context()->IsStackValue()) { 8583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(left); 8593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We want the value in the accumulator for the test, and on the stack in 8603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // case we need it. 8613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ push(result_register()); 8623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label discard; 8633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 8643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &discard, &done, &discard); 8653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &done, &discard, &discard); 8673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&discard); 8693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Drop(1); 8703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 8710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 8733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(context()->IsEffect()); 8743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label eval_right; 8753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 8763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &eval_right, &done, &eval_right); 8773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &done, &eval_right, &eval_right); 8793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 8813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&eval_right); 8820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 8833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(right); 8853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&done); 8860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 8870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 88880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 8903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Token::Value op = expr->op(); 8913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, "[ ArithmeticExpression"); 8923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* left = expr->left(); 8933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* right = expr->right(); 8943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OverwriteMode mode = 8953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch left->ResultOverwriteAllowed() 8963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ? OVERWRITE_LEFT 8973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE); 89880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 8993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForStackValue(left); 9003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(right); 90180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 9023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SetSourcePosition(expr->position()); 9033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (ShouldInlineSmiCase(op)) { 9043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitInlineSmiBinaryOp(expr, op, mode, left, right); 9050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 9063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitBinaryOp(expr, op, mode); 9070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 9080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 9090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 911d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) { 912d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Block"); 913589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch NestedBlock nested_block(this, stmt); 914d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 91669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Scope* saved_scope = scope(); 917589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Push a block context when entering a block with block scoped variables. 91869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (stmt->block_scope() != NULL) { 91969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { Comment cmnt(masm_, "[ Extend block context"); 92069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch scope_ = stmt->block_scope(); 9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); 9223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS; 9233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(scope_info); 92469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch PushFunctionArgumentForContextAllocation(); 9253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) { 9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastNewBlockContextStub stub(heap_slots); 9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallStub(&stub); 9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntime(Runtime::kPushBlockContext, 2); 9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Replace the context stored in the frame. 93369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 93469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 93569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 93669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { Comment cmnt(masm_, "[ Declarations"); 93769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch VisitDeclarations(scope_->declarations()); 93869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 93969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 9401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 941d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 94269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch scope_ = saved_scope; 943589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch __ bind(nested_block.break_label()); 944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 945589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 946589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Pop block context if necessary. 947589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (stmt->block_scope() != NULL) { 948589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 949589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Update local stack frame context field. 950589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 951589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch context_register()); 952589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 954d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 955d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 956d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 957d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ExpressionStatement"); 958d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 959d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForEffect(stmt->expression()); 960d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 961d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 962d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 963d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 964d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ EmptyStatement"); 965d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 966d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 969d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 970d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ IfStatement"); 971d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 972d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label then_part, else_part, done; 973d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 97480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (stmt->HasElseStatement()) { 97580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); 976b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 97780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 97880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 97980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ jmp(&done); 980d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 981b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 98280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&else_part); 98380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->else_statement()); 98480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else { 98580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &done, &then_part); 986b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 98780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 98880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 989b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 99180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 992d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 9933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); 994d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 995d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 996d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 997d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 998d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ContinueStatement"); 999d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1000d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1001d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 100269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 1003db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When continuing, we clobber the unpredictable value in the accumulator 1004db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 1005db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 1006db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 1007db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1008d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsContinueTarget(stmt->target())) { 100969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 1010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 101269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (context_length > 0) { 101369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (context_length > 0) { 101469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 101569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch --context_length; 101669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 101769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 101869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 101969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 102169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ jmp(current->AsIteration()->continue_label()); 1022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1025d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 1026d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ BreakStatement"); 1027d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1028d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1029d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 103069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 1031db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When breaking, we clobber the unpredictable value in the accumulator 1032db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 1033db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 1034db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 1035db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1036d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsBreakTarget(stmt->target())) { 103769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 1038d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1039d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 104069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (context_length > 0) { 104169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (context_length > 0) { 104269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 104369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch --context_length; 104469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 104569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 104669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 104769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1048d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 104969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ jmp(current->AsBreakable()->break_label()); 1050d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1053d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ReturnStatement"); 1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1056d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Expression* expr = stmt->expression(); 10570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForAccumulatorValue(expr); 1058d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1059d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Exit all nested statements. 1060d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1061d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 106269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 1063d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (current != NULL) { 106469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 1065d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1066d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1067d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 10687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitReturnSequence(); 1069d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1070d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1071d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 107269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { 107369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Comment cmnt(masm_, "[ WithStatement"); 1074d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1075d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 10760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(stmt->expression()); 10773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushFunctionArgumentForContextAllocation(); 10783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ CallRuntime(Runtime::kPushWithContext, 2); 107969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 108069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 108169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { WithOrCatch body(this); 108269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Visit(stmt->statement()); 108369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 108469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 108569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Pop context. 108669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 108769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Update local stack frame context field. 1088d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1089d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1090d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1091d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1092d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1093d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DoWhileStatement"); 1094d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1095b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label body, stack_check; 1096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1098d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1099d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 110380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Record the position of the do while condition and make sure it is 110480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // possible to break on the condition. 110569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 1106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 11077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(stmt->cond(), stmt->condition_position()); 110880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 1109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &stack_check, 111069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 1111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch &stack_check); 11127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check stack before looping. 1114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&stack_check); 11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitStackCheck(stmt, &body); 1117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&body); 1118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 112069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WhileStatement"); 1127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label test, body; 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop. 1133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&test); 1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 113880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 113980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Emit the statement position here as this is where the while 114080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // statement code starts. 114169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 11427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1143f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 11453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitStackCheck(stmt, &body); 1146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&test); 114880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 114980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen &body, 115069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 115169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label()); 1152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 115469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ForStatement"); 1161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label test, body; 1162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 11643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set statement position for a break slot before entering the for-body. 11663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetStatementPosition(stmt); 11673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 1169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 1170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop (even if empty). 1174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&test); 1175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 118169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 1182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 1183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 1184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 118680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Emit the statement position here as this is where the for 118780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // statement code starts. 11887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitStackCheck(stmt, &body); 1192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&test); 1194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 119580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 119680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen &body, 119769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 119869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label()); 1199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 1200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&body); 1201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1203b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 120469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryCatchStatement"); 1211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 12123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The try block adds a handler to the exception handler chain before 12133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // entering, and removes it again when exiting normally. If an exception 12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is thrown during execution of the try block, the handler is consumed 12153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // and control is passed to the catch block with the exception in the 12163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result register. 12173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label try_entry, handler_entry, exit; 12193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&try_entry); 12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&handler_entry); 12213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 12223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Exception handler code, the exception is in the result register. 12233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Extend the context before executing the catch block. 12243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { Comment cmnt(masm_, "[ Extend catch context"); 12253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Push(stmt->variable()->name()); 12263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ push(result_register()); 12273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushFunctionArgumentForContextAllocation(); 12283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ CallRuntime(Runtime::kPushCatchContext, 3); 12293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 12303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context_register()); 1231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 12333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Scope* saved_scope = scope(); 12343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch scope_ = stmt->scope(); 12353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(scope_->declarations()->is_empty()); 12363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { WithOrCatch catch_body(this); 123769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Visit(stmt->catch_block()); 123869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Restore the context. 1240589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1241589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 12423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch scope_ = saved_scope; 12433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&exit); 1244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try block code. Sets up the exception handler chain. 12463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&try_entry); 12473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PushTryHandler(StackHandler::CATCH, stmt->index()); 12483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { TryCatch try_body(this); 1249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 12513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PopTryHandler(); 12523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&exit); 1253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryFinallyStatement"); 1258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try finally is compiled by setting up a try-handler on the stack while 1260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the try body, and removing it again afterwards. 1261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try-finally construct can enter the finally block in three ways: 1263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1. By exiting the try-block normally. This removes the try-handler and 12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // calls the finally block code before continuing. 1265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 2. By exiting the try-block with a function-local control flow transfer 1266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (break/continue/return). The site of the, e.g., break removes the 1267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // try handler and calls the finally block code before continuing 1268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // its outward control transfer. 12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 3. By exiting the try-block with a thrown exception. 1270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This can happen in nested function calls. It traverses the try-handler 1271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // chain and consumes the try-handler entry before jumping to the 1272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // handler code. The handler code then calls the finally-block before 1273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // rethrowing the exception. 1274d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The finally block must assume a return address on top of the stack 1276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (or in the link register on ARM chips) and a value (return value or 1277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception) in the result register (rax/eax/r0), both of which must 1278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // be preserved. The return address isn't GC-safe, so it should be 1279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // cooked before GC. 12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label try_entry, handler_entry, finally_entry; 12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Jump to try-handler setup and try-block code. 12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&try_entry); 12843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&handler_entry); 12853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 12863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Exception handler code. This code is only executed when an exception 12873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is thrown. The exception is in the result register, and must be 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // preserved by the finally block. Call the finally block and then 12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // rethrow the exception if it returns. 12903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Call(&finally_entry); 12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(result_register()); 12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntime(Runtime::kReThrow, 1); 1293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 12943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Finally block implementation. 1295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&finally_entry); 12963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnterFinallyBlock(); 12973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { Finally finally_body(this); 1298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 1299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 13003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExitFinallyBlock(); // Return to the calling code. 1301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up try handler. 13033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&try_entry); 13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PushTryHandler(StackHandler::FINALLY, stmt->index()); 13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { TryFinally try_body(this, &finally_entry); 1306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 13083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PopTryHandler(); 1309db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // Execute the finally block on the way out. Clobber the unpredictable 13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // value in the result register with one that's safe for GC because the 13113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // finally block will unconditionally preserve the result register on the 13123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // stack. 1313db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 1320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DebuggerStatement"); 1321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 13224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 1323402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu __ DebugBreak(); 1324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Ignore the return value. 1325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif 1326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) { 1330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Conditional"); 1331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label true_case, false_case, done; 133280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1334b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&true_case); 13367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->then_expression(), 13377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->then_expression_position()); 1338f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (context()->IsTest()) { 1339f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const TestContext* for_test = TestContext::cast(context()); 1340f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch VisitForControl(expr->then_expression(), 1341f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->true_label(), 1342f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->false_label(), 1343f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch NULL); 1344f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 13453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(expr->then_expression()); 1346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&false_case); 13517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetExpressionPosition(expr->else_expression(), 13527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expr->else_expression_position()); 13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(expr->else_expression()); 1354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, merge it with true case here. 13550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!context()->IsTest()) { 1356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) { 1362d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Literal"); 13630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen context()->Plug(expr->handle()); 1364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1367f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1368f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ FunctionLiteral"); 1369f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1370f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Build the function boilerplate and instantiate it. 1371f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<SharedFunctionInfo> function_info = 1372f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Compiler::BuildFunctionInfo(expr, script()); 1373f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (function_info.is_null()) { 1374f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SetStackOverflow(); 1375f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return; 1376f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 13778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang EmitNewClosure(function_info, expr->pretenure()); 1378f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1379f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1380f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1381f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitSharedFunctionInfoLiteral( 1382f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke SharedFunctionInfoLiteral* expr) { 1383f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); 13848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang EmitNewClosure(expr->shared_function_info(), false); 1385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1387f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1388d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) { 1389d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Throw"); 13900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(expr->exception()); 1391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kThrow, 1); 1392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Never returns here. 1393d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1395d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 139669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochFullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( 139769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int* stack_depth, 139869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int* context_length) { 1399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 140069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ Drop(*stack_depth); 1401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 140269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch *stack_depth = 0; 140369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return previous_; 1404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 140680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 14073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) { 14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expression* sub_expr; 14093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> check; 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLiteralCompareTypeof(expr, sub_expr, check); 14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return true; 14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expr->IsLiteralCompareUndefined(&sub_expr)) { 14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue); 14173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 14183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expr->IsLiteralCompareNull(&sub_expr)) { 14213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLiteralCompareNil(expr, sub_expr, kNullValue); 14223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 14233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 14263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 14273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __ 1430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} } // namespace v8::internal 1433