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