Home | History | Annotate | Download | only in src
      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                         info->function()->scope()->AllowsLazyRecompilation());
    319   code->set_self_optimization_header(cgen.has_self_optimization_header_);
    320   cgen.PopulateDeoptimizationData(code);
    321   cgen.PopulateTypeFeedbackInfo(code);
    322   cgen.PopulateTypeFeedbackCells(code);
    323   code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
    324   code->set_handler_table(*cgen.handler_table());
    325 #ifdef ENABLE_DEBUGGER_SUPPORT
    326   code->set_has_debug_break_slots(
    327       info->isolate()->debugger()->IsDebuggerActive());
    328   code->set_compiled_optimizable(info->IsOptimizable());
    329 #endif  // ENABLE_DEBUGGER_SUPPORT
    330   code->set_allow_osr_at_loop_nesting_level(0);
    331   code->set_profiler_ticks(0);
    332   code->set_stack_check_table_offset(table_offset);
    333   CodeGenerator::PrintCode(code, info);
    334   info->SetCode(code);  // May be an empty handle.
    335   if (!code.is_null()) {
    336     isolate->runtime_profiler()->NotifyCodeGenerated(code->instruction_size());
    337   }
    338 #ifdef ENABLE_GDB_JIT_INTERFACE
    339   if (FLAG_gdbjit && !code.is_null()) {
    340     GDBJITLineInfo* lineinfo =
    341         masm.positions_recorder()->DetachGDBJITLineInfo();
    342 
    343     GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
    344   }
    345 #endif
    346   return !code.is_null();
    347 }
    348 
    349 
    350 unsigned FullCodeGenerator::EmitStackCheckTable() {
    351   // The stack check table consists of a length (in number of entries)
    352   // field, and then a sequence of entries.  Each entry is a pair of AST id
    353   // and code-relative pc offset.
    354   masm()->Align(kIntSize);
    355   unsigned offset = masm()->pc_offset();
    356   unsigned length = stack_checks_.length();
    357   __ dd(length);
    358   for (unsigned i = 0; i < length; ++i) {
    359     __ dd(stack_checks_[i].id);
    360     __ dd(stack_checks_[i].pc_and_state);
    361   }
    362   return offset;
    363 }
    364 
    365 
    366 void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
    367   // Fill in the deoptimization information.
    368   ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
    369   if (!info_->HasDeoptimizationSupport()) return;
    370   int length = bailout_entries_.length();
    371   Handle<DeoptimizationOutputData> data = isolate()->factory()->
    372       NewDeoptimizationOutputData(length, TENURED);
    373   for (int i = 0; i < length; i++) {
    374     data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id));
    375     data->SetPcAndState(i, Smi::FromInt(bailout_entries_[i].pc_and_state));
    376   }
    377   code->set_deoptimization_data(*data);
    378 }
    379 
    380 
    381 void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
    382   Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
    383   info->set_ic_total_count(ic_total_count_);
    384   ASSERT(!isolate()->heap()->InNewSpace(*info));
    385   code->set_type_feedback_info(*info);
    386 }
    387 
    388 
    389 void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) {
    390   if (type_feedback_cells_.is_empty()) return;
    391   int length = type_feedback_cells_.length();
    392   int array_size = TypeFeedbackCells::LengthOfFixedArray(length);
    393   Handle<TypeFeedbackCells> cache = Handle<TypeFeedbackCells>::cast(
    394       isolate()->factory()->NewFixedArray(array_size, TENURED));
    395   for (int i = 0; i < length; i++) {
    396     cache->SetAstId(i, Smi::FromInt(type_feedback_cells_[i].ast_id));
    397     cache->SetCell(i, *type_feedback_cells_[i].cell);
    398   }
    399   TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells(
    400       *cache);
    401 }
    402 
    403 
    404 
    405 void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
    406   PrepareForBailoutForId(node->id(), state);
    407 }
    408 
    409 
    410 void FullCodeGenerator::RecordJSReturnSite(Call* call) {
    411   // We record the offset of the function return so we can rebuild the frame
    412   // if the function was inlined, i.e., this is the return address in the
    413   // inlined function's frame.
    414   //
    415   // The state is ignored.  We defensively set it to TOS_REG, which is the
    416   // real state of the unoptimized code at the return site.
    417   PrepareForBailoutForId(call->ReturnId(), TOS_REG);
    418 #ifdef DEBUG
    419   // In debug builds, mark the return so we can verify that this function
    420   // was called.
    421   ASSERT(!call->return_is_recorded_);
    422   call->return_is_recorded_ = true;
    423 #endif
    424 }
    425 
    426 
    427 void FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) {
    428   // There's no need to prepare this code for bailouts from already optimized
    429   // code or code that can't be optimized.
    430   if (!info_->HasDeoptimizationSupport()) return;
    431   unsigned pc_and_state =
    432       StateField::encode(state) | PcField::encode(masm_->pc_offset());
    433   ASSERT(Smi::IsValid(pc_and_state));
    434   BailoutEntry entry = { id, pc_and_state };
    435 #ifdef DEBUG
    436   if (FLAG_enable_slow_asserts) {
    437     // Assert that we don't have multiple bailout entries for the same node.
    438     for (int i = 0; i < bailout_entries_.length(); i++) {
    439       if (bailout_entries_.at(i).id == entry.id) {
    440         AstPrinter printer;
    441         PrintF("%s", printer.PrintProgram(info_->function()));
    442         UNREACHABLE();
    443       }
    444     }
    445   }
    446 #endif  // DEBUG
    447   bailout_entries_.Add(entry);
    448 }
    449 
    450 
    451 void FullCodeGenerator::RecordTypeFeedbackCell(
    452     unsigned id, Handle<JSGlobalPropertyCell> cell) {
    453   TypeFeedbackCellEntry entry = { id, cell };
    454   type_feedback_cells_.Add(entry);
    455 }
    456 
    457 
    458 void FullCodeGenerator::RecordStackCheck(unsigned ast_id) {
    459   // The pc offset does not need to be encoded and packed together with a
    460   // state.
    461   ASSERT(masm_->pc_offset() > 0);
    462   BailoutEntry entry = { ast_id, static_cast<unsigned>(masm_->pc_offset()) };
    463   stack_checks_.Add(entry);
    464 }
    465 
    466 
    467 bool FullCodeGenerator::ShouldInlineSmiCase(Token::Value op) {
    468   // Inline smi case inside loops, but not division and modulo which
    469   // are too complicated and take up too much space.
    470   if (op == Token::DIV ||op == Token::MOD) return false;
    471   if (FLAG_always_inline_smi_code) return true;
    472   return loop_depth_ > 0;
    473 }
    474 
    475 
    476 void FullCodeGenerator::EffectContext::Plug(Register reg) const {
    477 }
    478 
    479 
    480 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const {
    481   __ Move(result_register(), reg);
    482 }
    483 
    484 
    485 void FullCodeGenerator::StackValueContext::Plug(Register reg) const {
    486   __ push(reg);
    487 }
    488 
    489 
    490 void FullCodeGenerator::TestContext::Plug(Register reg) const {
    491   // For simplicity we always test the accumulator register.
    492   __ Move(result_register(), reg);
    493   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
    494   codegen()->DoTest(this);
    495 }
    496 
    497 
    498 void FullCodeGenerator::EffectContext::PlugTOS() const {
    499   __ Drop(1);
    500 }
    501 
    502 
    503 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const {
    504   __ pop(result_register());
    505 }
    506 
    507 
    508 void FullCodeGenerator::StackValueContext::PlugTOS() const {
    509 }
    510 
    511 
    512 void FullCodeGenerator::TestContext::PlugTOS() const {
    513   // For simplicity we always test the accumulator register.
    514   __ pop(result_register());
    515   codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
    516   codegen()->DoTest(this);
    517 }
    518 
    519 
    520 void FullCodeGenerator::EffectContext::PrepareTest(
    521     Label* materialize_true,
    522     Label* materialize_false,
    523     Label** if_true,
    524     Label** if_false,
    525     Label** fall_through) const {
    526   // In an effect context, the true and the false case branch to the
    527   // same label.
    528   *if_true = *if_false = *fall_through = materialize_true;
    529 }
    530 
    531 
    532 void FullCodeGenerator::AccumulatorValueContext::PrepareTest(
    533     Label* materialize_true,
    534     Label* materialize_false,
    535     Label** if_true,
    536     Label** if_false,
    537     Label** fall_through) const {
    538   *if_true = *fall_through = materialize_true;
    539   *if_false = materialize_false;
    540 }
    541 
    542 
    543 void FullCodeGenerator::StackValueContext::PrepareTest(
    544     Label* materialize_true,
    545     Label* materialize_false,
    546     Label** if_true,
    547     Label** if_false,
    548     Label** fall_through) const {
    549   *if_true = *fall_through = materialize_true;
    550   *if_false = materialize_false;
    551 }
    552 
    553 
    554 void FullCodeGenerator::TestContext::PrepareTest(
    555     Label* materialize_true,
    556     Label* materialize_false,
    557     Label** if_true,
    558     Label** if_false,
    559     Label** fall_through) const {
    560   *if_true = true_label_;
    561   *if_false = false_label_;
    562   *fall_through = fall_through_;
    563 }
    564 
    565 
    566 void FullCodeGenerator::DoTest(const TestContext* context) {
    567   DoTest(context->condition(),
    568          context->true_label(),
    569          context->false_label(),
    570          context->fall_through());
    571 }
    572 
    573 
    574 void FullCodeGenerator::VisitDeclarations(
    575     ZoneList<Declaration*>* declarations) {
    576   int save_global_count = global_count_;
    577   global_count_ = 0;
    578 
    579   AstVisitor::VisitDeclarations(declarations);
    580 
    581   // Batch declare global functions and variables.
    582   if (global_count_ > 0) {
    583     Handle<FixedArray> array =
    584        isolate()->factory()->NewFixedArray(2 * global_count_, TENURED);
    585     int length = declarations->length();
    586     for (int j = 0, i = 0; i < length; i++) {
    587       Declaration* decl = declarations->at(i);
    588       Variable* var = decl->proxy()->var();
    589 
    590       if (var->IsUnallocated()) {
    591         array->set(j++, *(var->name()));
    592         FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
    593         if (fun_decl == NULL) {
    594           if (var->binding_needs_init()) {
    595             // In case this binding needs initialization use the hole.
    596             array->set_the_hole(j++);
    597           } else {
    598             array->set_undefined(j++);
    599           }
    600         } else {
    601           Handle<SharedFunctionInfo> function =
    602               Compiler::BuildFunctionInfo(fun_decl->fun(), script());
    603           // Check for stack-overflow exception.
    604           if (function.is_null()) {
    605             SetStackOverflow();
    606             return;
    607           }
    608           array->set(j++, *function);
    609         }
    610       }
    611     }
    612     // Invoke the platform-dependent code generator to do the actual
    613     // declaration the global functions and variables.
    614     DeclareGlobals(array);
    615   }
    616 
    617   global_count_ = save_global_count;
    618 }
    619 
    620 
    621 void FullCodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
    622   EmitDeclaration(decl->proxy(), decl->mode(), NULL);
    623 }
    624 
    625 
    626 void FullCodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
    627   EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
    628 }
    629 
    630 
    631 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* decl) {
    632   EmitDeclaration(decl->proxy(), decl->mode(), NULL);
    633 }
    634 
    635 
    636 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
    637   EmitDeclaration(decl->proxy(), decl->mode(), NULL);
    638 }
    639 
    640 
    641 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
    642   // TODO(rossberg)
    643 }
    644 
    645 
    646 void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
    647   // TODO(rossberg)
    648 }
    649 
    650 
    651 void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
    652   // TODO(rossberg)
    653 }
    654 
    655 
    656 void FullCodeGenerator::VisitModulePath(ModulePath* module) {
    657   // TODO(rossberg)
    658 }
    659 
    660 
    661 void FullCodeGenerator::VisitModuleUrl(ModuleUrl* decl) {
    662   // TODO(rossberg)
    663 }
    664 
    665 
    666 int FullCodeGenerator::DeclareGlobalsFlags() {
    667   ASSERT(DeclareGlobalsLanguageMode::is_valid(language_mode()));
    668   return DeclareGlobalsEvalFlag::encode(is_eval()) |
    669       DeclareGlobalsNativeFlag::encode(is_native()) |
    670       DeclareGlobalsLanguageMode::encode(language_mode());
    671 }
    672 
    673 
    674 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
    675   CodeGenerator::RecordPositions(masm_, fun->start_position());
    676 }
    677 
    678 
    679 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
    680   CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
    681 }
    682 
    683 
    684 void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
    685 #ifdef ENABLE_DEBUGGER_SUPPORT
    686   if (!isolate()->debugger()->IsDebuggerActive()) {
    687     CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
    688   } else {
    689     // Check if the statement will be breakable without adding a debug break
    690     // slot.
    691     BreakableStatementChecker checker;
    692     checker.Check(stmt);
    693     // Record the statement position right here if the statement is not
    694     // breakable. For breakable statements the actual recording of the
    695     // position will be postponed to the breakable code (typically an IC).
    696     bool position_recorded = CodeGenerator::RecordPositions(
    697         masm_, stmt->statement_pos(), !checker.is_breakable());
    698     // If the position recording did record a new position generate a debug
    699     // break slot to make the statement breakable.
    700     if (position_recorded) {
    701       Debug::GenerateSlot(masm_);
    702     }
    703   }
    704 #else
    705   CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
    706 #endif
    707 }
    708 
    709 
    710 void FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) {
    711 #ifdef ENABLE_DEBUGGER_SUPPORT
    712   if (!isolate()->debugger()->IsDebuggerActive()) {
    713     CodeGenerator::RecordPositions(masm_, pos);
    714   } else {
    715     // Check if the expression will be breakable without adding a debug break
    716     // slot.
    717     BreakableStatementChecker checker;
    718     checker.Check(expr);
    719     // Record a statement position right here if the expression is not
    720     // breakable. For breakable expressions the actual recording of the
    721     // position will be postponed to the breakable code (typically an IC).
    722     // NOTE this will record a statement position for something which might
    723     // not be a statement. As stepping in the debugger will only stop at
    724     // statement positions this is used for e.g. the condition expression of
    725     // a do while loop.
    726     bool position_recorded = CodeGenerator::RecordPositions(
    727         masm_, pos, !checker.is_breakable());
    728     // If the position recording did record a new position generate a debug
    729     // break slot to make the statement breakable.
    730     if (position_recorded) {
    731       Debug::GenerateSlot(masm_);
    732     }
    733   }
    734 #else
    735   CodeGenerator::RecordPositions(masm_, pos);
    736 #endif
    737 }
    738 
    739 
    740 void FullCodeGenerator::SetStatementPosition(int pos) {
    741   CodeGenerator::RecordPositions(masm_, pos);
    742 }
    743 
    744 
    745 void FullCodeGenerator::SetSourcePosition(int pos) {
    746   if (pos != RelocInfo::kNoPosition) {
    747     masm_->positions_recorder()->RecordPosition(pos);
    748   }
    749 }
    750 
    751 
    752 // Lookup table for code generators for  special runtime calls which are
    753 // generated inline.
    754 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize)          \
    755     &FullCodeGenerator::Emit##Name,
    756 
    757 const FullCodeGenerator::InlineFunctionGenerator
    758   FullCodeGenerator::kInlineFunctionGenerators[] = {
    759     INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
    760     INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
    761   };
    762 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
    763 
    764 
    765 FullCodeGenerator::InlineFunctionGenerator
    766   FullCodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
    767     int lookup_index =
    768         static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction);
    769     ASSERT(lookup_index >= 0);
    770     ASSERT(static_cast<size_t>(lookup_index) <
    771            ARRAY_SIZE(kInlineFunctionGenerators));
    772     return kInlineFunctionGenerators[lookup_index];
    773 }
    774 
    775 
    776 void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
    777   const Runtime::Function* function = expr->function();
    778   ASSERT(function != NULL);
    779   ASSERT(function->intrinsic_type == Runtime::INLINE);
    780   InlineFunctionGenerator generator =
    781       FindInlineFunctionGenerator(function->function_id);
    782   ((*this).*(generator))(expr);
    783 }
    784 
    785 
    786 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
    787   switch (expr->op()) {
    788     case Token::COMMA:
    789       return VisitComma(expr);
    790     case Token::OR:
    791     case Token::AND:
    792       return VisitLogicalExpression(expr);
    793     default:
    794       return VisitArithmeticExpression(expr);
    795   }
    796 }
    797 
    798 
    799 void FullCodeGenerator::VisitInDuplicateContext(Expression* expr) {
    800   if (context()->IsEffect()) {
    801     VisitForEffect(expr);
    802   } else if (context()->IsAccumulatorValue()) {
    803     VisitForAccumulatorValue(expr);
    804   } else if (context()->IsStackValue()) {
    805     VisitForStackValue(expr);
    806   } else if (context()->IsTest()) {
    807     const TestContext* test = TestContext::cast(context());
    808     VisitForControl(expr, test->true_label(), test->false_label(),
    809                     test->fall_through());
    810   }
    811 }
    812 
    813 
    814 void FullCodeGenerator::VisitComma(BinaryOperation* expr) {
    815   Comment cmnt(masm_, "[ Comma");
    816   VisitForEffect(expr->left());
    817   VisitInDuplicateContext(expr->right());
    818 }
    819 
    820 
    821 void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) {
    822   bool is_logical_and = expr->op() == Token::AND;
    823   Comment cmnt(masm_, is_logical_and ? "[ Logical AND" :  "[ Logical OR");
    824   Expression* left = expr->left();
    825   Expression* right = expr->right();
    826   int right_id = expr->RightId();
    827   Label done;
    828 
    829   if (context()->IsTest()) {
    830     Label eval_right;
    831     const TestContext* test = TestContext::cast(context());
    832     if (is_logical_and) {
    833       VisitForControl(left, &eval_right, test->false_label(), &eval_right);
    834     } else {
    835       VisitForControl(left, test->true_label(), &eval_right, &eval_right);
    836     }
    837     PrepareForBailoutForId(right_id, NO_REGISTERS);
    838     __ bind(&eval_right);
    839 
    840   } else if (context()->IsAccumulatorValue()) {
    841     VisitForAccumulatorValue(left);
    842     // We want the value in the accumulator for the test, and on the stack in
    843     // case we need it.
    844     __ push(result_register());
    845     Label discard, restore;
    846     if (is_logical_and) {
    847       DoTest(left, &discard, &restore, &restore);
    848     } else {
    849       DoTest(left, &restore, &discard, &restore);
    850     }
    851     __ bind(&restore);
    852     __ pop(result_register());
    853     __ jmp(&done);
    854     __ bind(&discard);
    855     __ Drop(1);
    856     PrepareForBailoutForId(right_id, NO_REGISTERS);
    857 
    858   } else if (context()->IsStackValue()) {
    859     VisitForAccumulatorValue(left);
    860     // We want the value in the accumulator for the test, and on the stack in
    861     // case we need it.
    862     __ push(result_register());
    863     Label discard;
    864     if (is_logical_and) {
    865       DoTest(left, &discard, &done, &discard);
    866     } else {
    867       DoTest(left, &done, &discard, &discard);
    868     }
    869     __ bind(&discard);
    870     __ Drop(1);
    871     PrepareForBailoutForId(right_id, NO_REGISTERS);
    872 
    873   } else {
    874     ASSERT(context()->IsEffect());
    875     Label eval_right;
    876     if (is_logical_and) {
    877       VisitForControl(left, &eval_right, &done, &eval_right);
    878     } else {
    879       VisitForControl(left, &done, &eval_right, &eval_right);
    880     }
    881     PrepareForBailoutForId(right_id, NO_REGISTERS);
    882     __ bind(&eval_right);
    883   }
    884 
    885   VisitInDuplicateContext(right);
    886   __ bind(&done);
    887 }
    888 
    889 
    890 void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
    891   Token::Value op = expr->op();
    892   Comment cmnt(masm_, "[ ArithmeticExpression");
    893   Expression* left = expr->left();
    894   Expression* right = expr->right();
    895   OverwriteMode mode =
    896       left->ResultOverwriteAllowed()
    897       ? OVERWRITE_LEFT
    898       : (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE);
    899 
    900   VisitForStackValue(left);
    901   VisitForAccumulatorValue(right);
    902 
    903   SetSourcePosition(expr->position());
    904   if (ShouldInlineSmiCase(op)) {
    905     EmitInlineSmiBinaryOp(expr, op, mode, left, right);
    906   } else {
    907     EmitBinaryOp(expr, op, mode);
    908   }
    909 }
    910 
    911 
    912 void FullCodeGenerator::VisitBlock(Block* stmt) {
    913   Comment cmnt(masm_, "[ Block");
    914   NestedBlock nested_block(this, stmt);
    915   SetStatementPosition(stmt);
    916 
    917   Scope* saved_scope = scope();
    918   // Push a block context when entering a block with block scoped variables.
    919   if (stmt->block_scope() != NULL) {
    920     { Comment cmnt(masm_, "[ Extend block context");
    921       scope_ = stmt->block_scope();
    922       Handle<ScopeInfo> scope_info = scope_->GetScopeInfo();
    923       int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS;
    924       __ Push(scope_info);
    925       PushFunctionArgumentForContextAllocation();
    926       if (heap_slots <= FastNewBlockContextStub::kMaximumSlots) {
    927         FastNewBlockContextStub stub(heap_slots);
    928         __ CallStub(&stub);
    929       } else {
    930         __ CallRuntime(Runtime::kPushBlockContext, 2);
    931       }
    932 
    933       // Replace the context stored in the frame.
    934       StoreToFrameField(StandardFrameConstants::kContextOffset,
    935                         context_register());
    936     }
    937     { Comment cmnt(masm_, "[ Declarations");
    938       VisitDeclarations(scope_->declarations());
    939     }
    940   }
    941   PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
    942   VisitStatements(stmt->statements());
    943   scope_ = saved_scope;
    944   __ bind(nested_block.break_label());
    945   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
    946 
    947   // Pop block context if necessary.
    948   if (stmt->block_scope() != NULL) {
    949     LoadContextField(context_register(), Context::PREVIOUS_INDEX);
    950     // Update local stack frame context field.
    951     StoreToFrameField(StandardFrameConstants::kContextOffset,
    952                       context_register());
    953   }
    954 }
    955 
    956 
    957 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
    958   Comment cmnt(masm_, "[ ExpressionStatement");
    959   SetStatementPosition(stmt);
    960   VisitForEffect(stmt->expression());
    961 }
    962 
    963 
    964 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
    965   Comment cmnt(masm_, "[ EmptyStatement");
    966   SetStatementPosition(stmt);
    967 }
    968 
    969 
    970 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
    971   Comment cmnt(masm_, "[ IfStatement");
    972   SetStatementPosition(stmt);
    973   Label then_part, else_part, done;
    974 
    975   if (stmt->HasElseStatement()) {
    976     VisitForControl(stmt->condition(), &then_part, &else_part, &then_part);
    977     PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
    978     __ bind(&then_part);
    979     Visit(stmt->then_statement());
    980     __ jmp(&done);
    981 
    982     PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
    983     __ bind(&else_part);
    984     Visit(stmt->else_statement());
    985   } else {
    986     VisitForControl(stmt->condition(), &then_part, &done, &then_part);
    987     PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS);
    988     __ bind(&then_part);
    989     Visit(stmt->then_statement());
    990 
    991     PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS);
    992   }
    993   __ bind(&done);
    994   PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS);
    995 }
    996 
    997 
    998 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
    999   Comment cmnt(masm_,  "[ ContinueStatement");
   1000   SetStatementPosition(stmt);
   1001   NestedStatement* current = nesting_stack_;
   1002   int stack_depth = 0;
   1003   int context_length = 0;
   1004   // When continuing, we clobber the unpredictable value in the accumulator
   1005   // with one that's safe for GC.  If we hit an exit from the try block of
   1006   // try...finally on our way out, we will unconditionally preserve the
   1007   // accumulator on the stack.
   1008   ClearAccumulator();
   1009   while (!current->IsContinueTarget(stmt->target())) {
   1010     current = current->Exit(&stack_depth, &context_length);
   1011   }
   1012   __ Drop(stack_depth);
   1013   if (context_length > 0) {
   1014     while (context_length > 0) {
   1015       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
   1016       --context_length;
   1017     }
   1018     StoreToFrameField(StandardFrameConstants::kContextOffset,
   1019                       context_register());
   1020   }
   1021 
   1022   __ jmp(current->AsIteration()->continue_label());
   1023 }
   1024 
   1025 
   1026 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
   1027   Comment cmnt(masm_,  "[ BreakStatement");
   1028   SetStatementPosition(stmt);
   1029   NestedStatement* current = nesting_stack_;
   1030   int stack_depth = 0;
   1031   int context_length = 0;
   1032   // When breaking, we clobber the unpredictable value in the accumulator
   1033   // with one that's safe for GC.  If we hit an exit from the try block of
   1034   // try...finally on our way out, we will unconditionally preserve the
   1035   // accumulator on the stack.
   1036   ClearAccumulator();
   1037   while (!current->IsBreakTarget(stmt->target())) {
   1038     current = current->Exit(&stack_depth, &context_length);
   1039   }
   1040   __ Drop(stack_depth);
   1041   if (context_length > 0) {
   1042     while (context_length > 0) {
   1043       LoadContextField(context_register(), Context::PREVIOUS_INDEX);
   1044       --context_length;
   1045     }
   1046     StoreToFrameField(StandardFrameConstants::kContextOffset,
   1047                       context_register());
   1048   }
   1049 
   1050   __ jmp(current->AsBreakable()->break_label());
   1051 }
   1052 
   1053 
   1054 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
   1055   Comment cmnt(masm_, "[ ReturnStatement");
   1056   SetStatementPosition(stmt);
   1057   Expression* expr = stmt->expression();
   1058   VisitForAccumulatorValue(expr);
   1059 
   1060   // Exit all nested statements.
   1061   NestedStatement* current = nesting_stack_;
   1062   int stack_depth = 0;
   1063   int context_length = 0;
   1064   while (current != NULL) {
   1065     current = current->Exit(&stack_depth, &context_length);
   1066   }
   1067   __ Drop(stack_depth);
   1068 
   1069   EmitReturnSequence();
   1070 }
   1071 
   1072 
   1073 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
   1074   Comment cmnt(masm_, "[ WithStatement");
   1075   SetStatementPosition(stmt);
   1076 
   1077   VisitForStackValue(stmt->expression());
   1078   PushFunctionArgumentForContextAllocation();
   1079   __ CallRuntime(Runtime::kPushWithContext, 2);
   1080   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
   1081 
   1082   { WithOrCatch body(this);
   1083     Visit(stmt->statement());
   1084   }
   1085 
   1086   // Pop context.
   1087   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
   1088   // Update local stack frame context field.
   1089   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
   1090 }
   1091 
   1092 
   1093 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
   1094   Comment cmnt(masm_, "[ DoWhileStatement");
   1095   SetStatementPosition(stmt);
   1096   Label body, stack_check;
   1097 
   1098   Iteration loop_statement(this, stmt);
   1099   increment_loop_depth();
   1100 
   1101   __ bind(&body);
   1102   Visit(stmt->body());
   1103 
   1104   // Record the position of the do while condition and make sure it is
   1105   // possible to break on the condition.
   1106   __ bind(loop_statement.continue_label());
   1107   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
   1108   SetExpressionPosition(stmt->cond(), stmt->condition_position());
   1109   VisitForControl(stmt->cond(),
   1110                   &stack_check,
   1111                   loop_statement.break_label(),
   1112                   &stack_check);
   1113 
   1114   // Check stack before looping.
   1115   PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
   1116   __ bind(&stack_check);
   1117   EmitStackCheck(stmt, &body);
   1118   __ jmp(&body);
   1119 
   1120   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
   1121   __ bind(loop_statement.break_label());
   1122   decrement_loop_depth();
   1123 }
   1124 
   1125 
   1126 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
   1127   Comment cmnt(masm_, "[ WhileStatement");
   1128   Label test, body;
   1129 
   1130   Iteration loop_statement(this, stmt);
   1131   increment_loop_depth();
   1132 
   1133   // Emit the test at the bottom of the loop.
   1134   __ jmp(&test);
   1135 
   1136   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   1137   __ bind(&body);
   1138   Visit(stmt->body());
   1139 
   1140   // Emit the statement position here as this is where the while
   1141   // statement code starts.
   1142   __ bind(loop_statement.continue_label());
   1143   SetStatementPosition(stmt);
   1144 
   1145   // Check stack before looping.
   1146   EmitStackCheck(stmt, &body);
   1147 
   1148   __ bind(&test);
   1149   VisitForControl(stmt->cond(),
   1150                   &body,
   1151                   loop_statement.break_label(),
   1152                   loop_statement.break_label());
   1153 
   1154   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
   1155   __ bind(loop_statement.break_label());
   1156   decrement_loop_depth();
   1157 }
   1158 
   1159 
   1160 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
   1161   Comment cmnt(masm_, "[ ForStatement");
   1162   Label test, body;
   1163 
   1164   Iteration loop_statement(this, stmt);
   1165 
   1166   // Set statement position for a break slot before entering the for-body.
   1167   SetStatementPosition(stmt);
   1168 
   1169   if (stmt->init() != NULL) {
   1170     Visit(stmt->init());
   1171   }
   1172 
   1173   increment_loop_depth();
   1174   // Emit the test at the bottom of the loop (even if empty).
   1175   __ jmp(&test);
   1176 
   1177   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   1178   __ bind(&body);
   1179   Visit(stmt->body());
   1180 
   1181   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
   1182   __ bind(loop_statement.continue_label());
   1183   if (stmt->next() != NULL) {
   1184     Visit(stmt->next());
   1185   }
   1186 
   1187   // Emit the statement position here as this is where the for
   1188   // statement code starts.
   1189   SetStatementPosition(stmt);
   1190 
   1191   // Check stack before looping.
   1192   EmitStackCheck(stmt, &body);
   1193 
   1194   __ bind(&test);
   1195   if (stmt->cond() != NULL) {
   1196     VisitForControl(stmt->cond(),
   1197                     &body,
   1198                     loop_statement.break_label(),
   1199                     loop_statement.break_label());
   1200   } else {
   1201     __ jmp(&body);
   1202   }
   1203 
   1204   PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
   1205   __ bind(loop_statement.break_label());
   1206   decrement_loop_depth();
   1207 }
   1208 
   1209 
   1210 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
   1211   Comment cmnt(masm_, "[ TryCatchStatement");
   1212   SetStatementPosition(stmt);
   1213   // The try block adds a handler to the exception handler chain before
   1214   // entering, and removes it again when exiting normally.  If an exception
   1215   // is thrown during execution of the try block, the handler is consumed
   1216   // and control is passed to the catch block with the exception in the
   1217   // result register.
   1218 
   1219   Label try_entry, handler_entry, exit;
   1220   __ jmp(&try_entry);
   1221   __ bind(&handler_entry);
   1222   handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
   1223   // Exception handler code, the exception is in the result register.
   1224   // Extend the context before executing the catch block.
   1225   { Comment cmnt(masm_, "[ Extend catch context");
   1226     __ Push(stmt->variable()->name());
   1227     __ push(result_register());
   1228     PushFunctionArgumentForContextAllocation();
   1229     __ CallRuntime(Runtime::kPushCatchContext, 3);
   1230     StoreToFrameField(StandardFrameConstants::kContextOffset,
   1231                       context_register());
   1232   }
   1233 
   1234   Scope* saved_scope = scope();
   1235   scope_ = stmt->scope();
   1236   ASSERT(scope_->declarations()->is_empty());
   1237   { WithOrCatch catch_body(this);
   1238     Visit(stmt->catch_block());
   1239   }
   1240   // Restore the context.
   1241   LoadContextField(context_register(), Context::PREVIOUS_INDEX);
   1242   StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
   1243   scope_ = saved_scope;
   1244   __ jmp(&exit);
   1245 
   1246   // Try block code. Sets up the exception handler chain.
   1247   __ bind(&try_entry);
   1248   __ PushTryHandler(StackHandler::CATCH, stmt->index());
   1249   { TryCatch try_body(this);
   1250     Visit(stmt->try_block());
   1251   }
   1252   __ PopTryHandler();
   1253   __ bind(&exit);
   1254 }
   1255 
   1256 
   1257 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
   1258   Comment cmnt(masm_, "[ TryFinallyStatement");
   1259   SetStatementPosition(stmt);
   1260   // Try finally is compiled by setting up a try-handler on the stack while
   1261   // executing the try body, and removing it again afterwards.
   1262   //
   1263   // The try-finally construct can enter the finally block in three ways:
   1264   // 1. By exiting the try-block normally. This removes the try-handler and
   1265   //    calls the finally block code before continuing.
   1266   // 2. By exiting the try-block with a function-local control flow transfer
   1267   //    (break/continue/return). The site of the, e.g., break removes the
   1268   //    try handler and calls the finally block code before continuing
   1269   //    its outward control transfer.
   1270   // 3. By exiting the try-block with a thrown exception.
   1271   //    This can happen in nested function calls. It traverses the try-handler
   1272   //    chain and consumes the try-handler entry before jumping to the
   1273   //    handler code. The handler code then calls the finally-block before
   1274   //    rethrowing the exception.
   1275   //
   1276   // The finally block must assume a return address on top of the stack
   1277   // (or in the link register on ARM chips) and a value (return value or
   1278   // exception) in the result register (rax/eax/r0), both of which must
   1279   // be preserved. The return address isn't GC-safe, so it should be
   1280   // cooked before GC.
   1281   Label try_entry, handler_entry, finally_entry;
   1282 
   1283   // Jump to try-handler setup and try-block code.
   1284   __ jmp(&try_entry);
   1285   __ bind(&handler_entry);
   1286   handler_table()->set(stmt->index(), Smi::FromInt(handler_entry.pos()));
   1287   // Exception handler code.  This code is only executed when an exception
   1288   // is thrown.  The exception is in the result register, and must be
   1289   // preserved by the finally block.  Call the finally block and then
   1290   // rethrow the exception if it returns.
   1291   __ Call(&finally_entry);
   1292   __ push(result_register());
   1293   __ CallRuntime(Runtime::kReThrow, 1);
   1294 
   1295   // Finally block implementation.
   1296   __ bind(&finally_entry);
   1297   EnterFinallyBlock();
   1298   { Finally finally_body(this);
   1299     Visit(stmt->finally_block());
   1300   }
   1301   ExitFinallyBlock();  // Return to the calling code.
   1302 
   1303   // Set up try handler.
   1304   __ bind(&try_entry);
   1305   __ PushTryHandler(StackHandler::FINALLY, stmt->index());
   1306   { TryFinally try_body(this, &finally_entry);
   1307     Visit(stmt->try_block());
   1308   }
   1309   __ PopTryHandler();
   1310   // Execute the finally block on the way out.  Clobber the unpredictable
   1311   // value in the result register with one that's safe for GC because the
   1312   // finally block will unconditionally preserve the result register on the
   1313   // stack.
   1314   ClearAccumulator();
   1315   __ Call(&finally_entry);
   1316 }
   1317 
   1318 
   1319 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
   1320 #ifdef ENABLE_DEBUGGER_SUPPORT
   1321   Comment cmnt(masm_, "[ DebuggerStatement");
   1322   SetStatementPosition(stmt);
   1323 
   1324   __ DebugBreak();
   1325   // Ignore the return value.
   1326 #endif
   1327 }
   1328 
   1329 
   1330 void FullCodeGenerator::VisitConditional(Conditional* expr) {
   1331   Comment cmnt(masm_, "[ Conditional");
   1332   Label true_case, false_case, done;
   1333   VisitForControl(expr->condition(), &true_case, &false_case, &true_case);
   1334 
   1335   PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS);
   1336   __ bind(&true_case);
   1337   SetExpressionPosition(expr->then_expression(),
   1338                         expr->then_expression_position());
   1339   if (context()->IsTest()) {
   1340     const TestContext* for_test = TestContext::cast(context());
   1341     VisitForControl(expr->then_expression(),
   1342                     for_test->true_label(),
   1343                     for_test->false_label(),
   1344                     NULL);
   1345   } else {
   1346     VisitInDuplicateContext(expr->then_expression());
   1347     __ jmp(&done);
   1348   }
   1349 
   1350   PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS);
   1351   __ bind(&false_case);
   1352   SetExpressionPosition(expr->else_expression(),
   1353                         expr->else_expression_position());
   1354   VisitInDuplicateContext(expr->else_expression());
   1355   // If control flow falls through Visit, merge it with true case here.
   1356   if (!context()->IsTest()) {
   1357     __ bind(&done);
   1358   }
   1359 }
   1360 
   1361 
   1362 void FullCodeGenerator::VisitLiteral(Literal* expr) {
   1363   Comment cmnt(masm_, "[ Literal");
   1364   context()->Plug(expr->handle());
   1365 }
   1366 
   1367 
   1368 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
   1369   Comment cmnt(masm_, "[ FunctionLiteral");
   1370 
   1371   // Build the function boilerplate and instantiate it.
   1372   Handle<SharedFunctionInfo> function_info =
   1373       Compiler::BuildFunctionInfo(expr, script());
   1374   if (function_info.is_null()) {
   1375     SetStackOverflow();
   1376     return;
   1377   }
   1378   EmitNewClosure(function_info, expr->pretenure());
   1379 }
   1380 
   1381 
   1382 void FullCodeGenerator::VisitSharedFunctionInfoLiteral(
   1383     SharedFunctionInfoLiteral* expr) {
   1384   Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
   1385   EmitNewClosure(expr->shared_function_info(), false);
   1386 }
   1387 
   1388 
   1389 void FullCodeGenerator::VisitThrow(Throw* expr) {
   1390   Comment cmnt(masm_, "[ Throw");
   1391   VisitForStackValue(expr->exception());
   1392   __ CallRuntime(Runtime::kThrow, 1);
   1393   // Never returns here.
   1394 }
   1395 
   1396 
   1397 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryCatch::Exit(
   1398     int* stack_depth,
   1399     int* context_length) {
   1400   // The macros used here must preserve the result register.
   1401   __ Drop(*stack_depth);
   1402   __ PopTryHandler();
   1403   *stack_depth = 0;
   1404   return previous_;
   1405 }
   1406 
   1407 
   1408 bool FullCodeGenerator::TryLiteralCompare(CompareOperation* expr) {
   1409   Expression* sub_expr;
   1410   Handle<String> check;
   1411   if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
   1412     EmitLiteralCompareTypeof(expr, sub_expr, check);
   1413     return true;
   1414   }
   1415 
   1416   if (expr->IsLiteralCompareUndefined(&sub_expr)) {
   1417     EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
   1418     return true;
   1419   }
   1420 
   1421   if (expr->IsLiteralCompareNull(&sub_expr)) {
   1422     EmitLiteralCompareNil(expr, sub_expr, kNullValue);
   1423     return true;
   1424   }
   1425 
   1426   return false;
   1427 }
   1428 
   1429 
   1430 #undef __
   1431 
   1432 
   1433 } }  // namespace v8::internal
   1434