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