full-codegen.cc revision d91b9f7d46489a9ee00f9cb415630299c76a502b
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"
33d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "stub-cache.h"
34d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "debug.h"
35d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
36d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 {
37d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal {
38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define BAILOUT(reason)                         \
40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  do {                                          \
41d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (FLAG_trace_bailout) {                   \
42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      PrintF("%s\n", reason);                   \
43d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }                                           \
44d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    has_supported_syntax_ = false;              \
45d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    return;                                     \
46d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } while (false)
47d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
48d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
49d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define CHECK_BAILOUT                           \
50d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  do {                                          \
51d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (!has_supported_syntax_) return;         \
52d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } while (false)
53d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
54d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
55d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) {
56d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Scope* scope = fun->scope();
57d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
58d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (scope->num_heap_slots() > 0) {
59d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // We support functions with a local context if they do not have
60d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // parameters that need to be copied into the context.
61d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    for (int i = 0, len = scope->num_parameters(); i < len; i++) {
62d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Slot* slot = scope->parameter(i)->slot();
63d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      if (slot != NULL && slot->type() == Slot::CONTEXT) {
64d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        BAILOUT("Function has context-allocated parameters.");
65d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      }
66d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
67d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
68d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
69d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitDeclarations(scope->declarations());
70d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
71d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
72d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitStatements(fun->body());
73d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
74d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
75d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
76d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclarations(
77d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ZoneList<Declaration*>* decls) {
78d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < decls->length(); i++) {
79d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(decls->at(i));
80d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
81d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
82d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
83d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
84d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
85d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
86d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0, len = stmts->length(); i < len; i++) {
87d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmts->at(i));
88d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
89d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
90d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
91d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
92d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
93d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) {
94d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Property* prop = decl->proxy()->AsProperty();
95d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (prop != NULL) {
96d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
97d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
98d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
99d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (decl->fun() != NULL) {
101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(decl->fun());
102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBlock(Block* stmt) {
107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitStatements(stmt->statements());
108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitExpressionStatement(
112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ExpressionStatement* stmt) {
113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->expression());
114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) {
118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) {
123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->condition());
124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->then_statement());
126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->else_statement());
128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) {
132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) {
137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) {
142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->expression());
143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithEnterStatement(
147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    WithEnterStatement* stmt) {
148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->expression());
149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) {
153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) {
158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  BAILOUT("SwitchStatement");
159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->cond());
164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) {
170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->cond());
171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) {
177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (!FLAG_always_full_compiler) BAILOUT("ForStatement");
178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->init() != NULL) {
179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->init());
180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->cond() != NULL) {
183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->cond());
184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->next() != NULL) {
188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->next());
190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) {
195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  BAILOUT("ForInStatement");
196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) {
200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->try_block());
201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->catch_block());
203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitTryFinallyStatement(
207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    TryFinallyStatement* stmt) {
208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->try_block());
209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->finally_block());
211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitDebuggerStatement(
215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DebuggerStatement* stmt) {
216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitFunctionBoilerplateLiteral(
226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    FunctionBoilerplateLiteral* expr) {
227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  BAILOUT("FunctionBoilerplateLiteral");
228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitConditional(Conditional* expr) {
232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->condition());
233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->then_expression());
235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->else_expression());
237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitSlot(Slot* expr) {
241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  UNREACHABLE();
242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) {
246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitLiteral(Literal* expr) {
251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) {
261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0, len = properties->length(); i < len; i++) {
264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ObjectLiteral::Property* property = properties->at(i);
265d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (property->IsCompileTimeValue()) continue;
266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(property->key());
267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(property->value());
269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
272d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
273d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
274d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) {
275d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<Expression*>* subexprs = expr->values();
276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0, len = subexprs->length(); i < len; i++) {
277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Expression* subexpr = subexprs->at(i);
278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (subexpr->AsLiteral() != NULL) continue;
279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(subexpr);
281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCatchExtensionObject(
287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CatchExtensionObject* expr) {
288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->key());
289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->value());
291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) {
295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Token::Value op = expr->op();
296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (op == Token::INIT_CONST) BAILOUT("initialize constant");
297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Variable* var = expr->target()->AsVariableProxy()->AsVariable();
299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Property* prop = expr->target()->AsProperty();
300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ASSERT(var == NULL || prop == NULL);
301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (var != NULL) {
302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (var->mode() == Variable::CONST) BAILOUT("Assignment to const");
303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // All other variables are supported.
304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (prop != NULL) {
305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // This is a throw reference error.
311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("non-variable/non-property assignment");
312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->value());
315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->exception());
320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitProperty(Property* expr) {
324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->obj());
325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->key());
327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCall(Call* expr) {
331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Expression* fun = expr->expression();
332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<Expression*>* args = expr->arguments();
333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Variable* var = fun->AsVariableProxy()->AsVariable();
334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check for supported calls
336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (var != NULL && var->is_possibly_eval()) {
337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("call to the identifier 'eval'");
338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (var != NULL && !var->is_this() && var->is_global()) {
339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Calls to global variables are supported.
340d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (var != NULL && var->slot() != NULL &&
341d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke             var->slot()->type() == Slot::LOOKUP) {
342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("call to a lookup slot");
343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (fun->AsProperty() != NULL) {
344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Property* prop = fun->AsProperty();
345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Otherwise the call is supported if the function expression is.
351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(fun);
352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check all arguments to the call.
354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < args->length(); i++) {
355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(args->at(i));
356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
360d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
361d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
362d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->expression());
363d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
364d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ZoneList<Expression*>* args = expr->arguments();
365d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check all arguments to the call
366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < args->length(); i++) {
367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(args->at(i));
368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
373d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
374d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check for inline runtime call
375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (expr->name()->Get(0) == '_' &&
376d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("inlined runtime call");
378d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
379d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check all arguments to the call.  (Relies on TEMP meaning STACK.)
380d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < expr->arguments()->length(); i++) {
381d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(expr->arguments()->at(i));
382d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
386d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
387d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
388d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  switch (expr->op()) {
389d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::ADD:
390d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::NOT:
391d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::TYPEOF:
392d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::VOID:
393d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Visit(expr->expression());
394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
395d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::BIT_NOT:
396d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      BAILOUT("UnaryOperation: BIT_NOT");
397d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::DELETE:
398d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      BAILOUT("UnaryOperation: DELETE");
399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Token::SUB:
400d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      BAILOUT("UnaryOperation: SUB");
401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    default:
402d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      UNREACHABLE();
403d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
404d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
406d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Property* prop = expr->expression()->AsProperty();
410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ASSERT(var == NULL || prop == NULL);
411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (var != NULL) {
412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // All global variables are supported.
413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (!var->is_global()) {
414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      ASSERT(var->slot() != NULL);
415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Slot::Type type = var->slot()->type();
416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      if (type == Slot::LOOKUP) {
417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        BAILOUT("CountOperation with lookup slot");
418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      }
419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (prop != NULL) {
421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->obj());
422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(prop->key());
424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK_BAILOUT;
425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // This is a throw reference error.
427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BAILOUT("CountOperation non-variable/non-property expression");
428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->left());
434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
435d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->right());
436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->left());
441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK_BAILOUT;
442d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->right());
443d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
444d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
445d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
446d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
447d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Supported.
448d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
449d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
450d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef BAILOUT
451d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef CHECK_BAILOUT
452d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
453d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
454d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define __ ACCESS_MASM(masm())
455d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
456d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeHandle<Code> FullCodeGenerator::MakeCode(FunctionLiteral* fun,
457d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                         Handle<Script> script,
458d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                         bool is_eval) {
459d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (!script->IsUndefined() && !script->source()->IsUndefined()) {
460d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    int len = String::cast(script->source())->length();
461d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Counters::total_full_codegen_source_size.Increment(len);
462d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
463d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CodeGenerator::MakeCodePrologue(fun);
464d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  const int kInitialBufferSize = 4 * KB;
465d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  MacroAssembler masm(NULL, kInitialBufferSize);
466d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  FullCodeGenerator cgen(&masm, script, is_eval);
467d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  cgen.Generate(fun);
468d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (cgen.HasStackOverflow()) {
469d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT(!Top::has_pending_exception());
470d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    return Handle<Code>::null();
471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
472d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
473d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script);
474d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
475d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
476d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
477d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::SlotOffset(Slot* slot) {
478d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ASSERT(slot != NULL);
479d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Offset is negative because higher indexes are at lower addresses.
480d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int offset = -slot->index() * kPointerSize;
481d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Adjust by a (parameter or local) base offset.
482d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  switch (slot->type()) {
483d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::PARAMETER:
484d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      offset += (function_->scope()->num_parameters() + 1) * kPointerSize;
485d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
486d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::LOCAL:
487d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      offset += JavaScriptFrameConstants::kLocal0Offset;
488d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
489d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::CONTEXT:
490d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case Slot::LOOKUP:
491d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      UNREACHABLE();
492d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
493d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return offset;
494d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
495d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
496d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
497d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDeclarations(
498d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ZoneList<Declaration*>* declarations) {
499d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int length = declarations->length();
500d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int globals = 0;
501d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  for (int i = 0; i < length; i++) {
502d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Declaration* decl = declarations->at(i);
503d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Variable* var = decl->proxy()->var();
504d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Slot* slot = var->slot();
505d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
506d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // If it was not possible to allocate the variable at compile
507d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // time, we need to "declare" it at runtime to make sure it
508d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // actually exists in the local context.
509d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
510d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      VisitDeclaration(decl);
511d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    } else {
512d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Count global variables and functions for later processing
513d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      globals++;
514d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
515d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
516d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
517d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Compute array of global variable and function declarations.
518d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Do nothing in case of no declared global functions or variables.
519d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (globals > 0) {
520d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED);
521d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    for (int j = 0, i = 0; i < length; i++) {
522d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Declaration* decl = declarations->at(i);
523d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Variable* var = decl->proxy()->var();
524d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      Slot* slot = var->slot();
525d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
526d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) {
527d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        array->set(j++, *(var->name()));
528d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        if (decl->fun() == NULL) {
529d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          if (var->mode() == Variable::CONST) {
530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke            // In case this is const property use the hole.
531d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke            array->set_the_hole(j++);
532d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          } else {
533d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke            array->set_undefined(j++);
534d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          }
535d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        } else {
536d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          Handle<JSFunction> function =
537d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke              Compiler::BuildBoilerplate(decl->fun(), script_, this);
538d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          // Check for stack-overflow exception.
539d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          if (HasStackOverflow()) return;
540d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          array->set(j++, *function);
541d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        }
542d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      }
543d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
544d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Invoke the platform-dependent code generator to do the actual
545d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // declaration the global variables and functions.
546d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DeclareGlobals(array);
547d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
548d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
550d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
551d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
552d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
553d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, fun->start_position());
554d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
555d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
556d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
557d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
558d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
559d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
560d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, fun->end_position());
561d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
562d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
563d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
564d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
565d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(Statement* stmt) {
566d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
567d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
568d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
569d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
570d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
571d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
572d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetStatementPosition(int pos) {
573d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info) {
574d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CodeGenerator::RecordPositions(masm_, pos);
575d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
576d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
577d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
578d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
579d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::SetSourcePosition(int pos) {
580d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
581d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    masm_->RecordPosition(pos);
582d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
583d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
584d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
585d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
586d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
587d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label eval_right, done;
588d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
589d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Set up the appropriate context for the left subexpression based
590d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // on the operation and our own context.  Initially assume we can
591d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // inherit both true and false labels from our context.
592d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (expr->op() == Token::OR) {
593d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    switch (context_) {
594d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kUninitialized:
595d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        UNREACHABLE();
596d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kEffect:
597d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &done, &eval_right);
598d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
599d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValue:
600d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForValueControl(expr->left(),
601d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
602d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &done,
603d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right);
604d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
605d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTest:
606d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), true_label_, &eval_right);
607d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
608d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValueTest:
609d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForValueControl(expr->left(),
610d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
611d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             true_label_,
612d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right);
613d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
614d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTestValue:
615d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), true_label_, &eval_right);
616d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
617d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
618d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
619d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_EQ(Token::AND, expr->op());
620d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    switch (context_) {
621d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kUninitialized:
622d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        UNREACHABLE();
623d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kEffect:
624d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &eval_right, &done);
625d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
626d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValue:
627d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControlValue(expr->left(),
628d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
629d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right,
630d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &done);
631d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
632d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTest:
633d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &eval_right, false_label_);
634d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
635d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kValueTest:
636d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControl(expr->left(), &eval_right, false_label_);
637d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
638d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case Expression::kTestValue:
639d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        VisitForControlValue(expr->left(),
640d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             location_,
641d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             &eval_right,
642d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             false_label_);
643d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
644d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
645d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
646d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
647d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&eval_right);
648d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->right());
649d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
650d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&done);
651d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
652d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
653d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
654d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBlock(Block* stmt) {
655d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Block");
656d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Breakable nested_statement(this, stmt);
657d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
658d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitStatements(stmt->statements());
659d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(nested_statement.break_target());
660d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
661d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
662d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
663d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
664d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ ExpressionStatement");
665d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
666d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForEffect(stmt->expression());
667d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
668d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
669d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
670d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
671d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ EmptyStatement");
672d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
674d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
675d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
676d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
677d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ IfStatement");
678d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
679d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label then_part, else_part, done;
680d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
681d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Do not worry about optimizing for empty then or else bodies.
682d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(stmt->condition(), &then_part, &else_part);
683d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
684d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&then_part);
685d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->then_statement());
686d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&done);
687d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
688d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&else_part);
689d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->else_statement());
690d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
691d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&done);
692d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
693d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
694d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
695d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
696d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_,  "[ ContinueStatement");
697d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
698d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  NestedStatement* current = nesting_stack_;
699d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int stack_depth = 0;
700d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  while (!current->IsContinueTarget(stmt->target())) {
701d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    stack_depth = current->Exit(stack_depth);
702d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    current = current->outer();
703d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
704d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
705d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
706d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration* loop = current->AsIteration();
707d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(loop->continue_target());
708d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
709d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
710d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
711d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
712d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_,  "[ BreakStatement");
713d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  NestedStatement* current = nesting_stack_;
715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int stack_depth = 0;
716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  while (!current->IsBreakTarget(stmt->target())) {
717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    stack_depth = current->Exit(stack_depth);
718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    current = current->outer();
719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Breakable* target = current->AsBreakable();
723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(target->break_target());
724d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
725d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
726d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
727d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
728d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ ReturnStatement");
729d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
730d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Expression* expr = stmt->expression();
731d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr, kAccumulator);
732d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
733d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Exit all nested statements.
734d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  NestedStatement* current = nesting_stack_;
735d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int stack_depth = 0;
736d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  while (current != NULL) {
737d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    stack_depth = current->Exit(stack_depth);
738d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    current = current->outer();
739d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
740d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
741d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  EmitReturnSequence(stmt->statement_pos());
743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
744d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
745d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
746d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ WithEnterStatement");
748d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
749d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
750d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(stmt->expression(), kStack);
751d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->is_catch_block()) {
752d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ CallRuntime(Runtime::kPushCatchContext, 1);
753d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
754d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ CallRuntime(Runtime::kPushContext, 1);
755d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
756d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Both runtime calls return the new context in both the context and the
757d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // result registers.
758d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
759d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Update local stack frame context field.
760d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
761d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
762d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
763d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
764d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
765d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ WithExitStatement");
766d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
767d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Pop context.
769d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  LoadContextField(context_register(), Context::PREVIOUS_INDEX);
770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Update local stack frame context field.
771d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
772d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  UNREACHABLE();
777d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
778d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
779d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
780d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
781d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ DoWhileStatement");
782d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
783d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label body, stack_limit_hit, stack_check_success;
784d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
785d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration loop_statement(this, stmt);
786d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  increment_loop_depth();
787d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
788d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&body);
789d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
790d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
791d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check stack before looping.
792d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ StackLimitCheck(&stack_limit_hit);
793d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_check_success);
794d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
795d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.continue_target());
796d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt->condition_position());
797d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(stmt->cond(), &body, loop_statement.break_target());
798d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
799d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_limit_hit);
800d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StackCheckStub stack_stub;
801d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallStub(&stack_stub);
802d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&stack_check_success);
803d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
804d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.break_target());
805d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
806d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  decrement_loop_depth();
807d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
808d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
809d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
810d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
811d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ WhileStatement");
812d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
813d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label body, stack_limit_hit, stack_check_success;
814d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
815d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration loop_statement(this, stmt);
816d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  increment_loop_depth();
817d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
818d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Emit the test at the bottom of the loop.
819d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(loop_statement.continue_target());
820d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
821d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&body);
822d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
823d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
824d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.continue_target());
825d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check stack before looping.
826d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ StackLimitCheck(&stack_limit_hit);
827d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_check_success);
828d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
829d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(stmt->cond(), &body, loop_statement.break_target());
830d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
831d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_limit_hit);
832d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StackCheckStub stack_stub;
833d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallStub(&stack_stub);
834d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&stack_check_success);
835d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
836d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.break_target());
837d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  decrement_loop_depth();
838d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
839d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
840d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
841d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
842d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ ForStatement");
843d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
844d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label test, body, stack_limit_hit, stack_check_success;
845d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
846d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Iteration loop_statement(this, stmt);
847d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->init() != NULL) {
848d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->init());
849d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
850d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
851d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  increment_loop_depth();
852d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Emit the test at the bottom of the loop (even if empty).
853d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&test);
854d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
855d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&body);
856d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->body());
857d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
858d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.continue_target());
859d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
860d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
861d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->next() != NULL) {
862d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->next());
863d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
864d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
865d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&test);
866d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
867d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check stack before looping.
868d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ StackLimitCheck(&stack_limit_hit);
869d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_check_success);
870d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
871d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (stmt->cond() != NULL) {
872d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    VisitForControl(stmt->cond(), &body, loop_statement.break_target());
873d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else {
874d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ jmp(&body);
875d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
876d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
877d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&stack_limit_hit);
878d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  StackCheckStub stack_stub;
879d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallStub(&stack_stub);
880d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&stack_check_success);
881d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
882d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(loop_statement.break_target());
883d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  decrement_loop_depth();
884d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
885d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
886d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
887d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
888d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  UNREACHABLE();
889d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
890d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
891d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
892d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
893d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ TryCatchStatement");
894d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
895d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The try block adds a handler to the exception handler chain
896d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // before entering, and removes it again when exiting normally.
897d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If an exception is thrown during execution of the try block,
898d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // control is passed to the handler, which also consumes the handler.
899d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // At this point, the exception is in a register, and store it in
900d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // the temporary local variable (prints as ".catch-var") before
901d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // executing the catch block. The catch block has been rewritten
902d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // to introduce a new scope to bind the catch variable and to remove
903d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // that scope again afterwards.
904d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
905d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label try_handler_setup, catch_entry, done;
906d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(&try_handler_setup);
907d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try handler code, exception in result register.
908d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
909d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Store exception in local .catch variable before executing catch block.
910d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
911d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // The catch variable is *always* a variable proxy for a local variable.
912d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable();
913d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_NOT_NULL(catch_var);
914d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Slot* variable_slot = catch_var->slot();
915d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_NOT_NULL(variable_slot);
916d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT_EQ(Slot::LOCAL, variable_slot->type());
917d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    StoreToFrameField(SlotOffset(variable_slot), result_register());
918d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
919d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
920d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(stmt->catch_block());
921d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ jmp(&done);
922d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
923d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try block code. Sets up the exception handler chain.
924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&try_handler_setup);
925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
926d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    TryCatch try_block(this, &catch_entry);
927d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER);
928d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->try_block());
929d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PopTryHandler();
930d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
931d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&done);
932d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
933d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
934d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
935d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
936d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ TryFinallyStatement");
937d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
938d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try finally is compiled by setting up a try-handler on the stack while
939d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // executing the try body, and removing it again afterwards.
940d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
941d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The try-finally construct can enter the finally block in three ways:
942d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // 1. By exiting the try-block normally. This removes the try-handler and
943d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //      calls the finally block code before continuing.
944d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // 2. By exiting the try-block with a function-local control flow transfer
945d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    (break/continue/return). The site of the, e.g., break removes the
946d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    try handler and calls the finally block code before continuing
947d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    its outward control transfer.
948d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // 3. by exiting the try-block with a thrown exception.
949d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    This can happen in nested function calls. It traverses the try-handler
950d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    chain and consumes the try-handler entry before jumping to the
951d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    handler code. The handler code then calls the finally-block before
952d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    rethrowing the exception.
953d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
954d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The finally block must assume a return address on top of the stack
955d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // (or in the link register on ARM chips) and a value (return value or
956d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // exception) in the result register (rax/eax/r0), both of which must
957d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // be preserved. The return address isn't GC-safe, so it should be
958d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // cooked before GC.
959d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label finally_entry;
960d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label try_handler_setup;
961d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
962d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Setup the try-handler chain. Use a call to
963d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Jump to try-handler setup and try-block code. Use call to put try-handler
964d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // address on stack.
965d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(&try_handler_setup);
966d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Try handler code. Return address of call is pushed on handler stack.
967d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
968d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // This code is only executed during stack-handler traversal when an
969d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // exception is thrown. The execption is in the result register, which
970d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // is retained by the finally block.
971d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Call the finally block and then rethrow the exception.
972d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ Call(&finally_entry);
973d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ push(result_register());
974d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ CallRuntime(Runtime::kReThrow, 1);
975d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
976d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
977d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&finally_entry);
978d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
979d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Finally block implementation.
980d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Finally finally_block(this);
981d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    EnterFinallyBlock();
982d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->finally_block());
983d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ExitFinallyBlock();  // Return to the calling code.
984d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
985d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
986d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&try_handler_setup);
987d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  {
988d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Setup try handler (stack pointer registers).
989d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    TryFinally try_block(this, &finally_entry);
990d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER);
991d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(stmt->try_block());
992d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ PopTryHandler();
993d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
994d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Execute the finally block on the way out.
995d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(&finally_entry);
996d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
997d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
998d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
999d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1000d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
1001d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ DebuggerStatement");
1002d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetStatementPosition(stmt);
1003d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallRuntime(Runtime::kDebugBreak, 0);
1004d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Ignore the return value.
1005d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif
1006d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1007d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1008d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1009d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitFunctionBoilerplateLiteral(
1010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    FunctionBoilerplateLiteral* expr) {
1011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  UNREACHABLE();
1012d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1013d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1014d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1015d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitConditional(Conditional* expr) {
1016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Conditional");
1017d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label true_case, false_case, done;
1018d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForControl(expr->condition(), &true_case, &false_case);
1019d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&true_case);
1021d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->then_expression());
1022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If control flow falls through Visit, jump to done.
1023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (context_ == Expression::kEffect || context_ == Expression::kValue) {
1024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ jmp(&done);
1025d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1026d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1027d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&false_case);
1028d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Visit(expr->else_expression());
1029d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If control flow falls through Visit, merge it with true case here.
1030d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (context_ == Expression::kEffect || context_ == Expression::kValue) {
1031d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    __ bind(&done);
1032d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1033d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1034d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1035d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1036d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitSlot(Slot* expr) {
1037d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Slots do not appear directly in the AST.
1038d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  UNREACHABLE();
1039d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1040d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1041d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1042d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitLiteral(Literal* expr) {
1043d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Literal");
1044d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Apply(context_, expr);
1045d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1046d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1047d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1048d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitAssignment(Assignment* expr) {
1049d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Assignment");
1050d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  ASSERT(expr->op() != Token::INIT_CONST);
1051d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Left-hand side can only be a property, a global or a (parameter or local)
1052d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
1053d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1054d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  LhsKind assign_type = VARIABLE;
1055d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Property* prop = expr->target()->AsProperty();
1056d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (prop != NULL) {
1057d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    assign_type =
1058d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
1059d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1060d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1061d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Evaluate LHS expression.
1062d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  switch (assign_type) {
1063d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case VARIABLE:
1064d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Nothing to do here.
1065d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
1066d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case NAMED_PROPERTY:
1067d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      VisitForValue(prop->obj(), kStack);
1068d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
1069d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case KEYED_PROPERTY:
1070d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      VisitForValue(prop->obj(), kStack);
1071d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      VisitForValue(prop->key(), kStack);
1072d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
1073d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1074d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1075d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If we have a compound assignment: Get value of LHS expression and
1076d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // store in on top of the stack.
1077d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (expr->is_compound()) {
1078d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Location saved_location = location_;
1079d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = kStack;
1080d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    switch (assign_type) {
1081d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case VARIABLE:
1082d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        EmitVariableLoad(expr->target()->AsVariableProxy()->var(),
1083d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                         Expression::kValue);
1084d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
1085d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case NAMED_PROPERTY:
1086d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        EmitNamedPropertyLoad(prop);
1087d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        __ push(result_register());
1088d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
1089d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      case KEYED_PROPERTY:
1090d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        EmitKeyedPropertyLoad(prop);
1091d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        __ push(result_register());
1092d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        break;
1093d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
1094d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = saved_location;
1095d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Evaluate RHS expression.
1098d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Expression* rhs = expr->value();
1099d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(rhs, kAccumulator);
1100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // If we have a compound assignment: Apply operator.
1102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (expr->is_compound()) {
1103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Location saved_location = location_;
1104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = kAccumulator;
1105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    EmitBinaryOp(expr->binary_op(), Expression::kValue);
1106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = saved_location;
1107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Record source position before possible IC call.
1110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  SetSourcePosition(expr->position());
1111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Store the value.
1113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  switch (assign_type) {
1114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case VARIABLE:
1115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                             context_);
1117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
1118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case NAMED_PROPERTY:
1119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      EmitNamedPropertyAssignment(expr);
1120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
1121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    case KEYED_PROPERTY:
1122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      EmitKeyedPropertyAssignment(expr);
1123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      break;
1124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
1129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Call runtime routine to allocate the catch extension object and
1130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // assign the exception value to the catch variable.
1131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ CatchExtensionObject");
1132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr->key(), kStack);
1133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr->value(), kStack);
1134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Create catch extension object.
1135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
1136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Apply(context_, result_register());
1137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitThrow(Throw* expr) {
1141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Comment cmnt(masm_, "[ Throw");
1142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  VisitForValue(expr->exception(), kStack);
1143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ CallRuntime(Runtime::kThrow, 1);
1144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Never returns here.
1145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryFinally::Exit(int stack_depth) {
1149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The macros used here must preserve the result register.
1150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
1151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ PopTryHandler();
1152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Call(finally_entry_);
1153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return 0;
1154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint FullCodeGenerator::TryCatch::Exit(int stack_depth) {
1158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The macros used here must preserve the result register.
1159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ Drop(stack_depth);
1160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ PopTryHandler();
1161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return 0;
1162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef __
1166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} }  // namespace v8::internal
1169