full-codegen.cc revision 7f4d5bd8c03935e2c0cd412e561b8fc5a6a880ae
1d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Copyright 2009 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
30d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "codegen-inl.h"
31d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "compiler.h"
32d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "full-codegen.h"
336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "scopes.h"
34d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "stub-cache.h"
35d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "debug.h"
36402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#include "liveedit.h"
37d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 {
39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal {
40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
41d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define BAILOUT(reason)                         \
42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  do {                                          \
43d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (FLAG_trace_bailout) {                   \
44d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      PrintF("%s\n", reason);                   \
45d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }                                           \
46d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    has_supported_syntax_ = false;              \
47d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    return;                                     \
48d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } while (false)
49d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
50d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
51d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define CHECK_BAILOUT                           \
52d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  do {                                          \
53d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (!has_supported_syntax_) return;         \
54d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } while (false)
55d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
56d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
57d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) {
58d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Scope* scope = fun->scope();
59d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitDeclarations(scope->declarations());
60d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
61d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
62d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitStatements(fun->body());
63d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
64d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
65d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
66d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclarations(
67d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ZoneList<Declaration*>* decls) {
68d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < decls->length(); i++) {
69d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(decls->at(i));
70d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
71d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
72d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
73d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
74d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
75d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
76d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0, len = stmts->length(); i < len; i++) {
77d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmts->at(i));
78d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
79d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
80d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
81d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
82d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
83d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) {
84d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Property* prop = decl->proxy()->AsProperty();
85d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (prop != NULL) {
86d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
87d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
88d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
89d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
90d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (decl->fun() != NULL) {
91d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(decl->fun());
92d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
93d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
94d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
95d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
96d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBlock(Block* stmt) {
97d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitStatements(stmt->statements());
98d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
99d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitExpressionStatement(
102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ExpressionStatement* stmt) {
103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->expression());
104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) {
108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) {
113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->condition());
114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->then_statement());
116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->else_statement());
118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) {
122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) {
127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) {
132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->expression());
133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithEnterStatement(
137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    WithEnterStatement* stmt) {
138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->expression());
139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) {
143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) {
148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  BAILOUT("SwitchStatement");
149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->cond());
154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) {
160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->cond());
161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) {
167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (!FLAG_always_full_compiler) BAILOUT("ForStatement");
168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->init() != NULL) {
169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->init());
170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->cond() != NULL) {
173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->cond());
174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->next() != NULL) {
178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->next());
180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) {
185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  BAILOUT("ForInStatement");
186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) {
190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->try_block());
191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->catch_block());
193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryFinallyStatement(
197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    TryFinallyStatement* stmt) {
198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->try_block());
199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->finally_block());
201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDebuggerStatement(
205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DebuggerStatement* stmt) {
206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid FullCodeGenSyntaxChecker::VisitSharedFunctionInfoLiteral(
2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    SharedFunctionInfoLiteral* expr) {
2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  BAILOUT("SharedFunctionInfoLiteral");
218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitConditional(Conditional* expr) {
222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->condition());
223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->then_expression());
225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->else_expression());
227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSlot(Slot* expr) {
231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  UNREACHABLE();
232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) {
236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitLiteral(Literal* expr) {
241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) {
251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0, len = properties->length(); i < len; i++) {
254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ObjectLiteral::Property* property = properties->at(i);
255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (property->IsCompileTimeValue()) continue;
256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(property->key());
257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(property->value());
259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) {
265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<Expression*>* subexprs = expr->values();
266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0, len = subexprs->length(); i < len; i++) {
267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Expression* subexpr = subexprs->at(i);
268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (subexpr->AsLiteral() != NULL) continue;
269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(subexpr);
271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
274d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCatchExtensionObject(
277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CatchExtensionObject* expr) {
278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->key());
279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->value());
281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) {
285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Token::Value op = expr->op();
286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (op == Token::INIT_CONST) BAILOUT("initialize constant");
287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Variable* var = expr->target()->AsVariableProxy()->AsVariable();
289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Property* prop = expr->target()->AsProperty();
290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ASSERT(var == NULL || prop == NULL);
291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (var != NULL) {
292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (var->mode() == Variable::CONST) BAILOUT("Assignment to const");
293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // All other variables are supported.
294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (prop != NULL) {
295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // This is a throw reference error.
301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("non-variable/non-property assignment");
302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->value());
305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->exception());
310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitProperty(Property* expr) {
314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->obj());
315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->key());
317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCall(Call* expr) {
321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Expression* fun = expr->expression();
322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<Expression*>* args = expr->arguments();
323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Variable* var = fun->AsVariableProxy()->AsVariable();
324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check for supported calls
326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (var != NULL && var->is_possibly_eval()) {
327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("call to the identifier 'eval'");
328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (var != NULL && !var->is_this() && var->is_global()) {
329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Calls to global variables are supported.
330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (var != NULL && var->slot() != NULL &&
331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke             var->slot()->type() == Slot::LOOKUP) {
332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("call to a lookup slot");
333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (fun->AsProperty() != NULL) {
334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Property* prop = fun->AsProperty();
335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
340d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Otherwise the call is supported if the function expression is.
341d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(fun);
342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check all arguments to the call.
344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < args->length(); i++) {
345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(args->at(i));
346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->expression());
353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<Expression*>* args = expr->arguments();
355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check all arguments to the call
356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < args->length(); i++) {
357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(args->at(i));
358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
362d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
363d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check for inline runtime call
365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (expr->name()->Get(0) == '_' &&
366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("inlined runtime call");
368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check all arguments to the call.  (Relies on TEMP meaning STACK.)
370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < expr->arguments()->length(); i++) {
371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(expr->arguments()->at(i));
372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  switch (expr->op()) {
379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::ADD:
3804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    case Token::BIT_NOT:
381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::NOT:
3824515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    case Token::SUB:
383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::TYPEOF:
384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::VOID:
385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Visit(expr->expression());
386d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
387d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::DELETE:
388d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      BAILOUT("UnaryOperation: DELETE");
389d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    default:
390d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      UNREACHABLE();
391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
393d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
395d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
396d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
397d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Property* prop = expr->expression()->AsProperty();
398d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ASSERT(var == NULL || prop == NULL);
399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (var != NULL) {
400d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // All global variables are supported.
401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (!var->is_global()) {
402d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      ASSERT(var->slot() != NULL);
403d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Slot::Type type = var->slot()->type();
404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      if (type == Slot::LOOKUP) {
405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        BAILOUT("CountOperation with lookup slot");
406d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      }
407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (prop != NULL) {
409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // This is a throw reference error.
415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("CountOperation non-variable/non-property expression");
416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->left());
422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->right());
424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->left());
429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->right());
431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
435d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef BAILOUT
439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef CHECK_BAILOUT
440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
4427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Statement* stmt) {
4437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt);
4447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::Check(Expression* expr) {
4487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr);
4497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDeclaration(Declaration* decl) {
4537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBlock(Block* stmt) {
4577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitExpressionStatement(
4617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    ExpressionStatement* stmt) {
4627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Check if expression is breakable.
4637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt->expression());
4647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
4687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
4727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // If the condition is breakable the if statement is breakable.
4737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt->condition());
4747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitContinueStatement(
4787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    ContinueStatement* stmt) {
4797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
4837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
4877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Return is breakable if the expression is.
4887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt->expression());
4897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWithEnterStatement(
4937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    WithEnterStatement* stmt) {
4947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt->expression());
4957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
4967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWithExitStatement(
4997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    WithExitStatement* stmt) {
5007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
5047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Switch statements breakable if the tag expression is.
5057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt->tag());
5067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
5107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark do while as breakable to avoid adding a break slot in front of it.
5117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  is_breakable_ = true;
5127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
5167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark while statements breakable if the condition expression is.
5177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt->cond());
5187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
5227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark for statements breakable if the condition expression is.
5237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (stmt->cond() != NULL) {
5247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    Visit(stmt->cond());
5257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
5267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
5307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark for in statements breakable if the enumerable expression is.
5317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(stmt->enumerable());
5327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryCatchStatement(
5367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    TryCatchStatement* stmt) {
5377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark try catch as breakable to avoid adding a break slot in front of it.
5387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  is_breakable_ = true;
5397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitTryFinallyStatement(
5437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    TryFinallyStatement* stmt) {
5447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Mark try finally as breakable to avoid adding a break slot in front of it.
5457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  is_breakable_ = true;
5467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitDebuggerStatement(
5507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    DebuggerStatement* stmt) {
5517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The debugger statement is breakable.
5527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  is_breakable_ = true;
5537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
5577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSharedFunctionInfoLiteral(
5617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    SharedFunctionInfoLiteral* expr) {
5627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitConditional(Conditional* expr) {
5667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitSlot(Slot* expr) {
5707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
5747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitLiteral(Literal* expr) {
5787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
5827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
5867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
5907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCatchExtensionObject(
5947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CatchExtensionObject* expr) {
5957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
5967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitAssignment(Assignment* expr) {
5997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // If assigning to a property (including a global property) the assignment is
6007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // breakable.
6017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Variable* var = expr->target()->AsVariableProxy()->AsVariable();
6027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Property* prop = expr->target()->AsProperty();
6037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (prop != NULL || (var != NULL && var->is_global())) {
6047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    is_breakable_ = true;
6057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    return;
6067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
6077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Otherwise the assignment is breakable if the assigned value is.
6097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->value());
6107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThrow(Throw* expr) {
6147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Throw is breakable if the expression is.
6157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->exception());
6167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitProperty(Property* expr) {
6207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Property load is breakable.
6217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  is_breakable_ = true;
6227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCall(Call* expr) {
6267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Function calls both through IC and call stub are breakable.
6277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  is_breakable_ = true;
6287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallNew(CallNew* expr) {
6327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Function calls through new are breakable.
6337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  is_breakable_ = true;
6347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
6387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
6427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->expression());
6437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
6477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->expression());
6487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
6527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->left());
6537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->right());
6547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
6587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->left());
6597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Visit(expr->right());
6607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
6647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
6657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
667d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm())
668d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
6693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuHandle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
6703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Script> script = info->script();
671d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (!script->IsUndefined() && !script->source()->IsUndefined()) {
672d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    int len = String::cast(script->source())->length();
673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Counters::total_full_codegen_source_size.Increment(len);
674d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
6753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  CodeGenerator::MakeCodePrologue(info);
676d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  const int kInitialBufferSize = 4 * KB;
677d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  MacroAssembler masm(NULL, kInitialBufferSize);
678402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
6793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  FullCodeGenerator cgen(&masm);
6803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  cgen.Generate(info, PRIMARY);
681d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (cgen.HasStackOverflow()) {
682d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT(!Top::has_pending_exception());
683d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    return Handle<Code>::null();
684d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
685d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
6866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
687d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
688d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
689d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
690d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::SlotOffset(Slot* slot) {
691d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ASSERT(slot != NULL);
692d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Offset is negative because higher indexes are at lower addresses.
693d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int offset = -slot->index() * kPointerSize;
694d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Adjust by a (parameter or local) base offset.
695d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  switch (slot->type()) {
696d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::PARAMETER:
6973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      offset += (scope()->num_parameters() + 1) * kPointerSize;
698d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
699d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::LOCAL:
700d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      offset += JavaScriptFrameConstants::kLocal0Offset;
701d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
702d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::CONTEXT:
703d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::LOOKUP:
704d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      UNREACHABLE();
705d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
706d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return offset;
707d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
708d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
709d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
710d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDeclarations(
711d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ZoneList<Declaration*>* declarations) {
712d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int length = declarations->length();
713d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int globals = 0;
714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < length; i++) {
715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Declaration* decl = declarations->at(i);
716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Variable* var = decl->proxy()->var();
717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Slot* slot = var->slot();
718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // If it was not possible to allocate the variable at compile
720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // time, we need to "declare" it at runtime to make sure it
721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // actually exists in the local context.
722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      VisitDeclaration(decl);
724d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    } else {
725d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Count global variables and functions for later processing
726d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      globals++;
727d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
728d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
729d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
730d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Compute array of global variable and function declarations.
731d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Do nothing in case of no declared global functions or variables.
732d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (globals > 0) {
733d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED);
734d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    for (int j = 0, i = 0; i < length; i++) {
735d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Declaration* decl = declarations->at(i);
736d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Variable* var = decl->proxy()->var();
737d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Slot* slot = var->slot();
738d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
739d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) {
740d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        array->set(j++, *(var->name()));
741d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        if (decl->fun() == NULL) {
742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          if (var->mode() == Variable::CONST) {
743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke            // In case this is const property use the hole.
744d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke            array->set_the_hole(j++);
745d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          } else {
746d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke            array->set_undefined(j++);
747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          }
748d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        } else {
7496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          Handle<SharedFunctionInfo> function =
7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block              Compiler::BuildFunctionInfo(decl->fun(), script(), this);
751d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          // Check for stack-overflow exception.
752d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          if (HasStackOverflow()) return;
753d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          array->set(j++, *function);
754d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        }
755d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      }
756d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
757d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Invoke the platform-dependent code generator to do the actual
758d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // declaration the global variables and functions.
759d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DeclareGlobals(array);
760d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
761d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
762d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
763d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
764d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
765d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
766d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, fun->start_position());
767d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
769d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
771d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
772d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, fun->end_position());
774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
777d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
778d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) {
779d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
7807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT
7817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    if (!Debugger::IsDebuggerActive()) {
7827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
7837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    } else {
7847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // Check if the statement will be breakable without adding a debug break
7857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // slot.
7867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      BreakableStatementChecker checker;
7877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      checker.Check(stmt);
7887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // Record the statement position right here if the statement is not
7897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // breakable. For breakable statements the actual recording of the
7907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // position will be postponed to the breakable code (typically an IC).
7917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      bool position_recorded = CodeGenerator::RecordPositions(
7927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch          masm_, stmt->statement_pos(), !checker.is_breakable());
7937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // If the position recording did record a new position generate a debug
7947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // break slot to make the statement breakable.
7957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      if (position_recorded) {
7967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        Debug::GenerateSlot(masm_);
7977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      }
7987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
7997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else
800d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
8017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif
8027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
8037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
8047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
8057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
8067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) {
8077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (FLAG_debug_info) {
8087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#ifdef ENABLE_DEBUGGER_SUPPORT
8097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    if (!Debugger::IsDebuggerActive()) {
8107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      CodeGenerator::RecordPositions(masm_, pos);
8117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    } else {
8127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // Check if the expression will be breakable without adding a debug break
8137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // slot.
8147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      BreakableStatementChecker checker;
8157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      checker.Check(expr);
8167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // Record a statement position right here if the expression is not
8177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // breakable. For breakable expressions the actual recording of the
8187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // position will be postponed to the breakable code (typically an IC).
8197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // NOTE this will record a statement position for something which might
8207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // not be a statement. As stepping in the debugger will only stop at
8217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // statement positions this is used for e.g. the condition expression of
8227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // a do while loop.
8237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      bool position_recorded = CodeGenerator::RecordPositions(
8247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch          masm_, pos, !checker.is_breakable());
8257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // If the position recording did record a new position generate a debug
8267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      // break slot to make the statement breakable.
8277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      if (position_recorded) {
8287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch        Debug::GenerateSlot(masm_);
8297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      }
8307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    }
8317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#else
8327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CodeGenerator::RecordPositions(masm_, pos);
8337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#endif
834d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
835d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
836d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
837d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
838d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(int pos) {
839d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
840d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, pos);
841d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
842d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
843d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
844d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
845d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetSourcePosition(int pos) {
846d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
847d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    masm_->RecordPosition(pos);
848d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
849d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
850d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
851d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
8527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
8537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Handle<String> name = expr->name();
8547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (strcmp("_IsSmi", *name->ToCString()) == 0) {
8557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsSmi(expr->arguments());
8567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_IsNonNegativeSmi", *name->ToCString()) == 0) {
8577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsNonNegativeSmi(expr->arguments());
8587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_IsObject", *name->ToCString()) == 0) {
8597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsObject(expr->arguments());
8607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_IsUndetectableObject", *name->ToCString()) == 0) {
8617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsUndetectableObject(expr->arguments());
8627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_IsFunction", *name->ToCString()) == 0) {
8637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsFunction(expr->arguments());
8647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_IsArray", *name->ToCString()) == 0) {
8657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsArray(expr->arguments());
8667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_IsRegExp", *name->ToCString()) == 0) {
8677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsRegExp(expr->arguments());
8687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_IsConstructCall", *name->ToCString()) == 0) {
8697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitIsConstructCall(expr->arguments());
8707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_ObjectEquals", *name->ToCString()) == 0) {
8717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitObjectEquals(expr->arguments());
8727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_Arguments", *name->ToCString()) == 0) {
8737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitArguments(expr->arguments());
8747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_ArgumentsLength", *name->ToCString()) == 0) {
8757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitArgumentsLength(expr->arguments());
8767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_ClassOf", *name->ToCString()) == 0) {
8777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitClassOf(expr->arguments());
8787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_Log", *name->ToCString()) == 0) {
8797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitLog(expr->arguments());
8807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_RandomHeapNumber", *name->ToCString()) == 0) {
8817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitRandomHeapNumber(expr->arguments());
8827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_SubString", *name->ToCString()) == 0) {
8837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitSubString(expr->arguments());
8847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_RegExpExec", *name->ToCString()) == 0) {
8857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitRegExpExec(expr->arguments());
8867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_ValueOf", *name->ToCString()) == 0) {
8877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitValueOf(expr->arguments());
8887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_SetValueOf", *name->ToCString()) == 0) {
8897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitSetValueOf(expr->arguments());
8907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_NumberToString", *name->ToCString()) == 0) {
8917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitNumberToString(expr->arguments());
8927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_StringCharFromCode", *name->ToCString()) == 0) {
8937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitStringCharFromCode(expr->arguments());
8947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_StringCharCodeAt", *name->ToCString()) == 0) {
8957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitStringCharCodeAt(expr->arguments());
8967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_StringCharAt", *name->ToCString()) == 0) {
8977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitStringCharAt(expr->arguments());
8987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_StringAdd", *name->ToCString()) == 0) {
8997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitStringAdd(expr->arguments());
9007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_StringCompare", *name->ToCString()) == 0) {
9017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitStringCompare(expr->arguments());
9027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_MathPow", *name->ToCString()) == 0) {
9037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitMathPow(expr->arguments());
9047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_MathSin", *name->ToCString()) == 0) {
9057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitMathSin(expr->arguments());
9067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_MathCos", *name->ToCString()) == 0) {
9077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitMathCos(expr->arguments());
9087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_MathSqrt", *name->ToCString()) == 0) {
9097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitMathSqrt(expr->arguments());
9107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_CallFunction", *name->ToCString()) == 0) {
9117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitCallFunction(expr->arguments());
9127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_RegExpConstructResult", *name->ToCString()) == 0) {
9137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitRegExpConstructResult(expr->arguments());
9147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_SwapElements", *name->ToCString()) == 0) {
9157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitSwapElements(expr->arguments());
9167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (strcmp("_GetFromCache", *name->ToCString()) == 0) {
9177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    EmitGetFromCache(expr->arguments());
9187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
9197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    UNREACHABLE();
9207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
9217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
9227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
9237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label eval_right, done;
926d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
927d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Set up the appropriate context for the left subexpression based
928d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // on the operation and our own context.  Initially assume we can
929d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // inherit both true and false labels from our context.
930d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (expr->op() == Token::OR) {
931d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    switch (context_) {
932d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kUninitialized:
933d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        UNREACHABLE();
934d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kEffect:
935d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &done, &eval_right);
936d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
937d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValue:
938d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForValueControl(expr->left(),
939d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
940d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &done,
941d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right);
942d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
943d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTest:
944d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), true_label_, &eval_right);
945d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
946d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValueTest:
947d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForValueControl(expr->left(),
948d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
949d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             true_label_,
950d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right);
951d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
952d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTestValue:
953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), true_label_, &eval_right);
954d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
955d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
956d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
957d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_EQ(Token::AND, expr->op());
958d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    switch (context_) {
959d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kUninitialized:
960d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        UNREACHABLE();
961d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kEffect:
962d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &eval_right, &done);
963d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
964d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValue:
965d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControlValue(expr->left(),
966d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right,
968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &done);
969d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
970d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTest:
971d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &eval_right, false_label_);
972d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
973d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValueTest:
974d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &eval_right, false_label_);
975d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
976d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTestValue:
977d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControlValue(expr->left(),
978d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
979d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right,
980d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             false_label_);
981d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
982d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
983d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
984d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
985d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&eval_right);
986d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->right());
987d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
988d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&done);
989d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
990d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
991d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
992d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) {
993d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Block");
994d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Breakable nested_statement(this, stmt);
995d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
996d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitStatements(stmt->statements());
997d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(nested_statement.break_target());
998d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
999d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1000d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1001d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
1002d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ ExpressionStatement");
1003d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1004d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForEffect(stmt->expression());
1005d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1006d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1007d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1008d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
1009d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ EmptyStatement");
1010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1012d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1013d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1014d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
1015d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ IfStatement");
1016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1017d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label then_part, else_part, done;
1018d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1019d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Do not worry about optimizing for empty then or else bodies.
1020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(stmt->condition(), &then_part, &else_part);
1021d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&then_part);
1023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->then_statement());
1024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&done);
1025d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1026d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&else_part);
1027d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->else_statement());
1028d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1029d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&done);
1030d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1031d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1032d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1033d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
1034d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_,  "[ ContinueStatement");
1035d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1036d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  NestedStatement* current = nesting_stack_;
1037d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int stack_depth = 0;
1038d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  while (!current->IsContinueTarget(stmt->target())) {
1039d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    stack_depth = current->Exit(stack_depth);
1040d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    current = current->outer();
1041d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1042d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
1043d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1044d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration* loop = current->AsIteration();
1045d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(loop->continue_target());
1046d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1047d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1048d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1049d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
1050d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_,  "[ BreakStatement");
1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  NestedStatement* current = nesting_stack_;
1053d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int stack_depth = 0;
1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  while (!current->IsBreakTarget(stmt->target())) {
1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    stack_depth = current->Exit(stack_depth);
1056d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    current = current->outer();
1057d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1058d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
1059d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1060d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Breakable* target = current->AsBreakable();
1061d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(target->break_target());
1062d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1063d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1064d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1065d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
1066d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ ReturnStatement");
1067d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1068d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Expression* expr = stmt->expression();
1069d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr, kAccumulator);
1070d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1071d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Exit all nested statements.
1072d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  NestedStatement* current = nesting_stack_;
1073d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int stack_depth = 0;
1074d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  while (current != NULL) {
1075d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    stack_depth = current->Exit(stack_depth);
1076d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    current = current->outer();
1077d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1078d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
1079d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
10807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  EmitReturnSequence();
1081d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1082d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1083d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1084d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
1085d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ WithEnterStatement");
1086d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1087d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1088d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(stmt->expression(), kStack);
1089d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->is_catch_block()) {
1090d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ CallRuntime(Runtime::kPushCatchContext, 1);
1091d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
1092d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ CallRuntime(Runtime::kPushContext, 1);
1093d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1094d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Both runtime calls return the new context in both the context and the
1095d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // result registers.
1096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Update local stack frame context field.
1098d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1099d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
1103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ WithExitStatement");
1104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Pop context.
1107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Update local stack frame context field.
1109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ DoWhileStatement");
1115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label body, stack_limit_hit, stack_check_success;
1117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration loop_statement(this, stmt);
1119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  increment_loop_depth();
1120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&body);
1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check stack before looping.
1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ StackLimitCheck(&stack_limit_hit);
1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_check_success);
1127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.continue_target());
11297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
11307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Record the position of the do while condition and make sure it is possible
11317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // to break on the condition.
11327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  SetExpressionPosition(stmt->cond(), stmt->condition_position());
11337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(stmt->cond(), &body, loop_statement.break_target());
1135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_limit_hit);
1137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StackCheckStub stack_stub;
1138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallStub(&stack_stub);
1139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&stack_check_success);
1140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.break_target());
1142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  decrement_loop_depth();
1144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ WhileStatement");
1149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label body, stack_limit_hit, stack_check_success;
1150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration loop_statement(this, stmt);
1152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  increment_loop_depth();
1153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Emit the test at the bottom of the loop.
1155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(loop_statement.continue_target());
1156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&body);
1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
1159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.continue_target());
11617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Emit the statement position here as this is where the while statement code
11627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // starts.
11637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  SetStatementPosition(stmt);
1164f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check stack before looping.
1166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ StackLimitCheck(&stack_limit_hit);
1167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_check_success);
1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(stmt->cond(), &body, loop_statement.break_target());
1170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_limit_hit);
1172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StackCheckStub stack_stub;
1173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallStub(&stack_stub);
1174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&stack_check_success);
1175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.break_target());
1177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  decrement_loop_depth();
1178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ ForStatement");
1183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label test, body, stack_limit_hit, stack_check_success;
1184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration loop_statement(this, stmt);
1186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->init() != NULL) {
1187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->init());
1188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  increment_loop_depth();
1191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Emit the test at the bottom of the loop (even if empty).
1192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&test);
1193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&body);
1195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
1196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.continue_target());
1198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->next() != NULL) {
1201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->next());
1202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&test);
12057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Emit the statement position here as this is where the for statement code
12067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // starts.
12077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  SetStatementPosition(stmt);
1208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check stack before looping.
1210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ StackLimitCheck(&stack_limit_hit);
1211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_check_success);
1212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->cond() != NULL) {
1214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    VisitForControl(stmt->cond(), &body, loop_statement.break_target());
1215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
1216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ jmp(&body);
1217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_limit_hit);
1220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StackCheckStub stack_stub;
1221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallStub(&stack_stub);
1222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&stack_check_success);
1223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.break_target());
1225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  decrement_loop_depth();
1226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ TryCatchStatement");
1231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The try block adds a handler to the exception handler chain
1233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // before entering, and removes it again when exiting normally.
1234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If an exception is thrown during execution of the try block,
1235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // control is passed to the handler, which also consumes the handler.
1236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // At this point, the exception is in a register, and store it in
1237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // the temporary local variable (prints as ".catch-var") before
1238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // executing the catch block. The catch block has been rewritten
1239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // to introduce a new scope to bind the catch variable and to remove
1240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // that scope again afterwards.
1241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label try_handler_setup, catch_entry, done;
1243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(&try_handler_setup);
1244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try handler code, exception in result register.
1245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Store exception in local .catch variable before executing catch block.
1247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
1248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // The catch variable is *always* a variable proxy for a local variable.
1249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable();
1250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_NOT_NULL(catch_var);
1251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Slot* variable_slot = catch_var->slot();
1252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_NOT_NULL(variable_slot);
1253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_EQ(Slot::LOCAL, variable_slot->type());
1254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    StoreToFrameField(SlotOffset(variable_slot), result_register());
1255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->catch_block());
1258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&done);
1259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try block code. Sets up the exception handler chain.
1261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&try_handler_setup);
1262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
1263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    TryCatch try_block(this, &catch_entry);
1264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER);
1265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->try_block());
1266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PopTryHandler();
1267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&done);
1269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ TryFinallyStatement");
1274d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try finally is compiled by setting up a try-handler on the stack while
1276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // executing the try body, and removing it again afterwards.
1277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
1278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The try-finally construct can enter the finally block in three ways:
1279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // 1. By exiting the try-block normally. This removes the try-handler and
1280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //      calls the finally block code before continuing.
1281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // 2. By exiting the try-block with a function-local control flow transfer
1282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    (break/continue/return). The site of the, e.g., break removes the
1283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    try handler and calls the finally block code before continuing
1284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    its outward control transfer.
1285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // 3. by exiting the try-block with a thrown exception.
1286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    This can happen in nested function calls. It traverses the try-handler
1287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    chain and consumes the try-handler entry before jumping to the
1288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    handler code. The handler code then calls the finally-block before
1289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    rethrowing the exception.
1290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
1291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The finally block must assume a return address on top of the stack
1292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // (or in the link register on ARM chips) and a value (return value or
1293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // exception) in the result register (rax/eax/r0), both of which must
1294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // be preserved. The return address isn't GC-safe, so it should be
1295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // cooked before GC.
1296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label finally_entry;
1297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label try_handler_setup;
1298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Setup the try-handler chain. Use a call to
1300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Jump to try-handler setup and try-block code. Use call to put try-handler
1301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // address on stack.
1302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(&try_handler_setup);
1303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try handler code. Return address of call is pushed on handler stack.
1304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
1305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // This code is only executed during stack-handler traversal when an
1306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // exception is thrown. The execption is in the result register, which
1307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // is retained by the finally block.
1308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Call the finally block and then rethrow the exception.
1309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ Call(&finally_entry);
1310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ push(result_register());
1311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ CallRuntime(Runtime::kReThrow, 1);
1312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&finally_entry);
1315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
1316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Finally block implementation.
1317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Finally finally_block(this);
1318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    EnterFinallyBlock();
1319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->finally_block());
1320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ExitFinallyBlock();  // Return to the calling code.
1321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&try_handler_setup);
1324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
1325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Setup try handler (stack pointer registers).
1326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    TryFinally try_block(this, &finally_entry);
1327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER);
1328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->try_block());
1329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PopTryHandler();
1330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Execute the finally block on the way out.
1332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(&finally_entry);
1333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
1338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ DebuggerStatement");
1339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
13404515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
1341402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  __ DebugBreak();
1342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Ignore the return value.
1343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif
1344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) {
1348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Conditional");
1349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label true_case, false_case, done;
1350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(expr->condition(), &true_case, &false_case);
1351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&true_case);
13537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  SetExpressionPosition(expr->then_expression(),
13547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                        expr->then_expression_position());
1355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->then_expression());
1356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If control flow falls through Visit, jump to done.
1357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (context_ == Expression::kEffect || context_ == Expression::kValue) {
1358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ jmp(&done);
1359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&false_case);
13627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  SetExpressionPosition(expr->else_expression(),
13637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                        expr->else_expression_position());
1364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->else_expression());
1365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If control flow falls through Visit, merge it with true case here.
1366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (context_ == Expression::kEffect || context_ == Expression::kValue) {
1367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ bind(&done);
1368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitSlot(Slot* expr) {
1373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Slots do not appear directly in the AST.
1374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  UNREACHABLE();
1375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) {
1379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Literal");
1380d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Apply(context_, expr);
1381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1382d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1384f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Comment cmnt(masm_, "[ FunctionLiteral");
1386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1387f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Build the function boilerplate and instantiate it.
1388f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Handle<SharedFunctionInfo> function_info =
1389f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      Compiler::BuildFunctionInfo(expr, script(), this);
1390f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (HasStackOverflow()) return;
1391f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  EmitNewClosure(function_info);
1392f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
1393f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1394f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1395f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitSharedFunctionInfoLiteral(
1396f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    SharedFunctionInfoLiteral* expr) {
1397f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
1398f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  EmitNewClosure(expr->shared_function_info());
1399f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
1400f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1401f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1402d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
1403d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Call runtime routine to allocate the catch extension object and
1404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // assign the exception value to the catch variable.
1405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ CatchExtensionObject");
1406d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr->key(), kStack);
1407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr->value(), kStack);
1408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Create catch extension object.
1409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
1410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Apply(context_, result_register());
1411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) {
1415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Throw");
1416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr->exception(), kStack);
1417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallRuntime(Runtime::kThrow, 1);
1418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Never returns here.
1419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryFinally::Exit(int stack_depth) {
1423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The macros used here must preserve the result register.
1424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
1425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ PopTryHandler();
1426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(finally_entry_);
1427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return 0;
1428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryCatch::Exit(int stack_depth) {
1432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The macros used here must preserve the result register.
1433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
1434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ PopTryHandler();
1435d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return 0;
1436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __
1439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} }  // namespace v8::internal
1442