[V8] Introduce a QML compilation mode
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / full-codegen.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #include "codegen.h"
31 #include "compiler.h"
32 #include "debug.h"
33 #include "full-codegen.h"
34 #include "liveedit.h"
35 #include "macro-assembler.h"
36 #include "prettyprinter.h"
37 #include "scopes.h"
38 #include "scopeinfo.h"
39 #include "stub-cache.h"
40
41 namespace v8 {
42 namespace internal {
43
44 void BreakableStatementChecker::Check(Statement* stmt) {
45   Visit(stmt);
46 }
47
48
49 void BreakableStatementChecker::Check(Expression* expr) {
50   Visit(expr);
51 }
52
53
54 void BreakableStatementChecker::VisitVariableDeclaration(
55     VariableDeclaration* decl) {
56 }
57
58 void BreakableStatementChecker::VisitFunctionDeclaration(
59     FunctionDeclaration* decl) {
60 }
61
62 void BreakableStatementChecker::VisitModuleDeclaration(
63     ModuleDeclaration* decl) {
64 }
65
66 void BreakableStatementChecker::VisitImportDeclaration(
67     ImportDeclaration* decl) {
68 }
69
70 void BreakableStatementChecker::VisitExportDeclaration(
71     ExportDeclaration* decl) {
72 }
73
74
75 void BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) {
76 }
77
78 void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) {
79 }
80
81 void BreakableStatementChecker::VisitModulePath(ModulePath* module) {
82 }
83
84 void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) {
85 }
86
87
88 void BreakableStatementChecker::VisitBlock(Block* stmt) {
89 }
90
91
92 void BreakableStatementChecker::VisitExpressionStatement(
93     ExpressionStatement* stmt) {
94   // Check if expression is breakable.
95   Visit(stmt->expression());
96 }
97
98
99 void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
100 }
101
102
103 void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
104   // If the condition is breakable the if statement is breakable.
105   Visit(stmt->condition());
106 }
107
108
109 void BreakableStatementChecker::VisitContinueStatement(
110     ContinueStatement* stmt) {
111 }
112
113
114 void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
115 }
116
117
118 void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
119   // Return is breakable if the expression is.
120   Visit(stmt->expression());
121 }
122
123
124 void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
125   Visit(stmt->expression());
126 }
127
128
129 void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
130   // Switch statements breakable if the tag expression is.
131   Visit(stmt->tag());
132 }
133
134
135 void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
136   // Mark do while as breakable to avoid adding a break slot in front of it.
137   is_breakable_ = true;
138 }
139
140
141 void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
142   // Mark while statements breakable if the condition expression is.
143   Visit(stmt->cond());
144 }
145
146
147 void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
148   // Mark for statements breakable if the condition expression is.
149   if (stmt->cond() != NULL) {
150     Visit(stmt->cond());
151   }
152 }
153
154
155 void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
156   // Mark for in statements breakable if the enumerable expression is.
157   Visit(stmt->enumerable());
158 }
159
160
161 void BreakableStatementChecker::VisitTryCatchStatement(
162     TryCatchStatement* stmt) {
163   // Mark try catch as breakable to avoid adding a break slot in front of it.
164   is_breakable_ = true;
165 }
166
167
168 void BreakableStatementChecker::VisitTryFinallyStatement(
169     TryFinallyStatement* stmt) {
170   // Mark try finally as breakable to avoid adding a break slot in front of it.
171   is_breakable_ = true;
172 }
173
174
175 void BreakableStatementChecker::VisitDebuggerStatement(
176     DebuggerStatement* stmt) {
177   // The debugger statement is breakable.
178   is_breakable_ = true;
179 }
180
181
182 void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
183 }
184
185
186 void BreakableStatementChecker::VisitSharedFunctionInfoLiteral(
187     SharedFunctionInfoLiteral* expr) {
188 }
189
190
191 void BreakableStatementChecker::VisitConditional(Conditional* expr) {
192 }
193
194
195 void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
196 }
197
198
199 void BreakableStatementChecker::VisitLiteral(Literal* expr) {
200 }
201
202
203 void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
204 }
205
206
207 void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
208 }
209
210
211 void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
212 }
213
214
215 void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
216   // If assigning to a property (including a global property) the assignment is
217   // breakable.
218   VariableProxy* proxy = expr->target()->AsVariableProxy();
219   Property* prop = expr->target()->AsProperty();
220   if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) {
221     is_breakable_ = true;
222     return;
223   }
224
225   // Otherwise the assignment is breakable if the assigned value is.
226   Visit(expr->value());
227 }
228
229
230 void BreakableStatementChecker::VisitThrow(Throw* expr) {
231   // Throw is breakable if the expression is.
232   Visit(expr->exception());
233 }
234
235
236 void BreakableStatementChecker::VisitProperty(Property* expr) {
237   // Property load is breakable.
238   is_breakable_ = true;
239 }
240
241
242 void BreakableStatementChecker::VisitCall(Call* expr) {
243   // Function calls both through IC and call stub are breakable.
244   is_breakable_ = true;
245 }
246
247
248 void BreakableStatementChecker::VisitCallNew(CallNew* expr) {
249   // Function calls through new are breakable.
250   is_breakable_ = true;
251 }
252
253
254 void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
255 }
256
257
258 void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
259   Visit(expr->expression());
260 }
261
262
263 void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
264   Visit(expr->expression());
265 }
266
267
268 void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
269   Visit(expr->left());
270   if (expr->op() != Token::AND &&
271       expr->op() != Token::OR) {
272     Visit(expr->right());
273   }
274 }
275
276
277 void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
278   Visit(expr->left());
279   Visit(expr->right());
280 }
281
282
283 void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
284 }
285
286
287 #define __ ACCESS_MASM(masm())
288
289 bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
290   Isolate* isolate = info->isolate();
291   Handle<Script> script = info->script();
292   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
293     int len = String::cast(script->source())->length();
294     isolate->counters()->total_full_codegen_source_size()->Increment(len);
295   }
296   if (FLAG_trace_codegen) {
297     PrintF("Full Compiler - ");
298   }
299   CodeGenerator::MakeCodePrologue(info);
300   const int kInitialBufferSize = 4 * KB;
301   MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize);
302 #ifdef ENABLE_GDB_JIT_INTERFACE
303   masm.positions_recorder()->StartGDBJITLineInfoRecording();
304 #endif
305
306   FullCodeGenerator cgen(&masm, info);
307   cgen.Generate();
308   if (cgen.HasStackOverflow()) {
309     ASSERT(!isolate->has_pending_exception());
310     return false;
311   }
312   unsigned table_offset = cgen.EmitStackCheckTable();
313
314   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
315   Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
316   code->set_optimizable(info->IsOptimizable() &&
317                         !info->function()->flags()->Contains(kDontOptimize));
318   cgen.PopulateDeoptimizationData(code);
319   cgen.PopulateTypeFeedbackInfo(code);
320   cgen.PopulateTypeFeedbackCells(code);
321   code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
322   code->set_handler_table(*cgen.handler_table());
323 #ifdef ENABLE_DEBUGGER_SUPPORT
324   code->set_has_debug_break_slots(
325       info->isolate()->debugger()->IsDebuggerActive());
326   code->set_compiled_optimizable(info->IsOptimizable());
327 #endif  // ENABLE_DEBUGGER_SUPPORT
328   code->set_allow_osr_at_loop_nesting_level(0);
329   code->set_profiler_ticks(0);
330   code->set_stack_check_table_offset(table_offset);
331   CodeGenerator::PrintCode(code, info);
332   info->SetCode(code);  // May be an empty handle.
333 #ifdef ENABLE_GDB_JIT_INTERFACE
334   if (FLAG_gdbjit && !code.is_null()) {
335     GDBJITLineInfo* lineinfo =
336         masm.positions_recorder()->DetachGDBJITLineInfo();
337
338     GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
339   }
340 #endif
341   return !code.is_null();
342 }
343
344
345 unsigned FullCodeGenerator::EmitStackCheckTable() {
346   // The stack check table consists of a length (in number of entries)
347   // field, and then a sequence of entries.  Each entry is a pair of AST id
348   // and code-relative pc offset.
349   masm()->Align(kIntSize);
350   unsigned offset = masm()->pc_offset();
351   unsigned length = stack_checks_.length();
352   __ dd(length);
353   for (unsigned i = 0; i < length; ++i) {
354     __ dd(stack_checks_[i].id);
355     __ dd(stack_checks_[i].pc_and_state);
356   }
357   return offset;
358 }
359
360
361 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
362   // Fill in the deoptimization information.
363   ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
364   if (!info_->HasDeoptimizationSupport()) return;
365   int length = bailout_entries_.length();
366   Handle<DeoptimizationOutputData> data = isolate()->factory()->
367       NewDeoptimizationOutputData(length, TENURED);
368   for (int i = 0; i < length; i++) {
369     data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id));
370     data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
371   }
372   code->set_deoptimization_data(*data);
373 }
374
375
376 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
377   Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
378   info->set_ic_total_count(ic_total_count_);
379   ASSERT(!isolate()->heap()->InNewSpace(*info));
380   code->set_type_feedback_info(*info);
381 }
382
383
384 void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) {
385   if (type_feedback_cells_.is_empty()) return;
386   int length = type_feedback_cells_.length();
387   int array_size = TypeFeedbackCells::LengthOfFixedArray(length);
388   Handle<TypeFeedbackCells> cache = Handle<TypeFeedbackCells>::cast(
389       isolate()->factory()->NewFixedArray(array_size, TENURED));
390   for (int i = 0; i < length; i++) {
391     cache->SetAstId(i, Smi::FromInt(type_feedback_cells_[i].ast_id));
392     cache->SetCell(i, *type_feedback_cells_[i].cell);
393   }
394   TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells(
395       *cache);
396 }
397
398
399
400 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
401   PrepareForBailoutForId(node->id(), state);
402 }
403
404
405 void FullCodeGenerator::RecordJSReturnSite(Call* call) {
406   // We record the offset of the function return so we can rebuild the frame
407   // if the function was inlined, i.e., this is the return address in the
408   // inlined function's frame.
409   //
410   // The state is ignored.  We defensively set it to TOS_REG, which is the
411   // real state of the unoptimized code at the return site.
412   PrepareForBailoutForId(call->ReturnId(), TOS_REG);
413 #ifdef DEBUG
414   // In debug builds, mark the return so we can verify that this function
415   // was called.
416   ASSERT(!call->return_is_recorded_);
417   call->return_is_recorded_ = true;
418 #endif
419 }
420
421
422 void FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) {
423   // There's no need to prepare this code for bailouts from already optimized
424   // code or code that can't be optimized.
425   if (!info_->HasDeoptimizationSupport()) return;
426   unsigned pc_and_state =
427       StateField::encode(state) | PcField::encode(masm_->pc_offset());
428   ASSERT(Smi::IsValid(pc_and_state));
429   BailoutEntry entry = { id, pc_and_state };
430 #ifdef DEBUG
431   if (FLAG_enable_slow_asserts) {
432     // Assert that we don't have multiple bailout entries for the same node.
433     for (int i = 0; i < bailout_entries_.length(); i++) {
434       if (bailout_entries_.at(i).id == entry.id) {
435         AstPrinter printer;
436         PrintF("%s", printer.PrintProgram(info_->function()));
437         UNREACHABLE();
438       }
439     }
440   }
441 #endif  // DEBUG
442   bailout_entries_.Add(entry);
443 }
444
445
446 void FullCodeGenerator::RecordTypeFeedbackCell(
447     unsigned id, Handle<JSGlobalPropertyCell> cell) {
448   TypeFeedbackCellEntry entry = { id, cell };
449   type_feedback_cells_.Add(entry);
450 }
451
452
453 void FullCodeGenerator::RecordStackCheck(unsigned ast_id) {
454   // The pc offset does not need to be encoded and packed together with a
455   // state.
456   ASSERT(masm_->pc_offset() > 0);
457   BailoutEntry entry = { ast_id, static_cast<unsigned>(masm_->pc_offset()) };
458   stack_checks_.Add(entry);
459 }
460
461
462 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) {
463   // Inline smi case inside loops, but not division and modulo which
464   // are too complicated and take up too much space.
465   if (op == Token::DIV ||op == Token::MOD) return false;
466   if (FLAG_always_inline_smi_code) return true;
467   return loop_depth_ > 0;
468 }
469
470
471 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
472 }
473
474
475 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
476   __ Move(result_register(), reg);
477 }
478
479
480 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
481   __ push(reg);
482 }
483
484
485 void FullCodeGenerator::TestContext::Plug(Register reg) const {
486   // For simplicity we always test the accumulator register.
487   __ Move(result_register(), reg);
488   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
489   codegen()->DoTest(this);
490 }
491
492
493 void FullCodeGenerator::EffectContext::PlugTOS() const {
494   __ Drop(1);
495 }
496
497
498 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
499   __ pop(result_register());
500 }
501
502
503 void FullCodeGenerator::StackValueContext::PlugTOS() const {
504 }
505
506
507 void FullCodeGenerator::TestContext::PlugTOS() const {
508   // For simplicity we always test the accumulator register.
509   __ pop(result_register());
510   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
511   codegen()->DoTest(this);
512 }
513
514
515 void FullCodeGenerator::EffectContext::PrepareTest(
516     Label* materialize_true,
517     Label* materialize_false,
518     Label** if_true,
519     Label** if_false,
520     Label** fall_through) const {
521   // In an effect context, the true and the false case branch to the
522   // same label.
523   *if_true = *if_false = *fall_through = materialize_true;
524 }
525
526
527 void FullCodeGenerator::AccumulatorValueContext::PrepareTest(
528     Label* materialize_true,
529     Label* materialize_false,
530     Label** if_true,
531     Label** if_false,
532     Label** fall_through) const {
533   *if_true = *fall_through = materialize_true;
534   *if_false = materialize_false;
535 }
536
537
538 void FullCodeGenerator::StackValueContext::PrepareTest(
539     Label* materialize_true,
540     Label* materialize_false,
541     Label** if_true,
542     Label** if_false,
543     Label** fall_through) const {
544   *if_true = *fall_through = materialize_true;
545   *if_false = materialize_false;
546 }
547
548
549 void FullCodeGenerator::TestContext::PrepareTest(
550     Label* materialize_true,
551     Label* materialize_false,
552     Label** if_true,
553     Label** if_false,
554     Label** fall_through) const {
555   *if_true = true_label_;
556   *if_false = false_label_;
557   *fall_through = fall_through_;
558 }
559
560
561 void FullCodeGenerator::DoTest(const TestContext* context) {
562   DoTest(context->condition(),
563          context->true_label(),
564          context->false_label(),
565          context->fall_through());
566 }
567
568
569 void FullCodeGenerator::VisitDeclarations(
570     ZoneList<Declaration*>* declarations) {
571   int save_global_count = global_count_;
572   global_count_ = 0;
573
574   AstVisitor::VisitDeclarations(declarations);
575
576   // Batch declare global functions and variables.
577   if (global_count_ > 0) {
578     Handle<FixedArray> array =
579        isolate()->factory()->NewFixedArray(3 * global_count_, TENURED);
580     int length = declarations->length();
581     for (int j = 0, i = 0; i < length; i++) {
582       Declaration* decl = declarations->at(i);
583       Variable* var = decl->proxy()->var();
584
585       if (var->IsUnallocated()) {
586         array->set(j++, *(var->name()));
587         FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
588         if (fun_decl == NULL) {
589           if (var->binding_needs_init()) {
590             // In case this binding needs initialization use the hole.
591             array->set_the_hole(j++);
592           } else {
593             array->set_undefined(j++);
594           }
595         } else {
596           Handle<SharedFunctionInfo> function =
597               Compiler::BuildFunctionInfo(fun_decl->fun(), script());
598           // Check for stack-overflow exception.
599           if (function.is_null()) {
600             SetStackOverflow();
601             return;
602           }
603           array->set(j++, *function);
604         }
605         array->set(j++, Smi::FromInt(var->is_qml_global()));
606       }
607     }
608     // Invoke the platform-dependent code generator to do the actual
609     // declaration the global functions and variables.
610     DeclareGlobals(array);
611   }
612
613   global_count_ = save_global_count;
614 }
615
616
617 void FullCodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
618   EmitDeclaration(decl->proxy(), decl->mode(), NULL);
619 }
620
621
622 void FullCodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
623   EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
624 }
625
626
627 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* decl) {
628   EmitDeclaration(decl->proxy(), decl->mode(), NULL);
629 }
630
631
632 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
633   EmitDeclaration(decl->proxy(), decl->mode(), NULL);
634 }
635
636
637 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
638   // TODO(rossberg)
639 }
640
641
642 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
643   // TODO(rossberg)
644 }
645
646
647 void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
648   // TODO(rossberg)
649 }
650
651
652 void FullCodeGenerator::VisitModulePath(ModulePath* module) {
653   // TODO(rossberg)
654 }
655
656
657 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* decl) {
658   // TODO(rossberg)
659 }
660
661
662 int FullCodeGenerator::DeclareGlobalsFlags() {
663   ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode()));
664   return DeclareGlobalsEvalFlag::encode(is_eval()) |
665       DeclareGlobalsNativeFlag::encode(is_native()) |
666       DeclareGlobalsLanguageMode::encode(language_mode());
667 }
668
669
670 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
671   CodeGenerator::RecordPositions(masm_, fun->start_position());
672 }
673
674
675 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
676   CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
677 }
678
679
680 void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
681 #ifdef ENABLE_DEBUGGER_SUPPORT
682   if (!isolate()->debugger()->IsDebuggerActive()) {
683     CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
684   } else {
685     // Check if the statement will be breakable without adding a debug break
686     // slot.
687     BreakableStatementChecker checker;
688     checker.Check(stmt);
689     // Record the statement position right here if the statement is not
690     // breakable. For breakable statements the actual recording of the
691     // position will be postponed to the breakable code (typically an IC).
692     bool position_recorded = CodeGenerator::RecordPositions(
693         masm_, stmt->statement_pos(), !checker.is_breakable());
694     // If the position recording did record a new position generate a debug
695     // break slot to make the statement breakable.
696     if (position_recorded) {
697       Debug::GenerateSlot(masm_);
698     }
699   }
700 #else
701   CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
702 #endif
703 }
704
705
706 void FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) {
707 #ifdef ENABLE_DEBUGGER_SUPPORT
708   if (!isolate()->debugger()->IsDebuggerActive()) {
709     CodeGenerator::RecordPositions(masm_, pos);
710   } else {
711     // Check if the expression will be breakable without adding a debug break
712     // slot.
713     BreakableStatementChecker checker;
714     checker.Check(expr);
715     // Record a statement position right here if the expression is not
716     // breakable. For breakable expressions the actual recording of the
717     // position will be postponed to the breakable code (typically an IC).
718     // NOTE this will record a statement position for something which might
719     // not be a statement. As stepping in the debugger will only stop at
720     // statement positions this is used for e.g. the condition expression of
721     // a do while loop.
722     bool position_recorded = CodeGenerator::RecordPositions(
723         masm_, pos, !checker.is_breakable());
724     // If the position recording did record a new position generate a debug
725     // break slot to make the statement breakable.
726     if (position_recorded) {
727       Debug::GenerateSlot(masm_);
728     }
729   }
730 #else
731   CodeGenerator::RecordPositions(masm_, pos);
732 #endif
733 }
734
735
736 void FullCodeGenerator::SetStatementPosition(int pos) {
737   CodeGenerator::RecordPositions(masm_, pos);
738 }
739
740
741 void FullCodeGenerator::SetSourcePosition(int pos) {
742   if (pos != RelocInfo::kNoPosition) {
743     masm_->positions_recorder()->RecordPosition(pos);
744   }
745 }
746
747
748 // Lookup table for code generators for  special runtime calls which are
749 // generated inline.
750 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize)          \
751     &FullCodeGenerator::Emit##Name,
752
753 const FullCodeGenerator::InlineFunctionGenerator
754   FullCodeGenerator::kInlineFunctionGenerators[] = {
755     INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
756     INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
757   };
758 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
759
760
761 FullCodeGenerator::InlineFunctionGenerator
762   FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
763     int lookup_index =
764         static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction);
765     ASSERT(lookup_index >= 0);
766     ASSERT(static_cast<size_t>(lookup_index) <
767            ARRAY_SIZE(kInlineFunctionGenerators));
768     return kInlineFunctionGenerators[lookup_index];
769 }
770
771
772 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
773   const Runtime::Function* function = expr->function();
774   ASSERT(function != NULL);
775   ASSERT(function->intrinsic_type == Runtime::INLINE);
776   InlineFunctionGenerator generator =
777       FindInlineFunctionGenerator(function->function_id);
778   ((*this).*(generator))(expr);
779 }
780
781
782 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
783   switch (expr->op()) {
784     case Token::COMMA:
785       return VisitComma(expr);
786     case Token::OR:
787     case Token::AND:
788       return VisitLogicalExpression(expr);
789     default:
790       return VisitArithmeticExpression(expr);
791   }
792 }
793
794
795 void FullCodeGenerator::VisitInDuplicateContext(Expression* expr) {
796   if (context()->IsEffect()) {
797     VisitForEffect(expr);
798   } else if (context()->IsAccumulatorValue()) {
799     VisitForAccumulatorValue(expr);
800   } else if (context()->IsStackValue()) {
801     VisitForStackValue(expr);
802   } else if (context()->IsTest()) {
803     const TestContext* test = TestContext::cast(context());
804     VisitForControl(expr, test->true_label(), test->false_label(),
805                     test->fall_through());
806   }
807 }
808
809
810 void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
811   Comment cmnt(masm_, "[ Comma");
812   VisitForEffect(expr->left());
813   VisitInDuplicateContext(expr->right());
814 }
815
816
817 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
818   bool is_logical_and = expr->op() == Token::AND;
819   Comment cmnt(masm_, is_logical_and ? "[ Logical AND" :  "[ Logical OR");
820   Expression* left = expr->left();
821   Expression* right = expr->right();
822   int right_id = expr->RightId();
823   Label done;
824
825   if (context()->IsTest()) {
826     Label eval_right;
827     const TestContext* test = TestContext::cast(context());
828     if (is_logical_and) {
829       VisitForControl(left, &eval_right, test->false_label(), &eval_right);
830     } else {
831       VisitForControl(left, test->true_label(), &eval_right, &eval_right);
832     }
833     PrepareForBailoutForId(right_id, NO_REGISTERS);
834     __ bind(&eval_right);
835
836   } else if (context()->IsAccumulatorValue()) {
837     VisitForAccumulatorValue(left);
838     // We want the value in the accumulator for the test, and on the stack in
839     // case we need it.
840     __ push(result_register());
841     Label discard, restore;
842     if (is_logical_and) {
843       DoTest(left, &discard, &restore, &restore);
844     } else {
845       DoTest(left, &restore, &discard, &restore);
846     }
847     __ bind(&restore);
848     __ pop(result_register());
849     __ jmp(&done);
850     __ bind(&discard);
851     __ Drop(1);
852     PrepareForBailoutForId(right_id, NO_REGISTERS);
853
854   } else if (context()->IsStackValue()) {
855     VisitForAccumulatorValue(left);
856     // We want the value in the accumulator for the test, and on the stack in
857     // case we need it.
858     __ push(result_register());
859     Label discard;
860     if (is_logical_and) {
861       DoTest(left, &discard, &done, &discard);
862     } else {
863       DoTest(left, &done, &discard, &discard);
864     }
865     __ bind(&discard);
866     __ Drop(1);
867     PrepareForBailoutForId(right_id, NO_REGISTERS);
868
869   } else {
870     ASSERT(context()->IsEffect());
871     Label eval_right;
872     if (is_logical_and) {
873       VisitForControl(left, &eval_right, &done, &eval_right);
874     } else {
875       VisitForControl(left, &done, &eval_right, &eval_right);
876     }
877     PrepareForBailoutForId(right_id, NO_REGISTERS);
878     __ bind(&eval_right);
879   }
880
881   VisitInDuplicateContext(right);
882   __ bind(&done);
883 }
884
885
886 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
887   Token::Value op = expr->op();
888   Comment cmnt(masm_, "[ ArithmeticExpression");
889   Expression* left = expr->left();
890   Expression* right = expr->right();
891   OverwriteMode mode =
892       left->ResultOverwriteAllowed()
893       ? OVERWRITE_LEFT
894       : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE);
895
896   VisitForStackValue(left);
897   VisitForAccumulatorValue(right);
898
899   SetSourcePosition(expr->position());
900   if (ShouldInlineSmiCase(op)) {
901     EmitInlineSmiBinaryOp(expr, op, mode, left, right);
902   } else {
903     EmitBinaryOp(expr, op, mode);
904   }
905 }
906
907
908 void FullCodeGenerator::VisitBlock(Block* stmt) {
909   Comment cmnt(masm_, "[ Block");
910   NestedBlock nested_block(this, stmt);
911   SetStatementPosition(stmt);
912
913   Scope* saved_scope = scope();
914   // Push a block context when entering a block with block scoped variables.
915   if (stmt->block_scope() != NULL) {
916     { Comment cmnt(masm_, "[ Extend block context");
917       scope_ = stmt->block_scope();
918       Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
919       int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
920       __ Push(scope_info);
921       PushFunctionArgumentForContextAllocation();
922       if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) {
923         FastNewBlockContextStub stub(heap_slots);
924         __ CallStub(&stub);
925       } else {
926         __ CallRuntime(Runtime::kPushBlockContext, 2);
927       }
928
929       // Replace the context stored in the frame.
930       StoreToFrameField(StandardFrameConstants::kContextOffset,
931                         context_register());
932     }
933     { Comment cmnt(masm_, "[ Declarations");
934       VisitDeclarations(scope_->declarations());
935     }
936   }
937   PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
938   VisitStatements(stmt->statements());
939   scope_ = saved_scope;
940   __ bind(nested_block.break_label());
941   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
942
943   // Pop block context if necessary.
944   if (stmt->block_scope() != NULL) {
945     LoadContextField(context_register(), Context::PREVIOUS_INDEX);
946     // Update local stack frame context field.
947     StoreToFrameField(StandardFrameConstants::kContextOffset,
948                       context_register());
949   }
950 }
951
952
953 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
954   Comment cmnt(masm_, "[ ExpressionStatement");
955   SetStatementPosition(stmt);
956   VisitForEffect(stmt->expression());
957 }
958
959
960 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
961   Comment cmnt(masm_, "[ EmptyStatement");
962   SetStatementPosition(stmt);
963 }
964
965
966 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
967   Comment cmnt(masm_, "[ IfStatement");
968   SetStatementPosition(stmt);
969   Label then_part, else_part, done;
970
971   if (stmt->HasElseStatement()) {
972     VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
973     PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
974     __ bind(&then_part);
975     Visit(stmt->then_statement());
976     __ jmp(&done);
977
978     PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
979     __ bind(&else_part);
980     Visit(stmt->else_statement());
981   } else {
982     VisitForControl(stmt->condition(), &then_part, &done, &then_part);
983     PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
984     __ bind(&then_part);
985     Visit(stmt->then_statement());
986
987     PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
988   }
989   __ bind(&done);
990   PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS);
991 }
992
993
994 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
995   Comment cmnt(masm_,  "[ ContinueStatement");
996   SetStatementPosition(stmt);
997   NestedStatement* current = nesting_stack_;
998   int stack_depth = 0;
999   int context_length = 0;
1000   // When continuing, we clobber the unpredictable value in the accumulator
1001   // with one that's safe for GC.  If we hit an exit from the try block of
1002   // try...finally on our way out, we will unconditionally preserve the
1003   // accumulator on the stack.
1004   ClearAccumulator();
1005   while (!current->IsContinueTarget(stmt->target())) {
1006     current = current->Exit(&stack_depth, &context_length);
1007   }
1008   __ Drop(stack_depth);
1009   if (context_length > 0) {
1010     while (context_length > 0) {
1011       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1012       --context_length;
1013     }
1014     StoreToFrameField(StandardFrameConstants::kContextOffset,
1015                       context_register());
1016   }
1017
1018   __ jmp(current->AsIteration()->continue_label());
1019 }
1020
1021
1022 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
1023   Comment cmnt(masm_,  "[ BreakStatement");
1024   SetStatementPosition(stmt);
1025   NestedStatement* current = nesting_stack_;
1026   int stack_depth = 0;
1027   int context_length = 0;
1028   // When breaking, we clobber the unpredictable value in the accumulator
1029   // with one that's safe for GC.  If we hit an exit from the try block of
1030   // try...finally on our way out, we will unconditionally preserve the
1031   // accumulator on the stack.
1032   ClearAccumulator();
1033   while (!current->IsBreakTarget(stmt->target())) {
1034     current = current->Exit(&stack_depth, &context_length);
1035   }
1036   __ Drop(stack_depth);
1037   if (context_length > 0) {
1038     while (context_length > 0) {
1039       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1040       --context_length;
1041     }
1042     StoreToFrameField(StandardFrameConstants::kContextOffset,
1043                       context_register());
1044   }
1045
1046   __ jmp(current->AsBreakable()->break_label());
1047 }
1048
1049
1050 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
1051   Comment cmnt(masm_, "[ ReturnStatement");
1052   SetStatementPosition(stmt);
1053   Expression* expr = stmt->expression();
1054   VisitForAccumulatorValue(expr);
1055
1056   // Exit all nested statements.
1057   NestedStatement* current = nesting_stack_;
1058   int stack_depth = 0;
1059   int context_length = 0;
1060   while (current != NULL) {
1061     current = current->Exit(&stack_depth, &context_length);
1062   }
1063   __ Drop(stack_depth);
1064
1065   EmitReturnSequence();
1066 }
1067
1068
1069 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
1070   Comment cmnt(masm_, "[ WithStatement");
1071   SetStatementPosition(stmt);
1072
1073   VisitForStackValue(stmt->expression());
1074   PushFunctionArgumentForContextAllocation();
1075   __ CallRuntime(Runtime::kPushWithContext, 2);
1076   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1077
1078   { WithOrCatch body(this);
1079     Visit(stmt->statement());
1080   }
1081
1082   // Pop context.
1083   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1084   // Update local stack frame context field.
1085   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1086 }
1087
1088
1089 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
1090   Comment cmnt(masm_, "[ DoWhileStatement");
1091   SetStatementPosition(stmt);
1092   Label body, stack_check;
1093
1094   Iteration loop_statement(this, stmt);
1095   increment_loop_depth();
1096
1097   __ bind(&body);
1098   Visit(stmt->body());
1099
1100   // Record the position of the do while condition and make sure it is
1101   // possible to break on the condition.
1102   __ bind(loop_statement.continue_label());
1103   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1104   SetExpressionPosition(stmt->cond(), stmt->condition_position());
1105   VisitForControl(stmt->cond(),
1106                   &stack_check,
1107                   loop_statement.break_label(),
1108                   &stack_check);
1109
1110   // Check stack before looping.
1111   PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
1112   __ bind(&stack_check);
1113   EmitStackCheck(stmt, &body);
1114   __ jmp(&body);
1115
1116   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1117   __ bind(loop_statement.break_label());
1118   decrement_loop_depth();
1119 }
1120
1121
1122 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
1123   Comment cmnt(masm_, "[ WhileStatement");
1124   Label test, body;
1125
1126   Iteration loop_statement(this, stmt);
1127   increment_loop_depth();
1128
1129   // Emit the test at the bottom of the loop.
1130   __ jmp(&test);
1131
1132   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1133   __ bind(&body);
1134   Visit(stmt->body());
1135
1136   // Emit the statement position here as this is where the while
1137   // statement code starts.
1138   __ bind(loop_statement.continue_label());
1139   SetStatementPosition(stmt);
1140
1141   // Check stack before looping.
1142   EmitStackCheck(stmt, &body);
1143
1144   __ bind(&test);
1145   VisitForControl(stmt->cond(),
1146                   &body,
1147                   loop_statement.break_label(),
1148                   loop_statement.break_label());
1149
1150   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1151   __ bind(loop_statement.break_label());
1152   decrement_loop_depth();
1153 }
1154
1155
1156 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
1157   Comment cmnt(masm_, "[ ForStatement");
1158   Label test, body;
1159
1160   Iteration loop_statement(this, stmt);
1161
1162   // Set statement position for a break slot before entering the for-body.
1163   SetStatementPosition(stmt);
1164
1165   if (stmt->init() != NULL) {
1166     Visit(stmt->init());
1167   }
1168
1169   increment_loop_depth();
1170   // Emit the test at the bottom of the loop (even if empty).
1171   __ jmp(&test);
1172
1173   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1174   __ bind(&body);
1175   Visit(stmt->body());
1176
1177   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
1178   __ bind(loop_statement.continue_label());
1179   if (stmt->next() != NULL) {
1180     Visit(stmt->next());
1181   }
1182
1183   // Emit the statement position here as this is where the for
1184   // statement code starts.
1185   SetStatementPosition(stmt);
1186
1187   // Check stack before looping.
1188   EmitStackCheck(stmt, &body);
1189
1190   __ bind(&test);
1191   if (stmt->cond() != NULL) {
1192     VisitForControl(stmt->cond(),
1193                     &body,
1194                     loop_statement.break_label(),
1195                     loop_statement.break_label());
1196   } else {
1197     __ jmp(&body);
1198   }
1199
1200   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1201   __ bind(loop_statement.break_label());
1202   decrement_loop_depth();
1203 }
1204
1205
1206 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1207   Comment cmnt(masm_, "[ TryCatchStatement");
1208   SetStatementPosition(stmt);
1209   // The try block adds a handler to the exception handler chain before
1210   // entering, and removes it again when exiting normally.  If an exception
1211   // is thrown during execution of the try block, the handler is consumed
1212   // and control is passed to the catch block with the exception in the
1213   // result register.
1214
1215   Label try_entry, handler_entry, exit;
1216   __ jmp(&try_entry);
1217   __ bind(&handler_entry);
1218   handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
1219   // Exception handler code, the exception is in the result register.
1220   // Extend the context before executing the catch block.
1221   { Comment cmnt(masm_, "[ Extend catch context");
1222     __ Push(stmt->variable()->name());
1223     __ push(result_register());
1224     PushFunctionArgumentForContextAllocation();
1225     __ CallRuntime(Runtime::kPushCatchContext, 3);
1226     StoreToFrameField(StandardFrameConstants::kContextOffset,
1227                       context_register());
1228   }
1229
1230   Scope* saved_scope = scope();
1231   scope_ = stmt->scope();
1232   ASSERT(scope_->declarations()->is_empty());
1233   { WithOrCatch catch_body(this);
1234     Visit(stmt->catch_block());
1235   }
1236   // Restore the context.
1237   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
1238   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
1239   scope_ = saved_scope;
1240   __ jmp(&exit);
1241
1242   // Try block code. Sets up the exception handler chain.
1243   __ bind(&try_entry);
1244   __ PushTryHandler(StackHandler::CATCH, stmt->index());
1245   { TryCatch try_body(this);
1246     Visit(stmt->try_block());
1247   }
1248   __ PopTryHandler();
1249   __ bind(&exit);
1250 }
1251
1252
1253 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1254   Comment cmnt(masm_, "[ TryFinallyStatement");
1255   SetStatementPosition(stmt);
1256   // Try finally is compiled by setting up a try-handler on the stack while
1257   // executing the try body, and removing it again afterwards.
1258   //
1259   // The try-finally construct can enter the finally block in three ways:
1260   // 1. By exiting the try-block normally. This removes the try-handler and
1261   //    calls the finally block code before continuing.
1262   // 2. By exiting the try-block with a function-local control flow transfer
1263   //    (break/continue/return). The site of the, e.g., break removes the
1264   //    try handler and calls the finally block code before continuing
1265   //    its outward control transfer.
1266   // 3. By exiting the try-block with a thrown exception.
1267   //    This can happen in nested function calls. It traverses the try-handler
1268   //    chain and consumes the try-handler entry before jumping to the
1269   //    handler code. The handler code then calls the finally-block before
1270   //    rethrowing the exception.
1271   //
1272   // The finally block must assume a return address on top of the stack
1273   // (or in the link register on ARM chips) and a value (return value or
1274   // exception) in the result register (rax/eax/r0), both of which must
1275   // be preserved. The return address isn't GC-safe, so it should be
1276   // cooked before GC.
1277   Label try_entry, handler_entry, finally_entry;
1278
1279   // Jump to try-handler setup and try-block code.
1280   __ jmp(&try_entry);
1281   __ bind(&handler_entry);
1282   handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
1283   // Exception handler code.  This code is only executed when an exception
1284   // is thrown.  The exception is in the result register, and must be
1285   // preserved by the finally block.  Call the finally block and then
1286   // rethrow the exception if it returns.
1287   __ Call(&finally_entry);
1288   __ push(result_register());
1289   __ CallRuntime(Runtime::kReThrow, 1);
1290
1291   // Finally block implementation.
1292   __ bind(&finally_entry);
1293   EnterFinallyBlock();
1294   { Finally finally_body(this);
1295     Visit(stmt->finally_block());
1296   }
1297   ExitFinallyBlock();  // Return to the calling code.
1298
1299   // Set up try handler.
1300   __ bind(&try_entry);
1301   __ PushTryHandler(StackHandler::FINALLY, stmt->index());
1302   { TryFinally try_body(this, &finally_entry);
1303     Visit(stmt->try_block());
1304   }
1305   __ PopTryHandler();
1306   // Execute the finally block on the way out.  Clobber the unpredictable
1307   // value in the result register with one that's safe for GC because the
1308   // finally block will unconditionally preserve the result register on the
1309   // stack.
1310   ClearAccumulator();
1311   __ Call(&finally_entry);
1312 }
1313
1314
1315 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1316 #ifdef ENABLE_DEBUGGER_SUPPORT
1317   Comment cmnt(masm_, "[ DebuggerStatement");
1318   SetStatementPosition(stmt);
1319
1320   __ DebugBreak();
1321   // Ignore the return value.
1322 #endif
1323 }
1324
1325
1326 void FullCodeGenerator::VisitConditional(Conditional* expr) {
1327   Comment cmnt(masm_, "[ Conditional");
1328   Label true_case, false_case, done;
1329   VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
1330
1331   PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS);
1332   __ bind(&true_case);
1333   SetExpressionPosition(expr->then_expression(),
1334                         expr->then_expression_position());
1335   if (context()->IsTest()) {
1336     const TestContext* for_test = TestContext::cast(context());
1337     VisitForControl(expr->then_expression(),
1338                     for_test->true_label(),
1339                     for_test->false_label(),
1340                     NULL);
1341   } else {
1342     VisitInDuplicateContext(expr->then_expression());
1343     __ jmp(&done);
1344   }
1345
1346   PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
1347   __ bind(&false_case);
1348   SetExpressionPosition(expr->else_expression(),
1349                         expr->else_expression_position());
1350   VisitInDuplicateContext(expr->else_expression());
1351   // If control flow falls through Visit, merge it with true case here.
1352   if (!context()->IsTest()) {
1353     __ bind(&done);
1354   }
1355 }
1356
1357
1358 void FullCodeGenerator::VisitLiteral(Literal* expr) {
1359   Comment cmnt(masm_, "[ Literal");
1360   context()->Plug(expr->handle());
1361 }
1362
1363
1364 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1365   Comment cmnt(masm_, "[ FunctionLiteral");
1366
1367   // Build the function boilerplate and instantiate it.
1368   Handle<SharedFunctionInfo> function_info =
1369       Compiler::BuildFunctionInfo(expr, script());
1370   if (function_info.is_null()) {
1371     SetStackOverflow();
1372     return;
1373   }
1374   EmitNewClosure(function_info, expr->pretenure());
1375 }
1376
1377
1378 void FullCodeGenerator::VisitSharedFunctionInfoLiteral(
1379     SharedFunctionInfoLiteral* expr) {
1380   Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
1381   EmitNewClosure(expr->shared_function_info(), false);
1382 }
1383
1384
1385 void FullCodeGenerator::VisitThrow(Throw* expr) {
1386   Comment cmnt(masm_, "[ Throw");
1387   VisitForStackValue(expr->exception());
1388   __ CallRuntime(Runtime::kThrow, 1);
1389   // Never returns here.
1390 }
1391
1392
1393 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
1394     int* stack_depth,
1395     int* context_length) {
1396   // The macros used here must preserve the result register.
1397   __ Drop(*stack_depth);
1398   __ PopTryHandler();
1399   *stack_depth = 0;
1400   return previous_;
1401 }
1402
1403
1404 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
1405   Expression* sub_expr;
1406   Handle<String> check;
1407   if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
1408     EmitLiteralCompareTypeof(expr, sub_expr, check);
1409     return true;
1410   }
1411
1412   if (expr->IsLiteralCompareUndefined(&sub_expr)) {
1413     EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
1414     return true;
1415   }
1416
1417   if (expr->IsLiteralCompareNull(&sub_expr)) {
1418     EmitLiteralCompareNil(expr, sub_expr, kNullValue);
1419     return true;
1420   }
1421
1422   return false;
1423 }
1424
1425
1426 #undef __
1427
1428
1429 } }  // namespace v8::internal