13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/code-factory.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/debug.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/full-codegen.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/liveedit.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/prettyprinter.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopeinfo.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scopes.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/snapshot.h" 18d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 19d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 { 20d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal { 21d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Statement* stmt) { 237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt); 247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Expression* expr) { 287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr); 297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitVariableDeclaration( 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VariableDeclaration* decl) { 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitFunctionDeclaration( 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionDeclaration* decl) { 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleDeclaration( 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ModuleDeclaration* decl) { 443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitImportDeclaration( 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ImportDeclaration* decl) { 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitExportDeclaration( 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExportDeclaration* decl) { 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) { 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) { 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModulePath(ModulePath* module) { 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) { 707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BreakableStatementChecker::VisitModuleStatement(ModuleStatement* stmt) { 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBlock(Block* stmt) { 787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitExpressionStatement( 827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ExpressionStatement* stmt) { 837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check if expression is breakable. 847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) { 897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) { 937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If the condition is breakable the if statement is breakable. 947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->condition()); 957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitContinueStatement( 997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ContinueStatement* stmt) { 1007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { 1047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { 1087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Return is breakable if the expression is. 1097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 1107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 11369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { 1147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->expression()); 1157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { 1197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Switch statements breakable if the tag expression is. 1207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->tag()); 1217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { 1257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark do while as breakable to avoid adding a break slot in front of it. 1267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) { 1317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark while statements breakable if the condition expression is. 1327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 1337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForStatement(ForStatement* stmt) { 1377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for statements breakable if the condition expression is. 1387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (stmt->cond() != NULL) { 1397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->cond()); 1407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 1417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) { 1457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark for in statements breakable if the enumerable expression is. 1467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(stmt->enumerable()); 1477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) { 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For-of is breakable because of the next() call. 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_breakable_ = true; 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryCatchStatement( 1577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryCatchStatement* stmt) { 1587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try catch as breakable to avoid adding a break slot in front of it. 1597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryFinallyStatement( 1647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch TryFinallyStatement* stmt) { 1657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Mark try finally as breakable to avoid adding a break slot in front of it. 1667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDebuggerStatement( 1717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebuggerStatement* stmt) { 1727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The debugger statement is breakable. 1737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 1747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BreakableStatementChecker::VisitCaseClause(CaseClause* clause) { 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) { 1827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) { 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->extends() != NULL) { 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr->extends()); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BreakableStatementChecker::VisitNativeFunctionLiteral( 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NativeFunctionLiteral* expr) { 1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitConditional(Conditional* expr) { 1987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) { 2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitLiteral(Literal* expr) { 2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) { 2107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) { 2147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { 2187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitAssignment(Assignment* expr) { 2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // If assigning to a property (including a global property) the assignment is 2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // breakable. 224589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch VariableProxy* proxy = expr->target()->AsVariableProxy(); 2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Property* prop = expr->target()->AsProperty(); 226589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) { 2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return; 2297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 2307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Otherwise the assignment is breakable if the assigned value is. 2327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->value()); 2337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BreakableStatementChecker::VisitYield(Yield* expr) { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Yield is breakable if the expression is. 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Visit(expr->expression()); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThrow(Throw* expr) { 2437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Throw is breakable if the expression is. 2447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->exception()); 2457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitProperty(Property* expr) { 2497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Property load is breakable. 2507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCall(Call* expr) { 2557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls both through IC and call stub are breakable. 2567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallNew(CallNew* expr) { 2617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Function calls through new are breakable. 2627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch is_breakable_ = true; 2637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) { 2677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) { 2717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCountOperation(CountOperation* expr) { 2767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->expression()); 2777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) { 2817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2827d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch if (expr->op() != Token::AND && 2837d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch expr->op() != Token::OR) { 2847d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch Visit(expr->right()); 2857d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch } 2867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) { 2907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->left()); 2917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Visit(expr->right()); 2927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) { 2967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BreakableStatementChecker::VisitSuperReference(SuperReference* expr) {} 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm()) 303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 304f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool FullCodeGenerator::MakeCode(CompilationInfo* info) { 30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = info->isolate(); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TimerEventScope<TimerEventCompileFullCode> timer(info->isolate()); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Script> script = info->script(); 310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (!script->IsUndefined() && !script->source()->IsUndefined()) { 311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = String::cast(script->source())->length(); 31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_full_codegen_source_size()->Increment(len); 313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeGenerator::MakeCodePrologue(info, "full"); 315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kInitialBufferSize = 4 * KB; 3168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (info->will_serialize()) masm.enable_serializer(); 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG_CODE_EVENT(isolate, 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeStartLinePosInfoRecordEvent(masm.positions_recorder())); 321402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FullCodeGenerator cgen(&masm, info); 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cgen.Generate(); 324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (cgen.HasStackOverflow()) { 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!isolate->has_pending_exception()); 326f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return false; 327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned table_offset = cgen.EmitBackEdgeTable(); 329f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 330589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Code::Flags flags = Code::ComputeFlags(Code::FUNCTION); 331f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_optimizable(info->IsOptimizable() && 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !info->function()->dont_optimize() && 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->function()->scope()->AllowsLazyCompilation()); 335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch cgen.PopulateDeoptimizationData(code); 3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cgen.PopulateTypeFeedbackInfo(code); 337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); 3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_handler_table(*cgen.handler_table()); 3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_compiled_optimizable(info->IsOptimizable()); 340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_allow_osr_at_loop_nesting_level(0); 3418f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch code->set_profiler_ticks(0); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->set_back_edge_table_offset(table_offset); 343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CodeGenerator::PrintCode(code, info); 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info->SetCode(code); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* line_info = masm.positions_recorder()->DetachJITHandlerData(); 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG_CODE_EVENT(isolate, CodeEndLinePosInfoRecordEvent(*code, line_info)); 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochunsigned FullCodeGenerator::EmitBackEdgeTable() { 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The back edge table consists of a length (in number of entries) 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // field, and then a sequence of entries. Each entry is a pair of AST id 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // and code-relative pc offset. 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm()->Align(kPointerSize); 356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned offset = masm()->pc_offset(); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned length = back_edges_.length(); 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ dd(length); 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (unsigned i = 0; i < length; ++i) { 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ dd(back_edges_[i].id.ToInt()); 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ dd(back_edges_[i].pc); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ dd(back_edges_[i].loop_depth); 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return offset; 365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EnsureSlotContainsAllocationSite(int slot) { 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> vector = FeedbackVector(); 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!vector->get(slot)->IsAllocationSite()) { 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<AllocationSite> allocation_site = 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->NewAllocationSite(); 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch vector->set(slot, *allocation_site); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) { 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fill in the deoptimization information. 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty()); 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info_->HasDeoptimizationSupport()) return; 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int length = bailout_entries_.length(); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<DeoptimizationOutputData> data = 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeoptimizationOutputData::New(isolate(), length, TENURED); 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < length; i++) { 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data->SetAstId(i, bailout_entries_[i].id); 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state)); 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code->set_deoptimization_data(*data); 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) { 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo(); 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->set_ic_total_count(ic_total_count_); 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!isolate()->heap()->InNewSpace(*info)); 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_type_feedback_info(*info); 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::Initialize() { 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InitializeAstVisitor(info_->zone()); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The generation of debug code must match between the snapshot code and the 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // code that is generated later. This is assumed by the debugger when it is 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // calculating PC offsets after generating a debug version of code. Therefore 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we disable the production of debug code in the full compiler if we are 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // either generating a snapshot or we booted from a snapshot. 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch generate_debug_code_ = FLAG_debug_code && 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !masm_->serializer_enabled() && 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !Snapshot::HaveASnapshotToStartFrom(); 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm_->set_emit_debug_code(generate_debug_code_); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm_->set_predictable_code_size(true); 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::PrepareForBailout(Expression* node, State state) { 417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(node->id(), state); 418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 419b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 420b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode, 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id) { 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> ic = CodeFactory::LoadIC(isolate(), contextual_mode).code(); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallIC(ic, id); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::CallStoreIC(TypeFeedbackId id) { 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> ic = CodeFactory::StoreIC(isolate(), strict_mode()).code(); 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallIC(ic, id); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::RecordJSReturnSite(Call* call) { 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We record the offset of the function return so we can rebuild the frame 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // if the function was inlined, i.e., this is the return address in the 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // inlined function's frame. 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The state is ignored. We defensively set it to TOS_REG, which is the 440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // real state of the unoptimized code at the return site. 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(call->ReturnId(), TOS_REG); 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // In debug builds, mark the return so we can verify that this function 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // was called. 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!call->return_is_recorded_); 446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch call->return_is_recorded_ = true; 447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) { 452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // There's no need to prepare this code for bailouts from already optimized 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // code or code that can't be optimized. 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!info_->HasDeoptimizationSupport()) return; 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unsigned pc_and_state = 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StateField::encode(state) | PcField::encode(masm_->pc_offset()); 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Smi::IsValid(pc_and_state)); 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < bailout_entries_.length(); ++i) { 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(bailout_entries_[i].id != id); 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutEntry entry = { id, pc_and_state }; 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bailout_entries_.Add(entry, zone()); 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::RecordBackEdge(BailoutId ast_id) { 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The pc offset does not need to be encoded and packed together with a state. 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_->pc_offset() > 0); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(loop_depth() > 0); 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t depth = Min(loop_depth(), Code::kMaxLoopNestingMarker); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BackEdgeEntry entry = 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { ast_id, static_cast<unsigned>(masm_->pc_offset()), depth }; 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch back_edges_.Add(entry, zone()); 476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 47980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenbool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) { 48080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Inline smi case inside loops, but not division and modulo which 48180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // are too complicated and take up too much space. 4820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (op == Token::DIV ||op == Token::MOD) return false; 4830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (FLAG_always_inline_smi_code) return true; 4840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen return loop_depth_ > 0; 48580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 48680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 48780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4880d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::Plug(Register reg) const { 4890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4920d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { 4930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 4940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 4950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 4970d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(Register reg) const { 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(reg); 4990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5020d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(Register reg) const { 5030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 5040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Move(result_register(), reg); 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 5063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch codegen()->DoTest(this); 5070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5100d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PlugTOS() const { 5110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen __ Drop(1); 5120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5150d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(result_register()); 5170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5200d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PlugTOS() const { 5210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5240d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PlugTOS() const { 5250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // For simplicity we always test the accumulator register. 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(result_register()); 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 5283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch codegen()->DoTest(this); 5290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5320d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::PrepareTest( 5330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // In an effect context, the true and the false case branch to the 5390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // same label. 5400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *if_false = *fall_through = materialize_true; 5410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5440d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::PrepareTest( 5450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 5510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 5520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5550d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::PrepareTest( 5560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = *fall_through = materialize_true; 5620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = materialize_false; 5630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 5640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 5660d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::PrepareTest( 5670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_true, 5680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label* materialize_false, 5690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_true, 5700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** if_false, 5710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Label** fall_through) const { 5720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_true = true_label_; 5730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *if_false = false_label_; 5740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen *fall_through = fall_through_; 57580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 57680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 57780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 5783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::DoTest(const TestContext* context) { 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(context->condition(), 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->true_label(), 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->false_label(), 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context->fall_through()); 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::AllocateModules(ZoneList<Declaration*>* declarations) { 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(scope_->is_global_scope()); 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < declarations->length(); i++) { 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ModuleDeclaration* declaration = declarations->at(i)->AsModuleDeclaration(); 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (declaration != NULL) { 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ModuleLiteral* module = declaration->module()->AsModuleLiteral(); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (module != NULL) { 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ Link nested modules"); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* scope = module->body()->scope(); 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Interface* interface = scope->interface(); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(interface->IsModule() && interface->IsFrozen()); 598d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch interface->Allocate(scope->module_var()->index()); 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up module context. 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(scope->interface()->Index() >= 0); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(Smi::FromInt(scope->interface()->Index())); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(scope->GetScopeInfo()); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallRuntime(Runtime::kPushModuleContext, 2); 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_register()); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateModules(scope->declarations()); 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop module context. 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update local stack frame context field. 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_register()); 616d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 617d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 618d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Modules have their own local scope, represented by their own context. 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Module instance objects have an accessor for every export that forwards 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// access to the respective slot from the module's context. (Exports that are 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modules themselves, however, are simple data properties.) 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All modules have a _hosting_ scope/context, which (currently) is the 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (innermost) enclosing global scope. To deal with recursion, nested modules 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// are hosted by the same scope as global ones. 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// For every (global or nested) module literal, the hosting context has an 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// internal slot that points directly to the respective module context. This 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// enables quick access to (statically resolved) module members by 2-dimensional 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// access through the hosting context. For example, 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// module A { 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// let x; 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// module B { let y; } 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// } 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// module C { let z; } 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// allocates contexts as follows: 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// [header| .A | .B | .C | A | C ] (global) 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// | | | 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// | | +-- [header| z ] (module) 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// | | 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// | +------- [header| y ] (module) 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// | 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// +------------ [header| x | B ] (module) 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Here, .A, .B, .C are the internal slots pointing to the hosted module 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// contexts, whereas A, B, C hold the actual instance objects (note that every 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// module context also points to the respective instance object through its 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// extension slot in the header). 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// To deal with arbitrary recursion and aliases between modules, 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// they are created and initialized in several stages. Each stage applies to 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// all modules in the hosting global scope, including nested ones. 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 1. Allocate: for each module _literal_, allocate the module contexts and 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// respective instance object and wire them up. This happens in the 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PushModuleContext runtime function, as generated by AllocateModules 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (invoked by VisitDeclarations in the hosting scope). 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 2. Bind: for each module _declaration_ (i.e. literals as well as aliases), 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// assign the respective instance object to respective local variables. This 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// happens in VisitModuleDeclaration, and uses the instance objects created 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// in the previous stage. 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// For each module _literal_, this phase also constructs a module descriptor 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// for the next stage. This happens in VisitModuleLiteral. 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3. Populate: invoke the DeclareModules runtime function to populate each 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// _instance_ object with accessors for it exports. This is generated by 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DeclareModules (invoked by VisitDeclarations in the hosting scope again), 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and uses the descriptors generated in the previous stage. 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 4. Initialize: execute the module bodies (and other code) in sequence. This 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// happens by the separate statements generated for module bodies. To reenter 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the module scopes properly, the parser inserted ModuleStatements. 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitDeclarations( 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Declaration*>* declarations) { 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> saved_modules = modules_; 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int saved_module_index = module_index_; 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Handle<Object> >* saved_globals = globals_; 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Handle<Object> > inner_globals(10, zone()); 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_ = &inner_globals; 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope_->num_modules() != 0) { 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This is a scope hosting modules. Allocate a descriptor array to pass 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the runtime for initialization. 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ Allocate modules"); 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(scope_->is_global_scope()); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch modules_ = 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED); 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch module_index_ = 0; 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate code for allocating all modules, including nested ones. 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The allocated contexts are stored in internal variables in this scope. 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateModules(declarations); 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstVisitor::VisitDeclarations(declarations); 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (scope_->num_modules() != 0) { 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initialize modules from descriptor array. 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(module_index_ == modules_->length()); 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeclareModules(modules_); 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch modules_ = saved_modules; 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch module_index_ = saved_module_index; 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!globals_->is_empty()) { 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Invoke the platform-dependent code generator to do the actual 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // declaration of the global functions and variables. 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> array = 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->NewFixedArray(globals_->length(), TENURED); 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < globals_->length(); ++i) 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->set(i, *globals_->at(i)); 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeclareGlobals(array); 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_ = saved_globals; 7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Block* block = module->body(); 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* saved_scope = scope(); 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_ = block->scope(); 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Interface* interface = scope_->interface(); 7333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ ModuleLiteral"); 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetStatementPosition(block); 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!modules_.is_null()); 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(module_index_ < modules_->length()); 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = module_index_++; 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up module context. 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(interface->Index() >= 0); 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(Smi::FromInt(interface->Index())); 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(Smi::FromInt(0)); 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallRuntime(Runtime::kPushModuleContext, 2); 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 7473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ Declarations"); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDeclarations(scope_->declarations()); 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Populate the module description. 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ModuleInfo> description = 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ModuleInfo::Create(isolate(), interface, scope_); 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch modules_->set(index, *description); 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_ = saved_scope; 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop module context. 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update local stack frame context field. 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) { 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Nothing to do. 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The instance object is resolved statically through the module's interface. 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitModulePath(ModulePath* module) { 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Nothing to do. 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The instance object is resolved statically through the module's interface. 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitModuleUrl(ModuleUrl* module) { 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(rossberg): dummy allocation for now. 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* scope = module->body()->scope(); 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Interface* interface = scope_->interface(); 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(interface->IsModule() && interface->IsFrozen()); 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!modules_.is_null()); 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(module_index_ < modules_->length()); 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch interface->Allocate(scope->module_var()->index()); 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = module_index_++; 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ModuleInfo> description = 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ModuleInfo::Create(isolate(), interface, scope_); 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch modules_->set(index, *description); 792d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 793d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 794d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 795589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochint FullCodeGenerator::DeclareGlobalsFlags() { 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(DeclareGlobalsStrictMode::is_valid(strict_mode())); 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DeclareGlobalsEvalFlag::encode(is_eval()) | 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeclareGlobalsNativeFlag::encode(is_native()) | 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeclareGlobalsStrictMode::encode(strict_mode()); 800589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 801589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 802589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 803d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 8043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, fun->start_position()); 805d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 806d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 807d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 808d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 8093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); 810d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 811d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 812d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 813d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) { 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info_->is_debug()) { 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeGenerator::RecordPositions(masm_, stmt->position()); 8163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the statement will be breakable without adding a debug break 8183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot. 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakableStatementChecker checker(zone()); 8203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch checker.Check(stmt); 8213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Record the statement position right here if the statement is not 8223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breakable. For breakable statements the actual recording of the 8233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // position will be postponed to the breakable code (typically an IC). 8243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool position_recorded = CodeGenerator::RecordPositions( 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm_, stmt->position(), !checker.is_breakable()); 8263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the position recording did record a new position generate a debug 8273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // break slot to make the statement breakable. 8283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (position_recorded) { 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugCodegen::GenerateSlot(masm_); 8307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 8313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 8327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 8337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 8347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitSuperReference(SuperReference* super) { 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::SetExpressionPosition(Expression* expr) { 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!info_->is_debug()) { 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeGenerator::RecordPositions(masm_, expr->position()); 8433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 8443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the expression will be breakable without adding a debug break 8453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot. 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakableStatementChecker checker(zone()); 8473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch checker.Check(expr); 8483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Record a statement position right here if the expression is not 8493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breakable. For breakable expressions the actual recording of the 8503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // position will be postponed to the breakable code (typically an IC). 8513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // NOTE this will record a statement position for something which might 8523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // not be a statement. As stepping in the debugger will only stop at 8533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // statement positions this is used for e.g. the condition expression of 8543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // a do while loop. 8553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool position_recorded = CodeGenerator::RecordPositions( 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm_, expr->position(), !checker.is_breakable()); 8573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // If the position recording did record a new position generate a debug 8583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // break slot to make the statement breakable. 8593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (position_recorded) { 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugCodegen::GenerateSlot(masm_); 8617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 8623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 863d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 864d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 865d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid FullCodeGenerator::SetSourcePosition(int pos) { 8673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (pos != RelocInfo::kNoPosition) { 868b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch masm_->positions_recorder()->RecordPosition(pos); 869d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 870d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 871d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 872d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 8730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// Lookup table for code generators for special runtime calls which are 8740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen// generated inline. 8750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 8760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen &FullCodeGenerator::Emit##Name, 877791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block 8780d5e116f6aee03185f237311a943491bb079a768Kristian Monsenconst FullCodeGenerator::InlineFunctionGenerator 8790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::kInlineFunctionGenerators[] = { 8800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 8810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen }; 8820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen#undef INLINE_FUNCTION_GENERATOR_ADDRESS 8830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8850d5e116f6aee03185f237311a943491bb079a768Kristian MonsenFullCodeGenerator::InlineFunctionGenerator 8860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) { 887b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int lookup_index = 888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction); 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(lookup_index >= 0); 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(static_cast<size_t>(lookup_index) < 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch arraysize(kInlineFunctionGenerators)); 892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return kInlineFunctionGenerators[lookup_index]; 8930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 8940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) { 8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Runtime::Function* function = expr->function(); 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function != NULL); 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(function->intrinsic_type == Runtime::INLINE); 9000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen InlineFunctionGenerator generator = 9010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen FindInlineFunctionGenerator(function->function_id); 9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ((*this).*(generator))(expr); 90380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 90480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 90580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) { 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* args = expr->arguments(); 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(args->length() == 2); 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::NEXT); 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitGeneratorThrow(CallRuntime* expr) { 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Expression*>* args = expr->arguments(); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(args->length() == 2); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitGeneratorResume(args->at(0), args->at(1), JSGeneratorObject::THROW); 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitDebugBreakInOptimizedCode(CallRuntime* expr) { 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context()->Plug(handle(Smi::FromInt(0), isolate())); 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 92580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 9263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch switch (expr->op()) { 92780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::COMMA: 9283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitComma(expr); 92980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::OR: 93080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen case Token::AND: 9313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitLogicalExpression(expr); 93280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen default: 9333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return VisitArithmeticExpression(expr); 93480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 9357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 9367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::VisitInDuplicateContext(Expression* expr) { 9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (context()->IsEffect()) { 9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForEffect(expr); 9413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (context()->IsAccumulatorValue()) { 9423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForAccumulatorValue(expr); 9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (context()->IsStackValue()) { 9443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForStackValue(expr); 9453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (context()->IsTest()) { 9463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const TestContext* test = TestContext::cast(context()); 9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitForControl(expr, test->true_label(), test->false_label(), 9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch test->fall_through()); 9493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 9513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitComma(BinaryOperation* expr) { 9543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, "[ Comma"); 9553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForEffect(expr->left()); 9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(expr->right()); 957d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 958d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 959d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 9603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { 9613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_logical_and = expr->op() == Token::AND; 9623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, is_logical_and ? "[ Logical AND" : "[ Logical OR"); 9633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* left = expr->left(); 9643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* right = expr->right(); 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId right_id = expr->RightId(); 9663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label done; 9670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 9683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (context()->IsTest()) { 9693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label eval_right; 9703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const TestContext* test = TestContext::cast(context()); 9713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 9723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &eval_right, test->false_label(), &eval_right); 9733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 9743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, test->true_label(), &eval_right, &eval_right); 9753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 9773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&eval_right); 9783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (context()->IsAccumulatorValue()) { 9803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(left); 9813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We want the value in the accumulator for the test, and on the stack in 9823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // case we need it. 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(result_register()); 9843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label discard, restore; 9853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 9863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &discard, &restore, &restore); 9873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 9883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &restore, &discard, &restore); 9893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&restore); 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(result_register()); 9923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ jmp(&done); 9933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&discard); 9943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Drop(1); 9953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 9963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (context()->IsStackValue()) { 9983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(left); 9993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We want the value in the accumulator for the test, and on the stack in 10003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // case we need it. 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(result_register()); 10023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label discard; 10033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 10043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &discard, &done, &discard); 10053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 10063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DoTest(left, &done, &discard, &discard); 10073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&discard); 10093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Drop(1); 10103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 10110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 10120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(context()->IsEffect()); 10143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label eval_right; 10153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (is_logical_and) { 10163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &eval_right, &done, &eval_right); 10173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 10183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForControl(left, &done, &eval_right, &eval_right); 10193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(right_id, NO_REGISTERS); 10213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&eval_right); 10220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 10233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(right); 10253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ bind(&done); 10260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 10270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 102880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 10293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 10303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Token::Value op = expr->op(); 10313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Comment cmnt(masm_, "[ ArithmeticExpression"); 10323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* left = expr->left(); 10333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Expression* right = expr->right(); 10343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OverwriteMode mode = 10353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch left->ResultOverwriteAllowed() 10363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ? OVERWRITE_LEFT 10373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE); 103880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 10393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForStackValue(left); 10403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch VisitForAccumulatorValue(right); 104180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 10423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SetSourcePosition(expr->position()); 10433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (ShouldInlineSmiCase(op)) { 10443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitInlineSmiBinaryOp(expr, op, mode, left, right); 10450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } else { 10463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmitBinaryOp(expr, op, mode); 10470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen } 10480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen} 10490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 10500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen 1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) { 1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Block"); 1053589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch NestedBlock nested_block(this, stmt); 1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 105669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Scope* saved_scope = scope(); 1057589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Push a block context when entering a block with block scoped variables. 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->scope() == NULL) { 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_ = stmt->scope(); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scope_->is_module_scope()); 106369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { Comment cmnt(masm_, "[ Extend block context"); 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(scope_->GetScopeInfo()); 106569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch PushFunctionArgumentForContextAllocation(); 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallRuntime(Runtime::kPushBlockContext, 2); 10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Replace the context stored in the frame. 106969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 107069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 107269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 107369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { Comment cmnt(masm_, "[ Declarations"); 107469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch VisitDeclarations(scope_->declarations()); 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrepareForBailoutForId(stmt->DeclsId(), NO_REGISTERS); 107669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 107769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1079d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitStatements(stmt->statements()); 108069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch scope_ = saved_scope; 1081589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch __ bind(nested_block.break_label()); 1082589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 1083589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Pop block context if necessary. 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stmt->scope() != NULL) { 1085589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1086589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Update local stack frame context field. 1087589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 1088589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch context_register()); 1089589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitModuleStatement(ModuleStatement* stmt) { 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ Module context"); 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(Smi::FromInt(stmt->proxy()->interface()->Index())); 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(Smi::FromInt(0)); 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ CallRuntime(Runtime::kPushModuleContext, 2); 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreToFrameField( 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StandardFrameConstants::kContextOffset, context_register()); 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* saved_scope = scope_; 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_ = stmt->body()->scope(); 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitStatements(stmt->body()->statements()); 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_ = saved_scope; 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update local stack frame context field. 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_register()); 1111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 1115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ExpressionStatement"); 1116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke VisitForEffect(stmt->expression()); 1118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ EmptyStatement"); 1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { 1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ IfStatement"); 1129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label then_part, else_part, done; 1131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 113280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (stmt->HasElseStatement()) { 113380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); 1134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 113580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 113680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 113780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ jmp(&done); 1138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 114080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&else_part); 114180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->else_statement()); 114280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } else { 114380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->condition(), &then_part, &done, &then_part); 1144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); 114580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen __ bind(&then_part); 114680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Visit(stmt->then_statement()); 1147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); 114980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 1150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 11513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); 1152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 1156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ContinueStatement"); 1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 116069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 1161db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When continuing, we clobber the unpredictable value in the accumulator 1162db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 1163db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 1164db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 1165db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsContinueTarget(stmt->target())) { 116769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 117069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (context_length > 0) { 117169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (context_length > 0) { 117269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 117369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch --context_length; 117469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 117569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 117669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 117769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 117969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ jmp(current->AsIteration()->continue_label()); 1180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 1184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ BreakStatement"); 1185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 118869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 1189db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // When breaking, we clobber the unpredictable value in the accumulator 1190db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // with one that's safe for GC. If we hit an exit from the try block of 1191db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // try...finally on our way out, we will unconditionally preserve the 1192db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // accumulator on the stack. 1193db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (!current->IsBreakTarget(stmt->target())) { 119569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 1196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 119869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (context_length > 0) { 119969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch while (context_length > 0) { 120069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 120169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch --context_length; 120269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 120369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 120469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch context_register()); 120569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 120769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ jmp(current->AsBreakable()->break_label()); 1208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitUnwindBeforeReturn() { 1212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke NestedStatement* current = nesting_stack_; 1213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int stack_depth = 0; 121469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_length = 0; 1215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke while (current != NULL) { 121669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch current = current->Exit(&stack_depth, &context_length); 1217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Drop(stack_depth); 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ ReturnStatement"); 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetStatementPosition(stmt); 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Expression* expr = stmt->expression(); 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForAccumulatorValue(expr); 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitUnwindBeforeReturn(); 12287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch EmitReturnSequence(); 1229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 123269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { 123369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Comment cmnt(masm_, "[ WithStatement"); 1234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 12360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(stmt->expression()); 12373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushFunctionArgumentForContextAllocation(); 12383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ CallRuntime(Runtime::kPushWithContext, 2); 123969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 124069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* saved_scope = scope(); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_ = stmt->scope(); 124369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { WithOrCatch body(this); 124469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Visit(stmt->statement()); 124569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_ = saved_scope; 124769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 124869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Pop context. 124969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 125069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Update local stack frame context field. 1251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 1252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 1256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DoWhileStatement"); 1257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label body, book_keeping; 1259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 126680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Record the position of the do while condition and make sure it is 126780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // possible to break on the condition. 126869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 1269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetExpressionPosition(stmt->cond()); 127180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &book_keeping, 127369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &book_keeping); 12757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check stack before looping. 1277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&book_keeping); 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitBackEdgeBookkeeping(stmt, &body); 1280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ jmp(&body); 1281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 128369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 1289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ WhileStatement"); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label loop, body; 1291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 1293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&loop); 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetExpressionPosition(stmt->cond()); 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForControl(stmt->cond(), 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &body, 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_statement.break_label(), 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &body); 1302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 130680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 130769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 1308f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitBackEdgeBookkeeping(stmt, &loop); 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ jmp(&loop); 1312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 131469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) { 1320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ ForStatement"); 1321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label test, body; 1322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Iteration loop_statement(this, stmt); 13243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set statement position for a break slot before entering the for-body. 13263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetStatementPosition(stmt); 13273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->init() != NULL) { 1329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->init()); 1330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke increment_loop_depth(); 1333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Emit the test at the bottom of the loop (even if empty). 1334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&test); 1335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&body); 1338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->body()); 1339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); 134169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.continue_label()); 1342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->next() != NULL) { 1343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->next()); 1344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 134680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Emit the statement position here as this is where the for 134780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // statement code starts. 13487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetStatementPosition(stmt); 1349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check stack before looping. 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitBackEdgeBookkeeping(stmt, &body); 1352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch __ bind(&test); 1354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (stmt->cond() != NULL) { 135580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(stmt->cond(), 135680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen &body, 135769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label(), 135869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch loop_statement.break_label()); 1359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 1360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&body); 1361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1362d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 136469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ bind(loop_statement.break_label()); 1365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke decrement_loop_depth(); 1366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryCatchStatement"); 1371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 13723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The try block adds a handler to the exception handler chain before 13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // entering, and removes it again when exiting normally. If an exception 13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is thrown during execution of the try block, the handler is consumed 13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // and control is passed to the catch block with the exception in the 13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result register. 13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label try_entry, handler_entry, exit; 13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&try_entry); 13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&handler_entry); 13813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Exception handler code, the exception is in the result register. 13833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Extend the context before executing the catch block. 13843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { Comment cmnt(masm_, "[ Extend catch context"); 13853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ Push(stmt->variable()->name()); 1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(result_register()); 13873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PushFunctionArgumentForContextAllocation(); 13883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch __ CallRuntime(Runtime::kPushCatchContext, 3); 13893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, 13903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context_register()); 1391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 13933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Scope* saved_scope = scope(); 13943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch scope_ = stmt->scope(); 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(scope_->declarations()->is_empty()); 13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { WithOrCatch catch_body(this); 139769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Visit(stmt->catch_block()); 139869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1399589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Restore the context. 1400589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LoadContextField(context_register(), Context::PREVIOUS_INDEX); 1401589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 14023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch scope_ = saved_scope; 14033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&exit); 1404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try block code. Sets up the exception handler chain. 14063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&try_entry); 14073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PushTryHandler(StackHandler::CATCH, stmt->index()); 14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { TryCatch try_body(this); 1409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PopTryHandler(); 14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&exit); 1413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ TryFinallyStatement"); 1418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 1419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Try finally is compiled by setting up a try-handler on the stack while 1420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // executing the try body, and removing it again afterwards. 1421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The try-finally construct can enter the finally block in three ways: 1423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1. By exiting the try-block normally. This removes the try-handler and 14243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // calls the finally block code before continuing. 1425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 2. By exiting the try-block with a function-local control flow transfer 1426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (break/continue/return). The site of the, e.g., break removes the 1427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // try handler and calls the finally block code before continuing 1428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // its outward control transfer. 14293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 3. By exiting the try-block with a thrown exception. 1430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // This can happen in nested function calls. It traverses the try-handler 1431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // chain and consumes the try-handler entry before jumping to the 1432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // handler code. The handler code then calls the finally-block before 1433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // rethrowing the exception. 1434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // 1435d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The finally block must assume a return address on top of the stack 1436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // (or in the link register on ARM chips) and a value (return value or 1437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // exception) in the result register (rax/eax/r0), both of which must 1438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // be preserved. The return address isn't GC-safe, so it should be 1439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // cooked before GC. 14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label try_entry, handler_entry, finally_entry; 14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Jump to try-handler setup and try-block code. 14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&try_entry); 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&handler_entry); 14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos())); 14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Exception handler code. This code is only executed when an exception 14473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is thrown. The exception is in the result register, and must be 14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // preserved by the finally block. Call the finally block and then 14493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // rethrow the exception if it returns. 14503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Call(&finally_entry); 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(result_register()); 14523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntime(Runtime::kReThrow, 1); 1453d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Finally block implementation. 1455d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&finally_entry); 14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnterFinallyBlock(); 14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { Finally finally_body(this); 1458d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->finally_block()); 1459d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 14603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExitFinallyBlock(); // Return to the calling code. 1461d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 14623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up try handler. 14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&try_entry); 14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PushTryHandler(StackHandler::FINALLY, stmt->index()); 14653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { TryFinally try_body(this, &finally_entry); 1466d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Visit(stmt->try_block()); 1467d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PopTryHandler(); 1469db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch // Execute the finally block on the way out. Clobber the unpredictable 14703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // value in the result register with one that's safe for GC because the 14713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // finally block will unconditionally preserve the result register on the 14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // stack. 1473db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch ClearAccumulator(); 1474d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ Call(&finally_entry); 1475d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1476d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1477d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1478d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1479d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ DebuggerStatement"); 1480d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke SetStatementPosition(stmt); 14814515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 1482402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu __ DebugBreak(); 1483d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Ignore the return value. 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitCaseClause(CaseClause* clause) { 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 1491d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1492d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1493d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1494d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) { 1495d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Conditional"); 1496d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Label true_case, false_case, done; 149780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen VisitForControl(expr->condition(), &true_case, &false_case, &true_case); 1498d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1499b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); 1500d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&true_case); 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetExpressionPosition(expr->then_expression()); 1502f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (context()->IsTest()) { 1503f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const TestContext* for_test = TestContext::cast(context()); 1504f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch VisitForControl(expr->then_expression(), 1505f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->true_label(), 1506f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for_test->false_label(), 1507f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch NULL); 1508f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 15093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(expr->then_expression()); 1510d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ jmp(&done); 1511d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1512d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); 1514d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&false_case); 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetExpressionPosition(expr->else_expression()); 15163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch VisitInDuplicateContext(expr->else_expression()); 1517d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // If control flow falls through Visit, merge it with true case here. 15180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!context()->IsTest()) { 1519d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ bind(&done); 1520d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1521d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1522d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1523d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1524d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) { 1525d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Literal"); 1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context()->Plug(expr->value()); 1527d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1528d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1529d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1530f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1531f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Comment cmnt(masm_, "[ FunctionLiteral"); 1532f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1533f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke // Build the function boilerplate and instantiate it. 1534f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke Handle<SharedFunctionInfo> function_info = 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Compiler::BuildFunctionInfo(expr, script(), info_); 1536f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (function_info.is_null()) { 1537f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SetStackOverflow(); 1538f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return; 1539f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 15408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang EmitNewClosure(function_info, expr->pretenure()); 1541f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1542f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1543f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitClassLiteral(ClassLiteral* expr) { 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(arv): Implement 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ ClassLiteral"); 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->extends() != NULL) { 1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitForEffect(expr->extends()); 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context()->Plug(isolate()->factory()->undefined_value()); 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitNativeFunctionLiteral( 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NativeFunctionLiteral* expr) { 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Comment cmnt(masm_, "[ NativeFunctionLiteral"); 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the function template for the native function. 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> name = expr->name(); 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> fun_template = 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expr->extension()->GetNativeFunctionTemplate( 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<v8::Isolate*>(isolate()), v8::Utils::ToLocal(name)); 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!fun_template.IsEmpty()); 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Instantiate the function and create a shared function info from it. 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int literals = fun->NumberOfLiterals(); 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = Handle<Code>(fun->shared()->code()); 1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); 1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<SharedFunctionInfo> shared = 1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->NewSharedFunctionInfo( 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name, literals, FunctionKind::kNormalFunction, code, 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ScopeInfo>(fun->shared()->scope_info()), 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<TypeFeedbackVector>(fun->shared()->feedback_vector())); 1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared->set_construct_stub(*construct_stub); 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the function data to the shared function info. 1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared->set_function_data(fun->shared()->function_data()); 1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parameters = fun->shared()->formal_parameter_count(); 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared->set_formal_parameter_count(parameters); 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitNewClosure(shared, false); 1583f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1584f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1585f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1586d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) { 1587d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Comment cmnt(masm_, "[ Throw"); 15880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen VisitForStackValue(expr->exception()); 1589d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ CallRuntime(Runtime::kThrow, 1); 1590d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Never returns here. 1591d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1592d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1593d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 159469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochFullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit( 159569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int* stack_depth, 159669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int* context_length) { 1597d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // The macros used here must preserve the result register. 159869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch __ Drop(*stack_depth); 1599d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke __ PopTryHandler(); 160069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch *stack_depth = 0; 160169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return previous_; 1602d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1603d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 160480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 16053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) { 16063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Expression* sub_expr; 16073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<String> check; 16083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 16093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLiteralCompareTypeof(expr, sub_expr, check); 16103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return true; 16113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { 16143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue); 16153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 16163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 16173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 16183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expr->IsLiteralCompareNull(&sub_expr)) { 16193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLiteralCompareNil(expr, sub_expr, kNullValue); 16203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return true; 16213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 16223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 16233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 16243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 16253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 16263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BackEdgeTable::Patch(Isolate* isolate, Code* unoptimized) { 1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* patch = isolate->builtins()->builtin(Builtins::kOnStackReplacement); 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Increment loop nesting level by one and iterate over the back edge table 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to find the matching loops to patch the interrupt 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // call to an unconditional call to the replacement code. 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level() + 1; 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (loop_nesting_level > Code::kMaxLoopNestingMarker) return; 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BackEdgeTable back_edges(unoptimized, &no_gc); 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (uint32_t i = 0; i < back_edges.length(); i++) { 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (static_cast<int>(back_edges.loop_depth(i)) == loop_nesting_level) { 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(INTERRUPT, GetBackEdgeState(isolate, 1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unoptimized, 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch back_edges.pc(i))); 1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PatchAt(unoptimized, back_edges.pc(i), ON_STACK_REPLACEMENT, patch); 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unoptimized->set_allow_osr_at_loop_nesting_level(loop_nesting_level); 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Verify(isolate, unoptimized)); 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BackEdgeTable::Revert(Isolate* isolate, Code* unoptimized) { 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* patch = isolate->builtins()->builtin(Builtins::kInterruptCheck); 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over the back edge table and revert the patched interrupt calls. 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level(); 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BackEdgeTable back_edges(unoptimized, &no_gc); 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (uint32_t i = 0; i < back_edges.length(); i++) { 1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (static_cast<int>(back_edges.loop_depth(i)) <= loop_nesting_level) { 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(INTERRUPT, GetBackEdgeState(isolate, 1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unoptimized, 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch back_edges.pc(i))); 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PatchAt(unoptimized, back_edges.pc(i), INTERRUPT, patch); 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unoptimized->set_allow_osr_at_loop_nesting_level(0); 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assert that none of the back edges are patched anymore. 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Verify(isolate, unoptimized)); 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BackEdgeTable::AddStackCheck(Handle<Code> code, uint32_t pc_offset) { 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = code->GetIsolate(); 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address pc = code->instruction_start() + pc_offset; 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* patch = isolate->builtins()->builtin(Builtins::kOsrAfterStackCheck); 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PatchAt(*code, pc, OSR_AFTER_STACK_CHECK, patch); 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BackEdgeTable::RemoveStackCheck(Handle<Code> code, uint32_t pc_offset) { 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = code->GetIsolate(); 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address pc = code->instruction_start() + pc_offset; 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (OSR_AFTER_STACK_CHECK == GetBackEdgeState(isolate, *code, pc)) { 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* patch = isolate->builtins()->builtin(Builtins::kOnStackReplacement); 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PatchAt(*code, pc, ON_STACK_REPLACEMENT, patch); 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool BackEdgeTable::Verify(Isolate* isolate, Code* unoptimized) { 1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_nesting_level = unoptimized->allow_osr_at_loop_nesting_level(); 1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BackEdgeTable back_edges(unoptimized, &no_gc); 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (uint32_t i = 0; i < back_edges.length(); i++) { 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t loop_depth = back_edges.loop_depth(i); 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LE(static_cast<int>(loop_depth), Code::kMaxLoopNestingMarker); 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assert that all back edges for shallower loops (and only those) 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // have already been patched. 1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ((static_cast<int>(loop_depth) <= loop_nesting_level), 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GetBackEdgeState(isolate, 1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unoptimized, 1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch back_edges.pc(i)) != INTERRUPT); 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // DEBUG 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __ 1717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} } // namespace v8::internal 1720