Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/interpreter/bytecode-generator.h"
      6 
      7 #include "src/ast/compile-time-value.h"
      8 #include "src/ast/scopes.h"
      9 #include "src/code-stubs.h"
     10 #include "src/compilation-info.h"
     11 #include "src/compiler.h"
     12 #include "src/interpreter/bytecode-flags.h"
     13 #include "src/interpreter/bytecode-label.h"
     14 #include "src/interpreter/bytecode-register-allocator.h"
     15 #include "src/interpreter/control-flow-builders.h"
     16 #include "src/objects.h"
     17 #include "src/parsing/parse-info.h"
     18 #include "src/parsing/token.h"
     19 
     20 namespace v8 {
     21 namespace internal {
     22 namespace interpreter {
     23 
     24 // Scoped class tracking context objects created by the visitor. Represents
     25 // mutations of the context chain within the function body, allowing pushing and
     26 // popping of the current {context_register} during visitation.
     27 class BytecodeGenerator::ContextScope BASE_EMBEDDED {
     28  public:
     29   ContextScope(BytecodeGenerator* generator, Scope* scope,
     30                bool should_pop_context = true)
     31       : generator_(generator),
     32         scope_(scope),
     33         outer_(generator_->execution_context()),
     34         register_(Register::current_context()),
     35         depth_(0),
     36         should_pop_context_(should_pop_context) {
     37     if (outer_) {
     38       depth_ = outer_->depth_ + 1;
     39 
     40       // Push the outer context into a new context register.
     41       Register outer_context_reg(builder()->first_context_register().index() +
     42                                  outer_->depth_);
     43       outer_->set_register(outer_context_reg);
     44       generator_->builder()->PushContext(outer_context_reg);
     45     }
     46     generator_->set_execution_context(this);
     47   }
     48 
     49   ~ContextScope() {
     50     if (outer_ && should_pop_context_) {
     51       DCHECK_EQ(register_.index(), Register::current_context().index());
     52       generator_->builder()->PopContext(outer_->reg());
     53       outer_->set_register(register_);
     54     }
     55     generator_->set_execution_context(outer_);
     56   }
     57 
     58   // Returns the depth of the given |scope| for the current execution context.
     59   int ContextChainDepth(Scope* scope) {
     60     return scope_->ContextChainLength(scope);
     61   }
     62 
     63   // Returns the execution context at |depth| in the current context chain if it
     64   // is a function local execution context, otherwise returns nullptr.
     65   ContextScope* Previous(int depth) {
     66     if (depth > depth_) {
     67       return nullptr;
     68     }
     69 
     70     ContextScope* previous = this;
     71     for (int i = depth; i > 0; --i) {
     72       previous = previous->outer_;
     73     }
     74     return previous;
     75   }
     76 
     77   Scope* scope() const { return scope_; }
     78   Register reg() const { return register_; }
     79   bool ShouldPopContext() { return should_pop_context_; }
     80 
     81  private:
     82   const BytecodeArrayBuilder* builder() const { return generator_->builder(); }
     83 
     84   void set_register(Register reg) { register_ = reg; }
     85 
     86   BytecodeGenerator* generator_;
     87   Scope* scope_;
     88   ContextScope* outer_;
     89   Register register_;
     90   int depth_;
     91   bool should_pop_context_;
     92 };
     93 
     94 // Scoped class for tracking control statements entered by the
     95 // visitor. The pattern derives AstGraphBuilder::ControlScope.
     96 class BytecodeGenerator::ControlScope BASE_EMBEDDED {
     97  public:
     98   explicit ControlScope(BytecodeGenerator* generator)
     99       : generator_(generator), outer_(generator->execution_control()),
    100         context_(generator->execution_context()) {
    101     generator_->set_execution_control(this);
    102   }
    103   virtual ~ControlScope() { generator_->set_execution_control(outer()); }
    104 
    105   void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); }
    106   void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); }
    107   void ReturnAccumulator() { PerformCommand(CMD_RETURN, nullptr); }
    108   void ReThrowAccumulator() { PerformCommand(CMD_RETHROW, nullptr); }
    109 
    110   class DeferredCommands;
    111 
    112  protected:
    113   enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_RETHROW };
    114   void PerformCommand(Command command, Statement* statement);
    115   virtual bool Execute(Command command, Statement* statement) = 0;
    116 
    117   BytecodeGenerator* generator() const { return generator_; }
    118   ControlScope* outer() const { return outer_; }
    119   ContextScope* context() const { return context_; }
    120 
    121  private:
    122   BytecodeGenerator* generator_;
    123   ControlScope* outer_;
    124   ContextScope* context_;
    125 
    126   DISALLOW_COPY_AND_ASSIGN(ControlScope);
    127 };
    128 
    129 // Helper class for a try-finally control scope. It can record intercepted
    130 // control-flow commands that cause entry into a finally-block, and re-apply
    131 // them after again leaving that block. Special tokens are used to identify
    132 // paths going through the finally-block to dispatch after leaving the block.
    133 class BytecodeGenerator::ControlScope::DeferredCommands final {
    134  public:
    135   DeferredCommands(BytecodeGenerator* generator, Register token_register,
    136                    Register result_register)
    137       : generator_(generator),
    138         deferred_(generator->zone()),
    139         token_register_(token_register),
    140         result_register_(result_register) {}
    141 
    142   // One recorded control-flow command.
    143   struct Entry {
    144     Command command;       // The command type being applied on this path.
    145     Statement* statement;  // The target statement for the command or {nullptr}.
    146     int token;             // A token identifying this particular path.
    147   };
    148 
    149   // Records a control-flow command while entering the finally-block. This also
    150   // generates a new dispatch token that identifies one particular path. This
    151   // expects the result to be in the accumulator.
    152   void RecordCommand(Command command, Statement* statement) {
    153     int token = static_cast<int>(deferred_.size());
    154     deferred_.push_back({command, statement, token});
    155 
    156     builder()->StoreAccumulatorInRegister(result_register_);
    157     builder()->LoadLiteral(Smi::FromInt(token));
    158     builder()->StoreAccumulatorInRegister(token_register_);
    159   }
    160 
    161   // Records the dispatch token to be used to identify the re-throw path when
    162   // the finally-block has been entered through the exception handler. This
    163   // expects the exception to be in the accumulator.
    164   void RecordHandlerReThrowPath() {
    165     // The accumulator contains the exception object.
    166     RecordCommand(CMD_RETHROW, nullptr);
    167   }
    168 
    169   // Records the dispatch token to be used to identify the implicit fall-through
    170   // path at the end of a try-block into the corresponding finally-block.
    171   void RecordFallThroughPath() {
    172     builder()->LoadLiteral(Smi::FromInt(-1));
    173     builder()->StoreAccumulatorInRegister(token_register_);
    174   }
    175 
    176   // Applies all recorded control-flow commands after the finally-block again.
    177   // This generates a dynamic dispatch on the token from the entry point.
    178   void ApplyDeferredCommands() {
    179     // The fall-through path is covered by the default case, hence +1 here.
    180     SwitchBuilder dispatch(builder(), static_cast<int>(deferred_.size() + 1));
    181     for (size_t i = 0; i < deferred_.size(); ++i) {
    182       Entry& entry = deferred_[i];
    183       builder()->LoadLiteral(Smi::FromInt(entry.token));
    184       builder()->CompareOperation(Token::EQ_STRICT, token_register_);
    185       dispatch.Case(static_cast<int>(i));
    186     }
    187     dispatch.DefaultAt(static_cast<int>(deferred_.size()));
    188     for (size_t i = 0; i < deferred_.size(); ++i) {
    189       Entry& entry = deferred_[i];
    190       dispatch.SetCaseTarget(static_cast<int>(i));
    191       builder()->LoadAccumulatorWithRegister(result_register_);
    192       execution_control()->PerformCommand(entry.command, entry.statement);
    193     }
    194     dispatch.SetCaseTarget(static_cast<int>(deferred_.size()));
    195   }
    196 
    197   BytecodeArrayBuilder* builder() { return generator_->builder(); }
    198   ControlScope* execution_control() { return generator_->execution_control(); }
    199 
    200  private:
    201   BytecodeGenerator* generator_;
    202   ZoneVector<Entry> deferred_;
    203   Register token_register_;
    204   Register result_register_;
    205 };
    206 
    207 // Scoped class for dealing with control flow reaching the function level.
    208 class BytecodeGenerator::ControlScopeForTopLevel final
    209     : public BytecodeGenerator::ControlScope {
    210  public:
    211   explicit ControlScopeForTopLevel(BytecodeGenerator* generator)
    212       : ControlScope(generator) {}
    213 
    214  protected:
    215   bool Execute(Command command, Statement* statement) override {
    216     switch (command) {
    217       case CMD_BREAK:  // We should never see break/continue in top-level.
    218       case CMD_CONTINUE:
    219         UNREACHABLE();
    220       case CMD_RETURN:
    221         generator()->BuildReturn();
    222         return true;
    223       case CMD_RETHROW:
    224         generator()->BuildReThrow();
    225         return true;
    226     }
    227     return false;
    228   }
    229 };
    230 
    231 // Scoped class for enabling break inside blocks and switch blocks.
    232 class BytecodeGenerator::ControlScopeForBreakable final
    233     : public BytecodeGenerator::ControlScope {
    234  public:
    235   ControlScopeForBreakable(BytecodeGenerator* generator,
    236                            BreakableStatement* statement,
    237                            BreakableControlFlowBuilder* control_builder)
    238       : ControlScope(generator),
    239         statement_(statement),
    240         control_builder_(control_builder) {}
    241 
    242  protected:
    243   bool Execute(Command command, Statement* statement) override {
    244     if (statement != statement_) return false;
    245     switch (command) {
    246       case CMD_BREAK:
    247         control_builder_->Break();
    248         return true;
    249       case CMD_CONTINUE:
    250       case CMD_RETURN:
    251       case CMD_RETHROW:
    252         break;
    253     }
    254     return false;
    255   }
    256 
    257  private:
    258   Statement* statement_;
    259   BreakableControlFlowBuilder* control_builder_;
    260 };
    261 
    262 // Scoped class for enabling 'break' and 'continue' in iteration
    263 // constructs, e.g. do...while, while..., for...
    264 class BytecodeGenerator::ControlScopeForIteration final
    265     : public BytecodeGenerator::ControlScope {
    266  public:
    267   ControlScopeForIteration(BytecodeGenerator* generator,
    268                            IterationStatement* statement,
    269                            LoopBuilder* loop_builder)
    270       : ControlScope(generator),
    271         statement_(statement),
    272         loop_builder_(loop_builder) {
    273     generator->loop_depth_++;
    274   }
    275   ~ControlScopeForIteration() { generator()->loop_depth_--; }
    276 
    277  protected:
    278   bool Execute(Command command, Statement* statement) override {
    279     if (statement != statement_) return false;
    280     switch (command) {
    281       case CMD_BREAK:
    282         loop_builder_->Break();
    283         return true;
    284       case CMD_CONTINUE:
    285         loop_builder_->Continue();
    286         return true;
    287       case CMD_RETURN:
    288       case CMD_RETHROW:
    289         break;
    290     }
    291     return false;
    292   }
    293 
    294  private:
    295   Statement* statement_;
    296   LoopBuilder* loop_builder_;
    297 };
    298 
    299 // Scoped class for enabling 'throw' in try-catch constructs.
    300 class BytecodeGenerator::ControlScopeForTryCatch final
    301     : public BytecodeGenerator::ControlScope {
    302  public:
    303   ControlScopeForTryCatch(BytecodeGenerator* generator,
    304                           TryCatchBuilder* try_catch_builder)
    305       : ControlScope(generator) {}
    306 
    307  protected:
    308   bool Execute(Command command, Statement* statement) override {
    309     switch (command) {
    310       case CMD_BREAK:
    311       case CMD_CONTINUE:
    312       case CMD_RETURN:
    313         break;
    314       case CMD_RETHROW:
    315         generator()->BuildReThrow();
    316         return true;
    317     }
    318     return false;
    319   }
    320 };
    321 
    322 // Scoped class for enabling control flow through try-finally constructs.
    323 class BytecodeGenerator::ControlScopeForTryFinally final
    324     : public BytecodeGenerator::ControlScope {
    325  public:
    326   ControlScopeForTryFinally(BytecodeGenerator* generator,
    327                             TryFinallyBuilder* try_finally_builder,
    328                             DeferredCommands* commands)
    329       : ControlScope(generator),
    330         try_finally_builder_(try_finally_builder),
    331         commands_(commands) {}
    332 
    333  protected:
    334   bool Execute(Command command, Statement* statement) override {
    335     switch (command) {
    336       case CMD_BREAK:
    337       case CMD_CONTINUE:
    338       case CMD_RETURN:
    339       case CMD_RETHROW:
    340         commands_->RecordCommand(command, statement);
    341         try_finally_builder_->LeaveTry();
    342         return true;
    343     }
    344     return false;
    345   }
    346 
    347  private:
    348   TryFinallyBuilder* try_finally_builder_;
    349   DeferredCommands* commands_;
    350 };
    351 
    352 void BytecodeGenerator::ControlScope::PerformCommand(Command command,
    353                                                      Statement* statement) {
    354   ControlScope* current = this;
    355   ContextScope* context = generator()->execution_context();
    356   // Pop context to the expected depth but do not pop the outermost context.
    357   if (context != current->context() && context->ShouldPopContext()) {
    358     generator()->builder()->PopContext(current->context()->reg());
    359   }
    360   do {
    361     if (current->Execute(command, statement)) {
    362       return;
    363     }
    364     current = current->outer();
    365     if (current->context() != context && context->ShouldPopContext()) {
    366       // Pop context to the expected depth.
    367       // TODO(rmcilroy): Only emit a single context pop.
    368       generator()->builder()->PopContext(current->context()->reg());
    369     }
    370   } while (current != nullptr);
    371   UNREACHABLE();
    372 }
    373 
    374 class BytecodeGenerator::RegisterAllocationScope {
    375  public:
    376   explicit RegisterAllocationScope(BytecodeGenerator* generator)
    377       : generator_(generator),
    378         outer_next_register_index_(
    379             generator->register_allocator()->next_register_index()) {}
    380 
    381   virtual ~RegisterAllocationScope() {
    382     generator_->register_allocator()->ReleaseRegisters(
    383         outer_next_register_index_);
    384   }
    385 
    386  private:
    387   BytecodeGenerator* generator_;
    388   int outer_next_register_index_;
    389 
    390   DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope);
    391 };
    392 
    393 // Scoped base class for determining how the result of an expression will be
    394 // used.
    395 class BytecodeGenerator::ExpressionResultScope {
    396  public:
    397   ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
    398       : generator_(generator),
    399         kind_(kind),
    400         outer_(generator->execution_result()),
    401         allocator_(generator) {
    402     generator_->set_execution_result(this);
    403   }
    404 
    405   virtual ~ExpressionResultScope() {
    406     generator_->set_execution_result(outer_);
    407   }
    408 
    409   bool IsEffect() const { return kind_ == Expression::kEffect; }
    410   bool IsValue() const { return kind_ == Expression::kValue; }
    411   bool IsTest() const { return kind_ == Expression::kTest; }
    412 
    413   TestResultScope* AsTest() {
    414     DCHECK(IsTest());
    415     return reinterpret_cast<TestResultScope*>(this);
    416   }
    417 
    418  private:
    419   BytecodeGenerator* generator_;
    420   Expression::Context kind_;
    421   ExpressionResultScope* outer_;
    422   RegisterAllocationScope allocator_;
    423 
    424   DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
    425 };
    426 
    427 // Scoped class used when the result of the current expression is not
    428 // expected to produce a result.
    429 class BytecodeGenerator::EffectResultScope final
    430     : public ExpressionResultScope {
    431  public:
    432   explicit EffectResultScope(BytecodeGenerator* generator)
    433       : ExpressionResultScope(generator, Expression::kEffect) {}
    434 };
    435 
    436 // Scoped class used when the result of the current expression to be
    437 // evaluated should go into the interpreter's accumulator.
    438 class BytecodeGenerator::ValueResultScope final : public ExpressionResultScope {
    439  public:
    440   explicit ValueResultScope(BytecodeGenerator* generator)
    441       : ExpressionResultScope(generator, Expression::kValue) {}
    442 };
    443 
    444 // Scoped class used when the result of the current expression to be
    445 // evaluated is only tested with jumps to two branches.
    446 class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
    447  public:
    448   TestResultScope(BytecodeGenerator* generator, BytecodeLabels* then_labels,
    449                   BytecodeLabels* else_labels, TestFallthrough fallthrough)
    450       : ExpressionResultScope(generator, Expression::kTest),
    451         then_labels_(then_labels),
    452         else_labels_(else_labels),
    453         fallthrough_(fallthrough),
    454         result_consumed_by_test_(false) {}
    455 
    456   // Used when code special cases for TestResultScope and consumes any
    457   // possible value by testing and jumping to a then/else label.
    458   void SetResultConsumedByTest() {
    459     result_consumed_by_test_ = true;
    460   }
    461 
    462   bool ResultConsumedByTest() { return result_consumed_by_test_; }
    463 
    464   BytecodeLabel* NewThenLabel() { return then_labels_->New(); }
    465   BytecodeLabel* NewElseLabel() { return else_labels_->New(); }
    466 
    467   BytecodeLabels* then_labels() const { return then_labels_; }
    468   BytecodeLabels* else_labels() const { return else_labels_; }
    469 
    470   TestFallthrough fallthrough() const { return fallthrough_; }
    471   TestFallthrough inverted_fallthrough() const {
    472     switch (fallthrough_) {
    473       case TestFallthrough::kThen:
    474         return TestFallthrough::kElse;
    475       case TestFallthrough::kElse:
    476         return TestFallthrough::kThen;
    477       default:
    478         return TestFallthrough::kNone;
    479     }
    480   }
    481 
    482  private:
    483   BytecodeLabels* then_labels_;
    484   BytecodeLabels* else_labels_;
    485   TestFallthrough fallthrough_;
    486   bool result_consumed_by_test_;
    487 
    488   DISALLOW_COPY_AND_ASSIGN(TestResultScope);
    489 };
    490 
    491 // Used to build a list of global declaration initial value pairs.
    492 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject {
    493  public:
    494   explicit GlobalDeclarationsBuilder(Zone* zone)
    495       : declarations_(0, zone),
    496         constant_pool_entry_(0),
    497         has_constant_pool_entry_(false) {}
    498 
    499   void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) {
    500     DCHECK(!slot.IsInvalid());
    501     declarations_.push_back(std::make_pair(slot, func));
    502   }
    503 
    504   void AddUndefinedDeclaration(FeedbackVectorSlot slot) {
    505     DCHECK(!slot.IsInvalid());
    506     declarations_.push_back(std::make_pair(slot, nullptr));
    507   }
    508 
    509   Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) {
    510     DCHECK(has_constant_pool_entry_);
    511     int array_index = 0;
    512     Handle<FixedArray> pairs = info->isolate()->factory()->NewFixedArray(
    513         static_cast<int>(declarations_.size() * 2), TENURED);
    514     for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration :
    515          declarations_) {
    516       FunctionLiteral* func = declaration.second;
    517       Handle<Object> initial_value;
    518       if (func == nullptr) {
    519         initial_value = info->isolate()->factory()->undefined_value();
    520       } else {
    521         initial_value =
    522             Compiler::GetSharedFunctionInfo(func, info->script(), info);
    523       }
    524 
    525       // Return a null handle if any initial values can't be created. Caller
    526       // will set stack overflow.
    527       if (initial_value.is_null()) return Handle<FixedArray>();
    528 
    529       pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt()));
    530       pairs->set(array_index++, *initial_value);
    531     }
    532     return pairs;
    533   }
    534 
    535   size_t constant_pool_entry() {
    536     DCHECK(has_constant_pool_entry_);
    537     return constant_pool_entry_;
    538   }
    539 
    540   void set_constant_pool_entry(size_t constant_pool_entry) {
    541     DCHECK(!empty());
    542     DCHECK(!has_constant_pool_entry_);
    543     constant_pool_entry_ = constant_pool_entry;
    544     has_constant_pool_entry_ = true;
    545   }
    546 
    547   bool empty() { return declarations_.empty(); }
    548 
    549  private:
    550   ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_;
    551   size_t constant_pool_entry_;
    552   bool has_constant_pool_entry_;
    553 };
    554 
    555 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info)
    556     : zone_(info->zone()),
    557       builder_(new (zone()) BytecodeArrayBuilder(
    558           info->isolate(), info->zone(), info->num_parameters_including_this(),
    559           info->scope()->MaxNestedContextChainLength(),
    560           info->scope()->num_stack_slots(), info->literal(),
    561           info->SourcePositionRecordingMode())),
    562       info_(info),
    563       scope_(info->scope()),
    564       globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())),
    565       global_declarations_(0, info->zone()),
    566       function_literals_(0, info->zone()),
    567       native_function_literals_(0, info->zone()),
    568       execution_control_(nullptr),
    569       execution_context_(nullptr),
    570       execution_result_(nullptr),
    571       generator_resume_points_(info->literal()->yield_count(), info->zone()),
    572       generator_state_(),
    573       loop_depth_(0),
    574       home_object_symbol_(info->isolate()->factory()->home_object_symbol()),
    575       empty_fixed_array_(info->isolate()->factory()->empty_fixed_array()) {
    576   AstValueFactory* ast_value_factory = info->parse_info()->ast_value_factory();
    577   const AstRawString* prototype_string = ast_value_factory->prototype_string();
    578   ast_value_factory->Internalize(info->isolate());
    579   prototype_string_ = prototype_string->string();
    580 }
    581 
    582 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) {
    583   AllocateDeferredConstants();
    584   if (HasStackOverflow()) return Handle<BytecodeArray>();
    585   return builder()->ToBytecodeArray(isolate);
    586 }
    587 
    588 void BytecodeGenerator::AllocateDeferredConstants() {
    589   // Build global declaration pair arrays.
    590   for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) {
    591     Handle<FixedArray> declarations =
    592         globals_builder->AllocateDeclarationPairs(info());
    593     if (declarations.is_null()) return SetStackOverflow();
    594     builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(),
    595                                          declarations);
    596   }
    597 
    598   // Find or build shared function infos.
    599   for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) {
    600     FunctionLiteral* expr = literal.first;
    601     Handle<SharedFunctionInfo> shared_info =
    602         Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
    603     if (shared_info.is_null()) return SetStackOverflow();
    604     builder()->InsertConstantPoolEntryAt(literal.second, shared_info);
    605   }
    606 
    607   // Find or build shared function infos for the native function templates.
    608   for (std::pair<NativeFunctionLiteral*, size_t> literal :
    609        native_function_literals_) {
    610     NativeFunctionLiteral* expr = literal.first;
    611     Handle<SharedFunctionInfo> shared_info =
    612         Compiler::GetSharedFunctionInfoForNative(expr->extension(),
    613                                                  expr->name());
    614     if (shared_info.is_null()) return SetStackOverflow();
    615     builder()->InsertConstantPoolEntryAt(literal.second, shared_info);
    616   }
    617 }
    618 
    619 void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) {
    620   DisallowHeapAllocation no_allocation;
    621   DisallowHandleAllocation no_handles;
    622   DisallowHandleDereference no_deref;
    623 
    624   InitializeAstVisitor(stack_limit);
    625 
    626   // Initialize the incoming context.
    627   ContextScope incoming_context(this, scope(), false);
    628 
    629   // Initialize control scope.
    630   ControlScopeForTopLevel control(this);
    631 
    632   RegisterAllocationScope register_scope(this);
    633 
    634   if (IsResumableFunction(info()->literal()->kind())) {
    635     generator_state_ = register_allocator()->NewRegister();
    636     VisitGeneratorPrologue();
    637   }
    638 
    639   if (scope()->NeedsContext()) {
    640     // Push a new inner context scope for the function.
    641     BuildNewLocalActivationContext();
    642     ContextScope local_function_context(this, scope(), false);
    643     BuildLocalActivationContextInitialization();
    644     GenerateBytecodeBody();
    645   } else {
    646     GenerateBytecodeBody();
    647   }
    648 
    649   // In generator functions, we may not have visited every yield in the AST
    650   // since we skip some obviously dead code. Hence the generated bytecode may
    651   // contain jumps to unbound labels (resume points that will never be used).
    652   // We bind these now.
    653   for (auto& label : generator_resume_points_) {
    654     if (!label.is_bound()) builder()->Bind(&label);
    655   }
    656 
    657   // Emit an implicit return instruction in case control flow can fall off the
    658   // end of the function without an explicit return being present on all paths.
    659   if (builder()->RequiresImplicitReturn()) {
    660     builder()->LoadUndefined();
    661     BuildReturn();
    662   }
    663   DCHECK(!builder()->RequiresImplicitReturn());
    664 }
    665 
    666 void BytecodeGenerator::GenerateBytecodeBody() {
    667   // Build the arguments object if it is used.
    668   VisitArgumentsObject(scope()->arguments());
    669 
    670   // Build rest arguments array if it is used.
    671   Variable* rest_parameter = scope()->rest_parameter();
    672   VisitRestArgumentsArray(rest_parameter);
    673 
    674   // Build assignment to {.this_function} variable if it is used.
    675   VisitThisFunctionVariable(scope()->this_function_var());
    676 
    677   // Build assignment to {new.target} variable if it is used.
    678   VisitNewTargetVariable(scope()->new_target_var());
    679 
    680   // Emit tracing call if requested to do so.
    681   if (FLAG_trace) builder()->CallRuntime(Runtime::kTraceEnter);
    682 
    683   // Visit declarations within the function scope.
    684   VisitDeclarations(scope()->declarations());
    685 
    686   // Emit initializing assignments for module namespace imports (if any).
    687   VisitModuleNamespaceImports();
    688 
    689   // Perform a stack-check before the body.
    690   builder()->StackCheck(info()->literal()->start_position());
    691 
    692   // Visit statements in the function body.
    693   VisitStatements(info()->literal()->body());
    694 }
    695 
    696 void BytecodeGenerator::BuildIndexedJump(Register index, size_t start_index,
    697                                          size_t size,
    698                                          ZoneVector<BytecodeLabel>& targets) {
    699   // TODO(neis): Optimize this by using a proper jump table.
    700   DCHECK_LE(start_index + size, targets.size());
    701   for (size_t i = start_index; i < start_index + size; i++) {
    702     builder()
    703         ->LoadLiteral(Smi::FromInt(static_cast<int>(i)))
    704         .CompareOperation(Token::Value::EQ_STRICT, index)
    705         .JumpIfTrue(&(targets[i]));
    706   }
    707   BuildAbort(BailoutReason::kInvalidJumpTableIndex);
    708 }
    709 
    710 void BytecodeGenerator::VisitIterationHeader(IterationStatement* stmt,
    711                                              LoopBuilder* loop_builder) {
    712   // Recall that stmt->yield_count() is always zero inside ordinary
    713   // (i.e. non-generator) functions.
    714 
    715   // Collect all labels for generator resume points within the loop (if any) so
    716   // that they can be bound to the loop header below. Also create fresh labels
    717   // for these resume points, to be used inside the loop.
    718   ZoneVector<BytecodeLabel> resume_points_in_loop(zone());
    719   size_t first_yield = stmt->first_yield_id();
    720   DCHECK_LE(first_yield + stmt->yield_count(), generator_resume_points_.size());
    721   for (size_t id = first_yield; id < first_yield + stmt->yield_count(); id++) {
    722     auto& label = generator_resume_points_[id];
    723     resume_points_in_loop.push_back(label);
    724     generator_resume_points_[id] = BytecodeLabel();
    725   }
    726 
    727   loop_builder->LoopHeader(&resume_points_in_loop);
    728 
    729   if (stmt->yield_count() > 0) {
    730     // If we are not resuming, fall through to loop body.
    731     // If we are resuming, perform state dispatch.
    732     BytecodeLabel not_resuming;
    733     builder()
    734         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
    735         .CompareOperation(Token::Value::EQ, generator_state_)
    736         .JumpIfTrue(&not_resuming);
    737     BuildIndexedJump(generator_state_, first_yield,
    738         stmt->yield_count(), generator_resume_points_);
    739     builder()->Bind(&not_resuming);
    740   }
    741 }
    742 
    743 void BytecodeGenerator::VisitGeneratorPrologue() {
    744   // The generator resume trampoline abuses the new.target register both to
    745   // indicate that this is a resume call and to pass in the generator object.
    746   // In ordinary calls, new.target is always undefined because generator
    747   // functions are non-constructable.
    748   Register generator_object = Register::new_target();
    749   BytecodeLabel regular_call;
    750   builder()
    751       ->LoadAccumulatorWithRegister(generator_object)
    752       .JumpIfUndefined(&regular_call);
    753 
    754   // This is a resume call. Restore registers and perform state dispatch.
    755   // (The current context has already been restored by the trampoline.)
    756   builder()
    757       ->ResumeGenerator(generator_object)
    758       .StoreAccumulatorInRegister(generator_state_);
    759   BuildIndexedJump(generator_state_, 0, generator_resume_points_.size(),
    760                    generator_resume_points_);
    761 
    762   builder()
    763       ->Bind(&regular_call)
    764       .LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
    765       .StoreAccumulatorInRegister(generator_state_);
    766   // This is a regular call. Fall through to the ordinary function prologue,
    767   // after which we will run into the generator object creation and other extra
    768   // code inserted by the parser.
    769 }
    770 
    771 void BytecodeGenerator::VisitBlock(Block* stmt) {
    772   // Visit declarations and statements.
    773   if (stmt->scope() != nullptr && stmt->scope()->NeedsContext()) {
    774     BuildNewLocalBlockContext(stmt->scope());
    775     ContextScope scope(this, stmt->scope());
    776     VisitBlockDeclarationsAndStatements(stmt);
    777   } else {
    778     VisitBlockDeclarationsAndStatements(stmt);
    779   }
    780 }
    781 
    782 void BytecodeGenerator::VisitBlockDeclarationsAndStatements(Block* stmt) {
    783   BlockBuilder block_builder(builder());
    784   ControlScopeForBreakable execution_control(this, stmt, &block_builder);
    785   if (stmt->scope() != nullptr) {
    786     VisitDeclarations(stmt->scope()->declarations());
    787   }
    788   VisitStatements(stmt->statements());
    789   if (stmt->labels() != nullptr) block_builder.EndBlock();
    790 }
    791 
    792 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
    793   Variable* variable = decl->proxy()->var();
    794   switch (variable->location()) {
    795     case VariableLocation::UNALLOCATED: {
    796       DCHECK(!variable->binding_needs_init());
    797       FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
    798       globals_builder()->AddUndefinedDeclaration(slot);
    799       break;
    800     }
    801     case VariableLocation::LOCAL:
    802       if (variable->binding_needs_init()) {
    803         Register destination(variable->index());
    804         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
    805       }
    806       break;
    807     case VariableLocation::PARAMETER:
    808       if (variable->binding_needs_init()) {
    809         // The parameter indices are shifted by 1 (receiver is variable
    810         // index -1 but is parameter index 0 in BytecodeArrayBuilder).
    811         Register destination(builder()->Parameter(variable->index() + 1));
    812         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
    813       }
    814       break;
    815     case VariableLocation::CONTEXT:
    816       if (variable->binding_needs_init()) {
    817         DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
    818         builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(),
    819                                                   variable->index(), 0);
    820       }
    821       break;
    822     case VariableLocation::LOOKUP: {
    823       DCHECK_EQ(VAR, variable->mode());
    824       DCHECK(!variable->binding_needs_init());
    825 
    826       Register name = register_allocator()->NewRegister();
    827 
    828       builder()
    829           ->LoadLiteral(variable->name())
    830           .StoreAccumulatorInRegister(name)
    831           .CallRuntime(Runtime::kDeclareEvalVar, name);
    832       break;
    833     }
    834     case VariableLocation::MODULE:
    835       if (variable->IsExport() && variable->binding_needs_init()) {
    836         builder()->LoadTheHole();
    837         BuildVariableAssignment(variable, Token::INIT,
    838                                 FeedbackVectorSlot::Invalid(),
    839                                 HoleCheckMode::kElided);
    840       }
    841       // Nothing to do for imports.
    842       break;
    843   }
    844 }
    845 
    846 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
    847   Variable* variable = decl->proxy()->var();
    848   DCHECK(variable->mode() == LET || variable->mode() == VAR);
    849   switch (variable->location()) {
    850     case VariableLocation::UNALLOCATED: {
    851       FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot();
    852       globals_builder()->AddFunctionDeclaration(slot, decl->fun());
    853       break;
    854     }
    855     case VariableLocation::PARAMETER:
    856     case VariableLocation::LOCAL: {
    857       VisitForAccumulatorValue(decl->fun());
    858       BuildVariableAssignment(variable, Token::INIT,
    859                               FeedbackVectorSlot::Invalid(),
    860                               HoleCheckMode::kElided);
    861       break;
    862     }
    863     case VariableLocation::CONTEXT: {
    864       DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
    865       VisitForAccumulatorValue(decl->fun());
    866       builder()->StoreContextSlot(execution_context()->reg(), variable->index(),
    867                                   0);
    868       break;
    869     }
    870     case VariableLocation::LOOKUP: {
    871       RegisterList args = register_allocator()->NewRegisterList(2);
    872       builder()
    873           ->LoadLiteral(variable->name())
    874           .StoreAccumulatorInRegister(args[0]);
    875       VisitForAccumulatorValue(decl->fun());
    876       builder()->StoreAccumulatorInRegister(args[1]).CallRuntime(
    877           Runtime::kDeclareEvalFunction, args);
    878       break;
    879     }
    880     case VariableLocation::MODULE:
    881       DCHECK_EQ(variable->mode(), LET);
    882       DCHECK(variable->IsExport());
    883       VisitForAccumulatorValue(decl->fun());
    884       BuildVariableAssignment(variable, Token::INIT,
    885                               FeedbackVectorSlot::Invalid(),
    886                               HoleCheckMode::kElided);
    887       break;
    888   }
    889 }
    890 
    891 void BytecodeGenerator::VisitModuleNamespaceImports() {
    892   if (!scope()->is_module_scope()) return;
    893 
    894   RegisterAllocationScope register_scope(this);
    895   Register module_request = register_allocator()->NewRegister();
    896 
    897   ModuleDescriptor* descriptor = scope()->AsModuleScope()->module();
    898   for (auto entry : descriptor->namespace_imports()) {
    899     builder()
    900         ->LoadLiteral(Smi::FromInt(entry->module_request))
    901         .StoreAccumulatorInRegister(module_request)
    902         .CallRuntime(Runtime::kGetModuleNamespace, module_request);
    903     Variable* var = scope()->LookupLocal(entry->local_name);
    904     DCHECK_NOT_NULL(var);
    905     BuildVariableAssignment(var, Token::INIT, FeedbackVectorSlot::Invalid(),
    906                             HoleCheckMode::kElided);
    907   }
    908 }
    909 
    910 void BytecodeGenerator::VisitDeclarations(Declaration::List* declarations) {
    911   RegisterAllocationScope register_scope(this);
    912   DCHECK(globals_builder()->empty());
    913   for (Declaration* decl : *declarations) {
    914     RegisterAllocationScope register_scope(this);
    915     Visit(decl);
    916   }
    917   if (globals_builder()->empty()) return;
    918 
    919   globals_builder()->set_constant_pool_entry(
    920       builder()->AllocateConstantPoolEntry());
    921   int encoded_flags = info()->GetDeclareGlobalsFlags();
    922 
    923   // Emit code to declare globals.
    924   RegisterList args = register_allocator()->NewRegisterList(3);
    925   builder()
    926       ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry())
    927       .StoreAccumulatorInRegister(args[0])
    928       .LoadLiteral(Smi::FromInt(encoded_flags))
    929       .StoreAccumulatorInRegister(args[1])
    930       .MoveRegister(Register::function_closure(), args[2])
    931       .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, args);
    932 
    933   // Push and reset globals builder.
    934   global_declarations_.push_back(globals_builder());
    935   globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone());
    936 }
    937 
    938 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
    939   for (int i = 0; i < statements->length(); i++) {
    940     // Allocate an outer register allocations scope for the statement.
    941     RegisterAllocationScope allocation_scope(this);
    942     Statement* stmt = statements->at(i);
    943     Visit(stmt);
    944     if (stmt->IsJump()) break;
    945   }
    946 }
    947 
    948 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
    949   builder()->SetStatementPosition(stmt);
    950   VisitForEffect(stmt->expression());
    951 }
    952 
    953 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
    954 }
    955 
    956 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
    957   builder()->SetStatementPosition(stmt);
    958   if (stmt->condition()->ToBooleanIsTrue()) {
    959     // Generate then block unconditionally as always true.
    960     Visit(stmt->then_statement());
    961   } else if (stmt->condition()->ToBooleanIsFalse()) {
    962     // Generate else block unconditionally if it exists.
    963     if (stmt->HasElseStatement()) {
    964       Visit(stmt->else_statement());
    965     }
    966   } else {
    967     // TODO(oth): If then statement is BreakStatement or
    968     // ContinueStatement we can reduce number of generated
    969     // jump/jump_ifs here. See BasicLoops test.
    970     BytecodeLabel end_label;
    971     BytecodeLabels then_labels(zone()), else_labels(zone());
    972     VisitForTest(stmt->condition(), &then_labels, &else_labels,
    973                  TestFallthrough::kThen);
    974 
    975     then_labels.Bind(builder());
    976     Visit(stmt->then_statement());
    977 
    978     if (stmt->HasElseStatement()) {
    979       builder()->Jump(&end_label);
    980       else_labels.Bind(builder());
    981       Visit(stmt->else_statement());
    982     } else {
    983       else_labels.Bind(builder());
    984     }
    985     builder()->Bind(&end_label);
    986   }
    987 }
    988 
    989 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
    990     SloppyBlockFunctionStatement* stmt) {
    991   Visit(stmt->statement());
    992 }
    993 
    994 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
    995   builder()->SetStatementPosition(stmt);
    996   execution_control()->Continue(stmt->target());
    997 }
    998 
    999 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
   1000   builder()->SetStatementPosition(stmt);
   1001   execution_control()->Break(stmt->target());
   1002 }
   1003 
   1004 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
   1005   builder()->SetStatementPosition(stmt);
   1006   VisitForAccumulatorValue(stmt->expression());
   1007   execution_control()->ReturnAccumulator();
   1008 }
   1009 
   1010 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
   1011   builder()->SetStatementPosition(stmt);
   1012   VisitForAccumulatorValue(stmt->expression());
   1013   BuildNewLocalWithContext(stmt->scope());
   1014   VisitInScope(stmt->statement(), stmt->scope());
   1015 }
   1016 
   1017 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
   1018   // We need this scope because we visit for register values. We have to
   1019   // maintain a execution result scope where registers can be allocated.
   1020   ZoneList<CaseClause*>* clauses = stmt->cases();
   1021   SwitchBuilder switch_builder(builder(), clauses->length());
   1022   ControlScopeForBreakable scope(this, stmt, &switch_builder);
   1023   int default_index = -1;
   1024 
   1025   builder()->SetStatementPosition(stmt);
   1026 
   1027   // Keep the switch value in a register until a case matches.
   1028   Register tag = VisitForRegisterValue(stmt->tag());
   1029 
   1030   // Iterate over all cases and create nodes for label comparison.
   1031   for (int i = 0; i < clauses->length(); i++) {
   1032     CaseClause* clause = clauses->at(i);
   1033 
   1034     // The default is not a test, remember index.
   1035     if (clause->is_default()) {
   1036       default_index = i;
   1037       continue;
   1038     }
   1039 
   1040     // Perform label comparison as if via '===' with tag.
   1041     VisitForAccumulatorValue(clause->label());
   1042     builder()->CompareOperation(
   1043         Token::Value::EQ_STRICT, tag,
   1044         feedback_index(clause->CompareOperationFeedbackSlot()));
   1045     switch_builder.Case(i);
   1046   }
   1047 
   1048   if (default_index >= 0) {
   1049     // Emit default jump if there is a default case.
   1050     switch_builder.DefaultAt(default_index);
   1051   } else {
   1052     // Otherwise if we have reached here none of the cases matched, so jump to
   1053     // the end.
   1054     switch_builder.Break();
   1055   }
   1056 
   1057   // Iterate over all cases and create the case bodies.
   1058   for (int i = 0; i < clauses->length(); i++) {
   1059     CaseClause* clause = clauses->at(i);
   1060     switch_builder.SetCaseTarget(i);
   1061     VisitStatements(clause->statements());
   1062   }
   1063   switch_builder.BindBreakTarget();
   1064 }
   1065 
   1066 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
   1067   // Handled entirely in VisitSwitchStatement.
   1068   UNREACHABLE();
   1069 }
   1070 
   1071 void BytecodeGenerator::VisitIterationBody(IterationStatement* stmt,
   1072                                            LoopBuilder* loop_builder) {
   1073   ControlScopeForIteration execution_control(this, stmt, loop_builder);
   1074   builder()->StackCheck(stmt->position());
   1075   Visit(stmt->body());
   1076   loop_builder->BindContinueTarget();
   1077 }
   1078 
   1079 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
   1080   LoopBuilder loop_builder(builder());
   1081   if (stmt->cond()->ToBooleanIsFalse()) {
   1082     VisitIterationBody(stmt, &loop_builder);
   1083   } else if (stmt->cond()->ToBooleanIsTrue()) {
   1084     VisitIterationHeader(stmt, &loop_builder);
   1085     VisitIterationBody(stmt, &loop_builder);
   1086     loop_builder.JumpToHeader(loop_depth_);
   1087   } else {
   1088     VisitIterationHeader(stmt, &loop_builder);
   1089     VisitIterationBody(stmt, &loop_builder);
   1090     builder()->SetExpressionAsStatementPosition(stmt->cond());
   1091     BytecodeLabels loop_backbranch(zone());
   1092     VisitForTest(stmt->cond(), &loop_backbranch, loop_builder.break_labels(),
   1093                  TestFallthrough::kThen);
   1094     loop_backbranch.Bind(builder());
   1095     loop_builder.JumpToHeader(loop_depth_);
   1096   }
   1097   loop_builder.EndLoop();
   1098 }
   1099 
   1100 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
   1101   if (stmt->cond()->ToBooleanIsFalse()) {
   1102     // If the condition is false there is no need to generate the loop.
   1103     return;
   1104   }
   1105 
   1106   LoopBuilder loop_builder(builder());
   1107   VisitIterationHeader(stmt, &loop_builder);
   1108   if (!stmt->cond()->ToBooleanIsTrue()) {
   1109     builder()->SetExpressionAsStatementPosition(stmt->cond());
   1110     BytecodeLabels loop_body(zone());
   1111     VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
   1112                  TestFallthrough::kThen);
   1113     loop_body.Bind(builder());
   1114   }
   1115   VisitIterationBody(stmt, &loop_builder);
   1116   loop_builder.JumpToHeader(loop_depth_);
   1117   loop_builder.EndLoop();
   1118 }
   1119 
   1120 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
   1121   if (stmt->init() != nullptr) {
   1122     Visit(stmt->init());
   1123   }
   1124   if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
   1125     // If the condition is known to be false there is no need to generate
   1126     // body, next or condition blocks. Init block should be generated.
   1127     return;
   1128   }
   1129 
   1130   LoopBuilder loop_builder(builder());
   1131   VisitIterationHeader(stmt, &loop_builder);
   1132   if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
   1133     builder()->SetExpressionAsStatementPosition(stmt->cond());
   1134     BytecodeLabels loop_body(zone());
   1135     VisitForTest(stmt->cond(), &loop_body, loop_builder.break_labels(),
   1136                  TestFallthrough::kThen);
   1137     loop_body.Bind(builder());
   1138   }
   1139   VisitIterationBody(stmt, &loop_builder);
   1140   if (stmt->next() != nullptr) {
   1141     builder()->SetStatementPosition(stmt->next());
   1142     Visit(stmt->next());
   1143   }
   1144   loop_builder.JumpToHeader(loop_depth_);
   1145   loop_builder.EndLoop();
   1146 }
   1147 
   1148 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
   1149                                              FeedbackVectorSlot slot) {
   1150   DCHECK(expr->IsValidReferenceExpression());
   1151 
   1152   // Evaluate assignment starting with the value to be stored in the
   1153   // accumulator.
   1154   Property* property = expr->AsProperty();
   1155   LhsKind assign_type = Property::GetAssignType(property);
   1156   switch (assign_type) {
   1157     case VARIABLE: {
   1158       VariableProxy* proxy = expr->AsVariableProxy();
   1159       BuildVariableAssignment(proxy->var(), Token::ASSIGN, slot,
   1160                               proxy->hole_check_mode());
   1161       break;
   1162     }
   1163     case NAMED_PROPERTY: {
   1164       RegisterAllocationScope register_scope(this);
   1165       Register value = register_allocator()->NewRegister();
   1166       builder()->StoreAccumulatorInRegister(value);
   1167       Register object = VisitForRegisterValue(property->obj());
   1168       Handle<String> name = property->key()->AsLiteral()->AsPropertyName();
   1169       builder()->LoadAccumulatorWithRegister(value);
   1170       builder()->StoreNamedProperty(object, name, feedback_index(slot),
   1171                                     language_mode());
   1172       break;
   1173     }
   1174     case KEYED_PROPERTY: {
   1175       RegisterAllocationScope register_scope(this);
   1176       Register value = register_allocator()->NewRegister();
   1177       builder()->StoreAccumulatorInRegister(value);
   1178       Register object = VisitForRegisterValue(property->obj());
   1179       Register key = VisitForRegisterValue(property->key());
   1180       builder()->LoadAccumulatorWithRegister(value);
   1181       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
   1182                                     language_mode());
   1183       break;
   1184     }
   1185     case NAMED_SUPER_PROPERTY: {
   1186       RegisterAllocationScope register_scope(this);
   1187       RegisterList args = register_allocator()->NewRegisterList(4);
   1188       builder()->StoreAccumulatorInRegister(args[3]);
   1189       SuperPropertyReference* super_property =
   1190           property->obj()->AsSuperPropertyReference();
   1191       VisitForRegisterValue(super_property->this_var(), args[0]);
   1192       VisitForRegisterValue(super_property->home_object(), args[1]);
   1193       builder()
   1194           ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
   1195           .StoreAccumulatorInRegister(args[2])
   1196           .CallRuntime(StoreToSuperRuntimeId(), args);
   1197       break;
   1198     }
   1199     case KEYED_SUPER_PROPERTY: {
   1200       RegisterAllocationScope register_scope(this);
   1201       RegisterList args = register_allocator()->NewRegisterList(4);
   1202       builder()->StoreAccumulatorInRegister(args[3]);
   1203       SuperPropertyReference* super_property =
   1204           property->obj()->AsSuperPropertyReference();
   1205       VisitForRegisterValue(super_property->this_var(), args[0]);
   1206       VisitForRegisterValue(super_property->home_object(), args[1]);
   1207       VisitForRegisterValue(property->key(), args[2]);
   1208       builder()->CallRuntime(StoreKeyedToSuperRuntimeId(), args);
   1209       break;
   1210     }
   1211   }
   1212 }
   1213 
   1214 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   1215   if (stmt->subject()->IsNullLiteral() ||
   1216       stmt->subject()->IsUndefinedLiteral()) {
   1217     // ForIn generates lots of code, skip if it wouldn't produce any effects.
   1218     return;
   1219   }
   1220 
   1221   LoopBuilder loop_builder(builder());
   1222   BytecodeLabel subject_null_label, subject_undefined_label;
   1223 
   1224   // Prepare the state for executing ForIn.
   1225   builder()->SetExpressionAsStatementPosition(stmt->subject());
   1226   VisitForAccumulatorValue(stmt->subject());
   1227   builder()->JumpIfUndefined(&subject_undefined_label);
   1228   builder()->JumpIfNull(&subject_null_label);
   1229   Register receiver = register_allocator()->NewRegister();
   1230   builder()->ConvertAccumulatorToObject(receiver);
   1231 
   1232   // Used as kRegTriple and kRegPair in ForInPrepare and ForInNext.
   1233   RegisterList triple = register_allocator()->NewRegisterList(3);
   1234   Register cache_length = triple[2];
   1235   builder()->ForInPrepare(receiver, triple);
   1236 
   1237   // Set up loop counter
   1238   Register index = register_allocator()->NewRegister();
   1239   builder()->LoadLiteral(Smi::kZero);
   1240   builder()->StoreAccumulatorInRegister(index);
   1241 
   1242   // The loop
   1243   VisitIterationHeader(stmt, &loop_builder);
   1244   builder()->SetExpressionAsStatementPosition(stmt->each());
   1245   builder()->ForInContinue(index, cache_length);
   1246   loop_builder.BreakIfFalse();
   1247   FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
   1248   builder()->ForInNext(receiver, index, triple.Truncate(2),
   1249                        feedback_index(slot));
   1250   loop_builder.ContinueIfUndefined();
   1251   VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
   1252   VisitIterationBody(stmt, &loop_builder);
   1253   builder()->ForInStep(index);
   1254   builder()->StoreAccumulatorInRegister(index);
   1255   loop_builder.JumpToHeader(loop_depth_);
   1256   loop_builder.EndLoop();
   1257   builder()->Bind(&subject_null_label);
   1258   builder()->Bind(&subject_undefined_label);
   1259 }
   1260 
   1261 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
   1262   LoopBuilder loop_builder(builder());
   1263 
   1264   builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
   1265   VisitForEffect(stmt->assign_iterator());
   1266 
   1267   VisitIterationHeader(stmt, &loop_builder);
   1268   builder()->SetExpressionAsStatementPosition(stmt->next_result());
   1269   VisitForEffect(stmt->next_result());
   1270   VisitForAccumulatorValue(stmt->result_done());
   1271   loop_builder.BreakIfTrue();
   1272 
   1273   VisitForEffect(stmt->assign_each());
   1274   VisitIterationBody(stmt, &loop_builder);
   1275   loop_builder.JumpToHeader(loop_depth_);
   1276   loop_builder.EndLoop();
   1277 }
   1278 
   1279 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
   1280   TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction());
   1281 
   1282   // Preserve the context in a dedicated register, so that it can be restored
   1283   // when the handler is entered by the stack-unwinding machinery.
   1284   // TODO(mstarzinger): Be smarter about register allocation.
   1285   Register context = register_allocator()->NewRegister();
   1286   builder()->MoveRegister(Register::current_context(), context);
   1287 
   1288   // Evaluate the try-block inside a control scope. This simulates a handler
   1289   // that is intercepting 'throw' control commands.
   1290   try_control_builder.BeginTry(context);
   1291   {
   1292     ControlScopeForTryCatch scope(this, &try_control_builder);
   1293     Visit(stmt->try_block());
   1294   }
   1295   try_control_builder.EndTry();
   1296 
   1297   // Create a catch scope that binds the exception.
   1298   BuildNewLocalCatchContext(stmt->variable(), stmt->scope());
   1299   builder()->StoreAccumulatorInRegister(context);
   1300 
   1301   // If requested, clear message object as we enter the catch block.
   1302   if (stmt->clear_pending_message()) {
   1303     builder()->CallRuntime(Runtime::kInterpreterClearPendingMessage);
   1304   }
   1305 
   1306   // Load the catch context into the accumulator.
   1307   builder()->LoadAccumulatorWithRegister(context);
   1308 
   1309   // Evaluate the catch-block.
   1310   VisitInScope(stmt->catch_block(), stmt->scope());
   1311   try_control_builder.EndCatch();
   1312 }
   1313 
   1314 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
   1315   TryFinallyBuilder try_control_builder(builder(), stmt->catch_prediction());
   1316 
   1317   // We keep a record of all paths that enter the finally-block to be able to
   1318   // dispatch to the correct continuation point after the statements in the
   1319   // finally-block have been evaluated.
   1320   //
   1321   // The try-finally construct can enter the finally-block in three ways:
   1322   // 1. By exiting the try-block normally, falling through at the end.
   1323   // 2. By exiting the try-block with a function-local control flow transfer
   1324   //    (i.e. through break/continue/return statements).
   1325   // 3. By exiting the try-block with a thrown exception.
   1326   //
   1327   // The result register semantics depend on how the block was entered:
   1328   //  - ReturnStatement: It represents the return value being returned.
   1329   //  - ThrowStatement: It represents the exception being thrown.
   1330   //  - BreakStatement/ContinueStatement: Undefined and not used.
   1331   //  - Falling through into finally-block: Undefined and not used.
   1332   Register token = register_allocator()->NewRegister();
   1333   Register result = register_allocator()->NewRegister();
   1334   ControlScope::DeferredCommands commands(this, token, result);
   1335 
   1336   // Preserve the context in a dedicated register, so that it can be restored
   1337   // when the handler is entered by the stack-unwinding machinery.
   1338   // TODO(mstarzinger): Be smarter about register allocation.
   1339   Register context = register_allocator()->NewRegister();
   1340   builder()->MoveRegister(Register::current_context(), context);
   1341 
   1342   // Evaluate the try-block inside a control scope. This simulates a handler
   1343   // that is intercepting all control commands.
   1344   try_control_builder.BeginTry(context);
   1345   {
   1346     ControlScopeForTryFinally scope(this, &try_control_builder, &commands);
   1347     Visit(stmt->try_block());
   1348   }
   1349   try_control_builder.EndTry();
   1350 
   1351   // Record fall-through and exception cases.
   1352   commands.RecordFallThroughPath();
   1353   try_control_builder.LeaveTry();
   1354   try_control_builder.BeginHandler();
   1355   commands.RecordHandlerReThrowPath();
   1356 
   1357   // Pending message object is saved on entry.
   1358   try_control_builder.BeginFinally();
   1359   Register message = context;  // Reuse register.
   1360 
   1361   // Clear message object as we enter the finally block.
   1362   builder()
   1363       ->CallRuntime(Runtime::kInterpreterClearPendingMessage)
   1364       .StoreAccumulatorInRegister(message);
   1365 
   1366   // Evaluate the finally-block.
   1367   Visit(stmt->finally_block());
   1368   try_control_builder.EndFinally();
   1369 
   1370   // Pending message object is restored on exit.
   1371   builder()->CallRuntime(Runtime::kInterpreterSetPendingMessage, message);
   1372 
   1373   // Dynamic dispatch after the finally-block.
   1374   commands.ApplyDeferredCommands();
   1375 }
   1376 
   1377 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
   1378   builder()->SetStatementPosition(stmt);
   1379   builder()->Debugger();
   1380 }
   1381 
   1382 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
   1383   uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(),
   1384                                              scope()->is_function_scope());
   1385   size_t entry = builder()->AllocateConstantPoolEntry();
   1386   builder()->CreateClosure(entry, flags);
   1387   function_literals_.push_back(std::make_pair(expr, entry));
   1388 }
   1389 
   1390 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
   1391   VisitClassLiteralForRuntimeDefinition(expr);
   1392 
   1393   // Load the "prototype" from the constructor.
   1394   RegisterList args = register_allocator()->NewRegisterList(2);
   1395   Register literal = args[0];
   1396   Register prototype = args[1];
   1397   FeedbackVectorSlot slot = expr->PrototypeSlot();
   1398   builder()
   1399       ->StoreAccumulatorInRegister(literal)
   1400       .LoadNamedProperty(literal, prototype_string(), feedback_index(slot))
   1401       .StoreAccumulatorInRegister(prototype);
   1402 
   1403   VisitClassLiteralProperties(expr, literal, prototype);
   1404   builder()->CallRuntime(Runtime::kToFastProperties, literal);
   1405   // Assign to class variable.
   1406   if (expr->class_variable_proxy() != nullptr) {
   1407     VariableProxy* proxy = expr->class_variable_proxy();
   1408     FeedbackVectorSlot slot = expr->NeedsProxySlot()
   1409                                   ? expr->ProxySlot()
   1410                                   : FeedbackVectorSlot::Invalid();
   1411     BuildVariableAssignment(proxy->var(), Token::INIT, slot,
   1412                             HoleCheckMode::kElided);
   1413   }
   1414 }
   1415 
   1416 void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition(
   1417     ClassLiteral* expr) {
   1418   RegisterAllocationScope register_scope(this);
   1419   RegisterList args = register_allocator()->NewRegisterList(4);
   1420   VisitForAccumulatorValueOrTheHole(expr->extends());
   1421   builder()->StoreAccumulatorInRegister(args[0]);
   1422   VisitForRegisterValue(expr->constructor(), args[1]);
   1423   builder()
   1424       ->LoadLiteral(Smi::FromInt(expr->start_position()))
   1425       .StoreAccumulatorInRegister(args[2])
   1426       .LoadLiteral(Smi::FromInt(expr->end_position()))
   1427       .StoreAccumulatorInRegister(args[3])
   1428       .CallRuntime(Runtime::kDefineClass, args);
   1429 }
   1430 
   1431 void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
   1432                                                     Register literal,
   1433                                                     Register prototype) {
   1434   RegisterAllocationScope register_scope(this);
   1435   RegisterList args = register_allocator()->NewRegisterList(5);
   1436   Register receiver = args[0], key = args[1], value = args[2], attr = args[3],
   1437            set_function_name = args[4];
   1438 
   1439   bool attr_assigned = false;
   1440   Register old_receiver = Register::invalid_value();
   1441 
   1442   // Create nodes to store method values into the literal.
   1443   for (int i = 0; i < expr->properties()->length(); i++) {
   1444     ClassLiteral::Property* property = expr->properties()->at(i);
   1445 
   1446     // Set-up receiver.
   1447     Register new_receiver = property->is_static() ? literal : prototype;
   1448     if (new_receiver != old_receiver) {
   1449       builder()->MoveRegister(new_receiver, receiver);
   1450       old_receiver = new_receiver;
   1451     }
   1452 
   1453     VisitForAccumulatorValue(property->key());
   1454     builder()->ConvertAccumulatorToName(key);
   1455 
   1456     if (property->is_static() && property->is_computed_name()) {
   1457       // The static prototype property is read only. We handle the non computed
   1458       // property name case in the parser. Since this is the only case where we
   1459       // need to check for an own read only property we special case this so we
   1460       // do not need to do this for every property.
   1461       BytecodeLabel done;
   1462       builder()
   1463           ->LoadLiteral(prototype_string())
   1464           .CompareOperation(Token::Value::EQ_STRICT, key)
   1465           .JumpIfFalse(&done)
   1466           .CallRuntime(Runtime::kThrowStaticPrototypeError)
   1467           .Bind(&done);
   1468     }
   1469 
   1470     VisitForRegisterValue(property->value(), value);
   1471     VisitSetHomeObject(value, receiver, property);
   1472 
   1473     if (!attr_assigned) {
   1474       builder()
   1475           ->LoadLiteral(Smi::FromInt(DONT_ENUM))
   1476           .StoreAccumulatorInRegister(attr);
   1477       attr_assigned = true;
   1478     }
   1479 
   1480     switch (property->kind()) {
   1481       case ClassLiteral::Property::METHOD: {
   1482         builder()
   1483             ->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
   1484             .StoreAccumulatorInRegister(set_function_name)
   1485             .CallRuntime(Runtime::kDefineDataPropertyInLiteral, args);
   1486         break;
   1487       }
   1488       case ClassLiteral::Property::GETTER: {
   1489         builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked,
   1490                                args.Truncate(4));
   1491         break;
   1492       }
   1493       case ClassLiteral::Property::SETTER: {
   1494         builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked,
   1495                                args.Truncate(4));
   1496         break;
   1497       }
   1498       case ClassLiteral::Property::FIELD: {
   1499         UNREACHABLE();
   1500         break;
   1501       }
   1502     }
   1503   }
   1504 }
   1505 
   1506 void BytecodeGenerator::VisitNativeFunctionLiteral(
   1507     NativeFunctionLiteral* expr) {
   1508   size_t entry = builder()->AllocateConstantPoolEntry();
   1509   builder()->CreateClosure(entry, NOT_TENURED);
   1510   native_function_literals_.push_back(std::make_pair(expr, entry));
   1511 }
   1512 
   1513 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
   1514   VisitBlock(expr->block());
   1515   VisitVariableProxy(expr->result());
   1516 }
   1517 
   1518 void BytecodeGenerator::VisitConditional(Conditional* expr) {
   1519   if (expr->condition()->ToBooleanIsTrue()) {
   1520     // Generate then block unconditionally as always true.
   1521     VisitForAccumulatorValue(expr->then_expression());
   1522   } else if (expr->condition()->ToBooleanIsFalse()) {
   1523     // Generate else block unconditionally if it exists.
   1524     VisitForAccumulatorValue(expr->else_expression());
   1525   } else {
   1526     BytecodeLabel end_label;
   1527     BytecodeLabels then_labels(zone()), else_labels(zone());
   1528 
   1529     VisitForTest(expr->condition(), &then_labels, &else_labels,
   1530                  TestFallthrough::kThen);
   1531 
   1532     then_labels.Bind(builder());
   1533     VisitForAccumulatorValue(expr->then_expression());
   1534     builder()->Jump(&end_label);
   1535 
   1536     else_labels.Bind(builder());
   1537     VisitForAccumulatorValue(expr->else_expression());
   1538     builder()->Bind(&end_label);
   1539   }
   1540 }
   1541 
   1542 void BytecodeGenerator::VisitLiteral(Literal* expr) {
   1543   if (!execution_result()->IsEffect()) {
   1544     const AstValue* raw_value = expr->raw_value();
   1545     if (raw_value->IsSmi()) {
   1546       builder()->LoadLiteral(raw_value->AsSmi());
   1547     } else if (raw_value->IsUndefined()) {
   1548       builder()->LoadUndefined();
   1549     } else if (raw_value->IsTrue()) {
   1550       builder()->LoadTrue();
   1551     } else if (raw_value->IsFalse()) {
   1552       builder()->LoadFalse();
   1553     } else if (raw_value->IsNull()) {
   1554       builder()->LoadNull();
   1555     } else if (raw_value->IsTheHole()) {
   1556       builder()->LoadTheHole();
   1557     } else {
   1558       builder()->LoadLiteral(raw_value->value());
   1559     }
   1560   }
   1561 }
   1562 
   1563 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
   1564   // Materialize a regular expression literal.
   1565   builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(),
   1566                                  expr->flags());
   1567 }
   1568 
   1569 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   1570   // Copy the literal boilerplate.
   1571   uint8_t flags = CreateObjectLiteralFlags::Encode(
   1572       FastCloneShallowObjectStub::IsSupported(expr),
   1573       FastCloneShallowObjectStub::PropertiesCount(expr->properties_count()),
   1574       expr->ComputeFlags());
   1575   // If constant properties is an empty fixed array, use our cached
   1576   // empty_fixed_array to ensure it's only added to the constant pool once.
   1577   Handle<FixedArray> constant_properties = expr->properties_count() == 0
   1578                                                ? empty_fixed_array()
   1579                                                : expr->constant_properties();
   1580   Register literal = register_allocator()->NewRegister();
   1581   builder()->CreateObjectLiteral(constant_properties, expr->literal_index(),
   1582                                  flags, literal);
   1583 
   1584   // Store computed values into the literal.
   1585   int property_index = 0;
   1586   AccessorTable accessor_table(zone());
   1587   for (; property_index < expr->properties()->length(); property_index++) {
   1588     ObjectLiteral::Property* property = expr->properties()->at(property_index);
   1589     if (property->is_computed_name()) break;
   1590     if (property->IsCompileTimeValue()) continue;
   1591 
   1592     RegisterAllocationScope inner_register_scope(this);
   1593     Literal* key = property->key()->AsLiteral();
   1594     switch (property->kind()) {
   1595       case ObjectLiteral::Property::CONSTANT:
   1596         UNREACHABLE();
   1597       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   1598         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
   1599       // Fall through.
   1600       case ObjectLiteral::Property::COMPUTED: {
   1601         // It is safe to use [[Put]] here because the boilerplate already
   1602         // contains computed properties with an uninitialized value.
   1603         if (key->IsStringLiteral()) {
   1604           DCHECK(key->IsPropertyName());
   1605           if (property->emit_store()) {
   1606             VisitForAccumulatorValue(property->value());
   1607             if (FunctionLiteral::NeedsHomeObject(property->value())) {
   1608               RegisterAllocationScope register_scope(this);
   1609               Register value = register_allocator()->NewRegister();
   1610               builder()->StoreAccumulatorInRegister(value);
   1611               builder()->StoreNamedProperty(
   1612                   literal, key->AsPropertyName(),
   1613                   feedback_index(property->GetSlot(0)), language_mode());
   1614               VisitSetHomeObject(value, literal, property, 1);
   1615             } else {
   1616               builder()->StoreNamedProperty(
   1617                   literal, key->AsPropertyName(),
   1618                   feedback_index(property->GetSlot(0)), language_mode());
   1619             }
   1620           } else {
   1621             VisitForEffect(property->value());
   1622           }
   1623         } else {
   1624           RegisterList args = register_allocator()->NewRegisterList(4);
   1625 
   1626           builder()->MoveRegister(literal, args[0]);
   1627           VisitForRegisterValue(property->key(), args[1]);
   1628           VisitForRegisterValue(property->value(), args[2]);
   1629           if (property->emit_store()) {
   1630             builder()
   1631                 ->LoadLiteral(Smi::FromInt(SLOPPY))
   1632                 .StoreAccumulatorInRegister(args[3])
   1633                 .CallRuntime(Runtime::kSetProperty, args);
   1634             Register value = args[2];
   1635             VisitSetHomeObject(value, literal, property);
   1636           }
   1637         }
   1638         break;
   1639       }
   1640       case ObjectLiteral::Property::PROTOTYPE: {
   1641         DCHECK(property->emit_store());
   1642         RegisterList args = register_allocator()->NewRegisterList(2);
   1643         builder()->MoveRegister(literal, args[0]);
   1644         VisitForRegisterValue(property->value(), args[1]);
   1645         builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
   1646         break;
   1647       }
   1648       case ObjectLiteral::Property::GETTER:
   1649         if (property->emit_store()) {
   1650           accessor_table.lookup(key)->second->getter = property;
   1651         }
   1652         break;
   1653       case ObjectLiteral::Property::SETTER:
   1654         if (property->emit_store()) {
   1655           accessor_table.lookup(key)->second->setter = property;
   1656         }
   1657         break;
   1658     }
   1659   }
   1660 
   1661   // Define accessors, using only a single call to the runtime for each pair of
   1662   // corresponding getters and setters.
   1663   for (AccessorTable::Iterator it = accessor_table.begin();
   1664        it != accessor_table.end(); ++it) {
   1665     RegisterAllocationScope inner_register_scope(this);
   1666     RegisterList args = register_allocator()->NewRegisterList(5);
   1667     builder()->MoveRegister(literal, args[0]);
   1668     VisitForRegisterValue(it->first, args[1]);
   1669     VisitObjectLiteralAccessor(literal, it->second->getter, args[2]);
   1670     VisitObjectLiteralAccessor(literal, it->second->setter, args[3]);
   1671     builder()
   1672         ->LoadLiteral(Smi::FromInt(NONE))
   1673         .StoreAccumulatorInRegister(args[4])
   1674         .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, args);
   1675   }
   1676 
   1677   // Object literals have two parts. The "static" part on the left contains no
   1678   // computed property names, and so we can compute its map ahead of time; see
   1679   // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
   1680   // with the first computed property name and continues with all properties to
   1681   // its right. All the code from above initializes the static component of the
   1682   // object literal, and arranges for the map of the result to reflect the
   1683   // static order in which the keys appear. For the dynamic properties, we
   1684   // compile them into a series of "SetOwnProperty" runtime calls. This will
   1685   // preserve insertion order.
   1686   for (; property_index < expr->properties()->length(); property_index++) {
   1687     ObjectLiteral::Property* property = expr->properties()->at(property_index);
   1688     RegisterAllocationScope inner_register_scope(this);
   1689 
   1690     if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
   1691       DCHECK(property->emit_store());
   1692       RegisterList args = register_allocator()->NewRegisterList(2);
   1693       builder()->MoveRegister(literal, args[0]);
   1694       VisitForRegisterValue(property->value(), args[1]);
   1695       builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
   1696       continue;
   1697     }
   1698 
   1699     switch (property->kind()) {
   1700       case ObjectLiteral::Property::CONSTANT:
   1701       case ObjectLiteral::Property::COMPUTED:
   1702       case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
   1703         RegisterList args = register_allocator()->NewRegisterList(5);
   1704         builder()->MoveRegister(literal, args[0]);
   1705         VisitForAccumulatorValue(property->key());
   1706         builder()->ConvertAccumulatorToName(args[1]);
   1707         VisitForRegisterValue(property->value(), args[2]);
   1708         VisitSetHomeObject(args[2], literal, property);
   1709         builder()
   1710             ->LoadLiteral(Smi::FromInt(NONE))
   1711             .StoreAccumulatorInRegister(args[3])
   1712             .LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
   1713             .StoreAccumulatorInRegister(args[4]);
   1714         builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral, args);
   1715         break;
   1716       }
   1717       case ObjectLiteral::Property::GETTER:
   1718       case ObjectLiteral::Property::SETTER: {
   1719         RegisterList args = register_allocator()->NewRegisterList(4);
   1720         builder()->MoveRegister(literal, args[0]);
   1721         VisitForAccumulatorValue(property->key());
   1722         builder()->ConvertAccumulatorToName(args[1]);
   1723         VisitForRegisterValue(property->value(), args[2]);
   1724         VisitSetHomeObject(args[2], literal, property);
   1725         builder()
   1726             ->LoadLiteral(Smi::FromInt(NONE))
   1727             .StoreAccumulatorInRegister(args[3]);
   1728         Runtime::FunctionId function_id =
   1729             property->kind() == ObjectLiteral::Property::GETTER
   1730                 ? Runtime::kDefineGetterPropertyUnchecked
   1731                 : Runtime::kDefineSetterPropertyUnchecked;
   1732         builder()->CallRuntime(function_id, args);
   1733         break;
   1734       }
   1735       case ObjectLiteral::Property::PROTOTYPE:
   1736         UNREACHABLE();  // Handled specially above.
   1737         break;
   1738     }
   1739   }
   1740 
   1741   builder()->LoadAccumulatorWithRegister(literal);
   1742 }
   1743 
   1744 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   1745   // Deep-copy the literal boilerplate.
   1746   int runtime_flags = expr->ComputeFlags();
   1747   bool use_fast_shallow_clone =
   1748       (runtime_flags & ArrayLiteral::kShallowElements) != 0 &&
   1749       expr->values()->length() <= JSArray::kInitialMaxFastElementArray;
   1750   uint8_t flags =
   1751       CreateArrayLiteralFlags::Encode(use_fast_shallow_clone, runtime_flags);
   1752   builder()->CreateArrayLiteral(expr->constant_elements(),
   1753                                 expr->literal_index(), flags);
   1754   Register index, literal;
   1755 
   1756   // Evaluate all the non-constant subexpressions and store them into the
   1757   // newly cloned array.
   1758   bool literal_in_accumulator = true;
   1759   for (int array_index = 0; array_index < expr->values()->length();
   1760        array_index++) {
   1761     Expression* subexpr = expr->values()->at(array_index);
   1762     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
   1763     DCHECK(!subexpr->IsSpread());
   1764 
   1765     if (literal_in_accumulator) {
   1766       index = register_allocator()->NewRegister();
   1767       literal = register_allocator()->NewRegister();
   1768       builder()->StoreAccumulatorInRegister(literal);
   1769       literal_in_accumulator = false;
   1770     }
   1771 
   1772     FeedbackVectorSlot slot = expr->LiteralFeedbackSlot();
   1773     builder()
   1774         ->LoadLiteral(Smi::FromInt(array_index))
   1775         .StoreAccumulatorInRegister(index);
   1776     VisitForAccumulatorValue(subexpr);
   1777     builder()->StoreKeyedProperty(literal, index, feedback_index(slot),
   1778                                   language_mode());
   1779   }
   1780 
   1781   if (!literal_in_accumulator) {
   1782     // Restore literal array into accumulator.
   1783     builder()->LoadAccumulatorWithRegister(literal);
   1784   }
   1785 }
   1786 
   1787 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
   1788   builder()->SetExpressionPosition(proxy);
   1789   BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
   1790                     proxy->hole_check_mode());
   1791 }
   1792 
   1793 void BytecodeGenerator::BuildVariableLoad(Variable* variable,
   1794                                           FeedbackVectorSlot slot,
   1795                                           HoleCheckMode hole_check_mode,
   1796                                           TypeofMode typeof_mode) {
   1797   switch (variable->location()) {
   1798     case VariableLocation::LOCAL: {
   1799       Register source(Register(variable->index()));
   1800       // We need to load the variable into the accumulator, even when in a
   1801       // VisitForRegisterScope, in order to avoid register aliasing if
   1802       // subsequent expressions assign to the same variable.
   1803       builder()->LoadAccumulatorWithRegister(source);
   1804       if (hole_check_mode == HoleCheckMode::kRequired) {
   1805         BuildThrowIfHole(variable->name());
   1806       }
   1807       break;
   1808     }
   1809     case VariableLocation::PARAMETER: {
   1810       // The parameter indices are shifted by 1 (receiver is variable
   1811       // index -1 but is parameter index 0 in BytecodeArrayBuilder).
   1812       Register source = builder()->Parameter(variable->index() + 1);
   1813       // We need to load the variable into the accumulator, even when in a
   1814       // VisitForRegisterScope, in order to avoid register aliasing if
   1815       // subsequent expressions assign to the same variable.
   1816       builder()->LoadAccumulatorWithRegister(source);
   1817       if (hole_check_mode == HoleCheckMode::kRequired) {
   1818         BuildThrowIfHole(variable->name());
   1819       }
   1820       break;
   1821     }
   1822     case VariableLocation::UNALLOCATED: {
   1823       builder()->LoadGlobal(feedback_index(slot), typeof_mode);
   1824       break;
   1825     }
   1826     case VariableLocation::CONTEXT: {
   1827       int depth = execution_context()->ContextChainDepth(variable->scope());
   1828       ContextScope* context = execution_context()->Previous(depth);
   1829       Register context_reg;
   1830       if (context) {
   1831         context_reg = context->reg();
   1832         depth = 0;
   1833       } else {
   1834         context_reg = execution_context()->reg();
   1835       }
   1836 
   1837       builder()->LoadContextSlot(context_reg, variable->index(), depth);
   1838       if (hole_check_mode == HoleCheckMode::kRequired) {
   1839         BuildThrowIfHole(variable->name());
   1840       }
   1841       break;
   1842     }
   1843     case VariableLocation::LOOKUP: {
   1844       switch (variable->mode()) {
   1845         case DYNAMIC_LOCAL: {
   1846           Variable* local_variable = variable->local_if_not_shadowed();
   1847           int depth =
   1848               execution_context()->ContextChainDepth(local_variable->scope());
   1849           builder()->LoadLookupContextSlot(variable->name(), typeof_mode,
   1850                                            local_variable->index(), depth);
   1851           if (hole_check_mode == HoleCheckMode::kRequired) {
   1852             BuildThrowIfHole(variable->name());
   1853           }
   1854           break;
   1855         }
   1856         case DYNAMIC_GLOBAL: {
   1857           int depth = scope()->ContextChainLengthUntilOutermostSloppyEval();
   1858           builder()->LoadLookupGlobalSlot(variable->name(), typeof_mode,
   1859                                           feedback_index(slot), depth);
   1860           break;
   1861         }
   1862         default:
   1863           builder()->LoadLookupSlot(variable->name(), typeof_mode);
   1864       }
   1865       break;
   1866     }
   1867     case VariableLocation::MODULE: {
   1868       int depth = execution_context()->ContextChainDepth(variable->scope());
   1869       builder()->LoadModuleVariable(variable->index(), depth);
   1870       if (hole_check_mode == HoleCheckMode::kRequired) {
   1871         BuildThrowIfHole(variable->name());
   1872       }
   1873       break;
   1874     }
   1875   }
   1876 }
   1877 
   1878 void BytecodeGenerator::BuildVariableLoadForAccumulatorValue(
   1879     Variable* variable, FeedbackVectorSlot slot, HoleCheckMode hole_check_mode,
   1880     TypeofMode typeof_mode) {
   1881   ValueResultScope accumulator_result(this);
   1882   BuildVariableLoad(variable, slot, hole_check_mode, typeof_mode);
   1883 }
   1884 
   1885 void BytecodeGenerator::BuildReturn() {
   1886   if (FLAG_trace) {
   1887     RegisterAllocationScope register_scope(this);
   1888     Register result = register_allocator()->NewRegister();
   1889     // Runtime returns {result} value, preserving accumulator.
   1890     builder()->StoreAccumulatorInRegister(result).CallRuntime(
   1891         Runtime::kTraceExit, result);
   1892   }
   1893   builder()->Return();
   1894 }
   1895 
   1896 void BytecodeGenerator::BuildReThrow() { builder()->ReThrow(); }
   1897 
   1898 void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) {
   1899   RegisterAllocationScope register_scope(this);
   1900   Register reason = register_allocator()->NewRegister();
   1901   builder()
   1902       ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason)))
   1903       .StoreAccumulatorInRegister(reason)
   1904       .CallRuntime(Runtime::kAbort, reason);
   1905 }
   1906 
   1907 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) {
   1908   RegisterAllocationScope register_scope(this);
   1909   Register name_reg = register_allocator()->NewRegister();
   1910   builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime(
   1911       Runtime::kThrowReferenceError, name_reg);
   1912 }
   1913 
   1914 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) {
   1915   // TODO(interpreter): Can the parser reduce the number of checks
   1916   // performed? Or should there be a ThrowIfHole bytecode.
   1917   BytecodeLabel no_reference_error;
   1918   builder()->JumpIfNotHole(&no_reference_error);
   1919   BuildThrowReferenceError(name);
   1920   builder()->Bind(&no_reference_error);
   1921 }
   1922 
   1923 void BytecodeGenerator::BuildThrowIfNotHole(Handle<String> name) {
   1924   // TODO(interpreter): Can the parser reduce the number of checks
   1925   // performed? Or should there be a ThrowIfNotHole bytecode.
   1926   BytecodeLabel no_reference_error, reference_error;
   1927   builder()
   1928       ->JumpIfNotHole(&reference_error)
   1929       .Jump(&no_reference_error)
   1930       .Bind(&reference_error);
   1931   BuildThrowReferenceError(name);
   1932   builder()->Bind(&no_reference_error);
   1933 }
   1934 
   1935 void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
   1936                                                             Token::Value op) {
   1937   if (variable->is_this() && variable->mode() == CONST && op == Token::INIT) {
   1938     // Perform an initialization check for 'this'. 'this' variable is the
   1939     // only variable able to trigger bind operations outside the TDZ
   1940     // via 'super' calls.
   1941     BuildThrowIfNotHole(variable->name());
   1942   } else {
   1943     // Perform an initialization check for let/const declared variables.
   1944     // E.g. let x = (x = 20); is not allowed.
   1945     DCHECK(IsLexicalVariableMode(variable->mode()));
   1946     BuildThrowIfHole(variable->name());
   1947   }
   1948 }
   1949 
   1950 void BytecodeGenerator::BuildVariableAssignment(Variable* variable,
   1951                                                 Token::Value op,
   1952                                                 FeedbackVectorSlot slot,
   1953                                                 HoleCheckMode hole_check_mode) {
   1954   VariableMode mode = variable->mode();
   1955   RegisterAllocationScope assignment_register_scope(this);
   1956   BytecodeLabel end_label;
   1957   switch (variable->location()) {
   1958     case VariableLocation::PARAMETER:
   1959     case VariableLocation::LOCAL: {
   1960       Register destination;
   1961       if (VariableLocation::PARAMETER == variable->location()) {
   1962         destination = Register(builder()->Parameter(variable->index() + 1));
   1963       } else {
   1964         destination = Register(variable->index());
   1965       }
   1966 
   1967       if (hole_check_mode == HoleCheckMode::kRequired) {
   1968         // Load destination to check for hole.
   1969         Register value_temp = register_allocator()->NewRegister();
   1970         builder()
   1971             ->StoreAccumulatorInRegister(value_temp)
   1972             .LoadAccumulatorWithRegister(destination);
   1973 
   1974         BuildHoleCheckForVariableAssignment(variable, op);
   1975         builder()->LoadAccumulatorWithRegister(value_temp);
   1976       }
   1977 
   1978       if (mode != CONST || op == Token::INIT) {
   1979         builder()->StoreAccumulatorInRegister(destination);
   1980       } else if (variable->throw_on_const_assignment(language_mode())) {
   1981         builder()->CallRuntime(Runtime::kThrowConstAssignError);
   1982       }
   1983       break;
   1984     }
   1985     case VariableLocation::UNALLOCATED: {
   1986       builder()->StoreGlobal(variable->name(), feedback_index(slot),
   1987                              language_mode());
   1988       break;
   1989     }
   1990     case VariableLocation::CONTEXT: {
   1991       int depth = execution_context()->ContextChainDepth(variable->scope());
   1992       ContextScope* context = execution_context()->Previous(depth);
   1993       Register context_reg;
   1994 
   1995       if (context) {
   1996         context_reg = context->reg();
   1997         depth = 0;
   1998       } else {
   1999         context_reg = execution_context()->reg();
   2000       }
   2001 
   2002       if (hole_check_mode == HoleCheckMode::kRequired) {
   2003         // Load destination to check for hole.
   2004         Register value_temp = register_allocator()->NewRegister();
   2005         builder()
   2006             ->StoreAccumulatorInRegister(value_temp)
   2007             .LoadContextSlot(context_reg, variable->index(), depth);
   2008 
   2009         BuildHoleCheckForVariableAssignment(variable, op);
   2010         builder()->LoadAccumulatorWithRegister(value_temp);
   2011       }
   2012 
   2013       if (mode != CONST || op == Token::INIT) {
   2014         builder()->StoreContextSlot(context_reg, variable->index(), depth);
   2015       } else if (variable->throw_on_const_assignment(language_mode())) {
   2016         builder()->CallRuntime(Runtime::kThrowConstAssignError);
   2017       }
   2018       break;
   2019     }
   2020     case VariableLocation::LOOKUP: {
   2021       builder()->StoreLookupSlot(variable->name(), language_mode());
   2022       break;
   2023     }
   2024     case VariableLocation::MODULE: {
   2025       DCHECK(IsDeclaredVariableMode(mode));
   2026 
   2027       if (mode == CONST && op != Token::INIT) {
   2028         builder()->CallRuntime(Runtime::kThrowConstAssignError);
   2029         break;
   2030       }
   2031 
   2032       // If we don't throw above, we know that we're dealing with an
   2033       // export because imports are const and we do not generate initializing
   2034       // assignments for them.
   2035       DCHECK(variable->IsExport());
   2036 
   2037       int depth = execution_context()->ContextChainDepth(variable->scope());
   2038       if (hole_check_mode == HoleCheckMode::kRequired) {
   2039         Register value_temp = register_allocator()->NewRegister();
   2040         builder()
   2041             ->StoreAccumulatorInRegister(value_temp)
   2042             .LoadModuleVariable(variable->index(), depth);
   2043         BuildHoleCheckForVariableAssignment(variable, op);
   2044         builder()->LoadAccumulatorWithRegister(value_temp);
   2045       }
   2046       builder()->StoreModuleVariable(variable->index(), depth);
   2047       break;
   2048     }
   2049   }
   2050 }
   2051 
   2052 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
   2053   DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
   2054   Register object, key;
   2055   RegisterList super_property_args;
   2056   Handle<String> name;
   2057 
   2058   // Left-hand side can only be a property, a global or a variable slot.
   2059   Property* property = expr->target()->AsProperty();
   2060   LhsKind assign_type = Property::GetAssignType(property);
   2061 
   2062   // Evaluate LHS expression.
   2063   switch (assign_type) {
   2064     case VARIABLE:
   2065       // Nothing to do to evaluate variable assignment LHS.
   2066       break;
   2067     case NAMED_PROPERTY: {
   2068       object = VisitForRegisterValue(property->obj());
   2069       name = property->key()->AsLiteral()->AsPropertyName();
   2070       break;
   2071     }
   2072     case KEYED_PROPERTY: {
   2073       object = VisitForRegisterValue(property->obj());
   2074       key = VisitForRegisterValue(property->key());
   2075       break;
   2076     }
   2077     case NAMED_SUPER_PROPERTY: {
   2078       super_property_args = register_allocator()->NewRegisterList(4);
   2079       SuperPropertyReference* super_property =
   2080           property->obj()->AsSuperPropertyReference();
   2081       VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
   2082       VisitForRegisterValue(super_property->home_object(),
   2083                             super_property_args[1]);
   2084       builder()
   2085           ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
   2086           .StoreAccumulatorInRegister(super_property_args[2]);
   2087       break;
   2088     }
   2089     case KEYED_SUPER_PROPERTY: {
   2090       super_property_args = register_allocator()->NewRegisterList(4);
   2091       SuperPropertyReference* super_property =
   2092           property->obj()->AsSuperPropertyReference();
   2093       VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
   2094       VisitForRegisterValue(super_property->home_object(),
   2095                             super_property_args[1]);
   2096       VisitForRegisterValue(property->key(), super_property_args[2]);
   2097       break;
   2098     }
   2099   }
   2100 
   2101   // Evaluate the value and potentially handle compound assignments by loading
   2102   // the left-hand side value and performing a binary operation.
   2103   if (expr->is_compound()) {
   2104     Register old_value = register_allocator()->NewRegister();
   2105     switch (assign_type) {
   2106       case VARIABLE: {
   2107         VariableProxy* proxy = expr->target()->AsVariableProxy();
   2108         BuildVariableLoad(proxy->var(), proxy->VariableFeedbackSlot(),
   2109                           proxy->hole_check_mode());
   2110         builder()->StoreAccumulatorInRegister(old_value);
   2111         break;
   2112       }
   2113       case NAMED_PROPERTY: {
   2114         FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   2115         builder()
   2116             ->LoadNamedProperty(object, name, feedback_index(slot))
   2117             .StoreAccumulatorInRegister(old_value);
   2118         break;
   2119       }
   2120       case KEYED_PROPERTY: {
   2121         // Key is already in accumulator at this point due to evaluating the
   2122         // LHS above.
   2123         FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   2124         builder()
   2125             ->LoadKeyedProperty(object, feedback_index(slot))
   2126             .StoreAccumulatorInRegister(old_value);
   2127         break;
   2128       }
   2129       case NAMED_SUPER_PROPERTY: {
   2130         builder()
   2131             ->CallRuntime(Runtime::kLoadFromSuper,
   2132                           super_property_args.Truncate(3))
   2133             .StoreAccumulatorInRegister(old_value);
   2134         break;
   2135       }
   2136       case KEYED_SUPER_PROPERTY: {
   2137         builder()
   2138             ->CallRuntime(Runtime::kLoadKeyedFromSuper,
   2139                           super_property_args.Truncate(3))
   2140             .StoreAccumulatorInRegister(old_value);
   2141         break;
   2142       }
   2143     }
   2144     VisitForAccumulatorValue(expr->value());
   2145     FeedbackVectorSlot slot =
   2146         expr->binary_operation()->BinaryOperationFeedbackSlot();
   2147     builder()->BinaryOperation(expr->binary_op(), old_value,
   2148                                feedback_index(slot));
   2149   } else {
   2150     VisitForAccumulatorValue(expr->value());
   2151   }
   2152 
   2153   // Store the value.
   2154   builder()->SetExpressionPosition(expr);
   2155   FeedbackVectorSlot slot = expr->AssignmentSlot();
   2156   switch (assign_type) {
   2157     case VARIABLE: {
   2158       // TODO(oth): The BuildVariableAssignment() call is hard to reason about.
   2159       // Is the value in the accumulator safe? Yes, but scary.
   2160       VariableProxy* proxy = expr->target()->AsVariableProxy();
   2161       BuildVariableAssignment(proxy->var(), expr->op(), slot,
   2162                               proxy->hole_check_mode());
   2163       break;
   2164     }
   2165     case NAMED_PROPERTY:
   2166       builder()->StoreNamedProperty(object, name, feedback_index(slot),
   2167                                     language_mode());
   2168       break;
   2169     case KEYED_PROPERTY:
   2170       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
   2171                                     language_mode());
   2172       break;
   2173     case NAMED_SUPER_PROPERTY: {
   2174       builder()
   2175           ->StoreAccumulatorInRegister(super_property_args[3])
   2176           .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
   2177       break;
   2178     }
   2179     case KEYED_SUPER_PROPERTY: {
   2180       builder()
   2181           ->StoreAccumulatorInRegister(super_property_args[3])
   2182           .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
   2183       break;
   2184     }
   2185   }
   2186 }
   2187 
   2188 void BytecodeGenerator::VisitYield(Yield* expr) {
   2189   builder()->SetExpressionPosition(expr);
   2190   Register value = VisitForRegisterValue(expr->expression());
   2191 
   2192   Register generator = VisitForRegisterValue(expr->generator_object());
   2193 
   2194   // Save context, registers, and state. Then return.
   2195   builder()
   2196       ->LoadLiteral(Smi::FromInt(expr->yield_id()))
   2197       .SuspendGenerator(generator)
   2198       .LoadAccumulatorWithRegister(value)
   2199       .Return();  // Hard return (ignore any finally blocks).
   2200 
   2201   builder()->Bind(&(generator_resume_points_[expr->yield_id()]));
   2202   // Upon resume, we continue here.
   2203 
   2204   {
   2205     RegisterAllocationScope register_scope(this);
   2206 
   2207     // Update state to indicate that we have finished resuming. Loop headers
   2208     // rely on this.
   2209     builder()
   2210         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
   2211         .StoreAccumulatorInRegister(generator_state_);
   2212 
   2213     Register input = register_allocator()->NewRegister();
   2214     builder()
   2215         ->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, generator)
   2216         .StoreAccumulatorInRegister(input);
   2217 
   2218     Register resume_mode = register_allocator()->NewRegister();
   2219     builder()
   2220         ->CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator)
   2221         .StoreAccumulatorInRegister(resume_mode);
   2222 
   2223     // Now dispatch on resume mode.
   2224 
   2225     BytecodeLabel resume_with_next;
   2226     BytecodeLabel resume_with_return;
   2227     BytecodeLabel resume_with_throw;
   2228 
   2229     builder()
   2230         ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext))
   2231         .CompareOperation(Token::EQ_STRICT, resume_mode)
   2232         .JumpIfTrue(&resume_with_next)
   2233         .LoadLiteral(Smi::FromInt(JSGeneratorObject::kThrow))
   2234         .CompareOperation(Token::EQ_STRICT, resume_mode)
   2235         .JumpIfTrue(&resume_with_throw)
   2236         .Jump(&resume_with_return);
   2237 
   2238     builder()->Bind(&resume_with_return);
   2239     {
   2240       RegisterList args = register_allocator()->NewRegisterList(2);
   2241       builder()
   2242           ->MoveRegister(input, args[0])
   2243           .LoadTrue()
   2244           .StoreAccumulatorInRegister(args[1])
   2245           .CallRuntime(Runtime::kInlineCreateIterResultObject, args);
   2246       execution_control()->ReturnAccumulator();
   2247     }
   2248 
   2249     builder()->Bind(&resume_with_throw);
   2250     builder()->SetExpressionPosition(expr);
   2251     builder()->LoadAccumulatorWithRegister(input);
   2252     if (expr->rethrow_on_exception()) {
   2253       builder()->ReThrow();
   2254     } else {
   2255       builder()->Throw();
   2256     }
   2257 
   2258     builder()->Bind(&resume_with_next);
   2259     builder()->LoadAccumulatorWithRegister(input);
   2260   }
   2261 }
   2262 
   2263 void BytecodeGenerator::VisitThrow(Throw* expr) {
   2264   VisitForAccumulatorValue(expr->exception());
   2265   builder()->SetExpressionPosition(expr);
   2266   builder()->Throw();
   2267 }
   2268 
   2269 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
   2270   LhsKind property_kind = Property::GetAssignType(expr);
   2271   FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
   2272   builder()->SetExpressionPosition(expr);
   2273   switch (property_kind) {
   2274     case VARIABLE:
   2275       UNREACHABLE();
   2276     case NAMED_PROPERTY: {
   2277       builder()->LoadNamedProperty(obj,
   2278                                    expr->key()->AsLiteral()->AsPropertyName(),
   2279                                    feedback_index(slot));
   2280       break;
   2281     }
   2282     case KEYED_PROPERTY: {
   2283       VisitForAccumulatorValue(expr->key());
   2284       builder()->LoadKeyedProperty(obj, feedback_index(slot));
   2285       break;
   2286     }
   2287     case NAMED_SUPER_PROPERTY:
   2288       VisitNamedSuperPropertyLoad(expr, Register::invalid_value());
   2289       break;
   2290     case KEYED_SUPER_PROPERTY:
   2291       VisitKeyedSuperPropertyLoad(expr, Register::invalid_value());
   2292       break;
   2293   }
   2294 }
   2295 
   2296 void BytecodeGenerator::VisitPropertyLoadForRegister(Register obj,
   2297                                                      Property* expr,
   2298                                                      Register destination) {
   2299   ValueResultScope result_scope(this);
   2300   VisitPropertyLoad(obj, expr);
   2301   builder()->StoreAccumulatorInRegister(destination);
   2302 }
   2303 
   2304 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property,
   2305                                                     Register opt_receiver_out) {
   2306   RegisterAllocationScope register_scope(this);
   2307   SuperPropertyReference* super_property =
   2308       property->obj()->AsSuperPropertyReference();
   2309   RegisterList args = register_allocator()->NewRegisterList(3);
   2310   VisitForRegisterValue(super_property->this_var(), args[0]);
   2311   VisitForRegisterValue(super_property->home_object(), args[1]);
   2312   builder()
   2313       ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
   2314       .StoreAccumulatorInRegister(args[2])
   2315       .CallRuntime(Runtime::kLoadFromSuper, args);
   2316 
   2317   if (opt_receiver_out.is_valid()) {
   2318     builder()->MoveRegister(args[0], opt_receiver_out);
   2319   }
   2320 }
   2321 
   2322 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
   2323                                                     Register opt_receiver_out) {
   2324   RegisterAllocationScope register_scope(this);
   2325   SuperPropertyReference* super_property =
   2326       property->obj()->AsSuperPropertyReference();
   2327   RegisterList args = register_allocator()->NewRegisterList(3);
   2328   VisitForRegisterValue(super_property->this_var(), args[0]);
   2329   VisitForRegisterValue(super_property->home_object(), args[1]);
   2330   VisitForRegisterValue(property->key(), args[2]);
   2331   builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, args);
   2332 
   2333   if (opt_receiver_out.is_valid()) {
   2334     builder()->MoveRegister(args[0], opt_receiver_out);
   2335   }
   2336 }
   2337 
   2338 void BytecodeGenerator::VisitProperty(Property* expr) {
   2339   LhsKind property_kind = Property::GetAssignType(expr);
   2340   if (property_kind != NAMED_SUPER_PROPERTY &&
   2341       property_kind != KEYED_SUPER_PROPERTY) {
   2342     Register obj = VisitForRegisterValue(expr->obj());
   2343     VisitPropertyLoad(obj, expr);
   2344   } else {
   2345     VisitPropertyLoad(Register::invalid_value(), expr);
   2346   }
   2347 }
   2348 
   2349 void BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args,
   2350                                        RegisterList* arg_regs) {
   2351   // Visit arguments.
   2352   for (int i = 0; i < static_cast<int>(args->length()); i++) {
   2353     VisitAndPushIntoRegisterList(args->at(i), arg_regs);
   2354   }
   2355 }
   2356 
   2357 void BytecodeGenerator::VisitCall(Call* expr) {
   2358   Expression* callee_expr = expr->expression();
   2359   Call::CallType call_type = expr->GetCallType();
   2360 
   2361   if (call_type == Call::SUPER_CALL) {
   2362     return VisitCallSuper(expr);
   2363   }
   2364 
   2365   Register callee = register_allocator()->NewRegister();
   2366   // Grow the args list as we visit receiver / arguments to avoid allocating all
   2367   // the registers up-front. Otherwise these registers are unavailable during
   2368   // receiver / argument visiting and we can end up with memory leaks due to
   2369   // registers keeping objects alive.
   2370   RegisterList args = register_allocator()->NewGrowableRegisterList();
   2371 
   2372   // Prepare the callee and the receiver to the function call. This depends on
   2373   // the semantics of the underlying call type.
   2374   switch (call_type) {
   2375     case Call::NAMED_PROPERTY_CALL:
   2376     case Call::KEYED_PROPERTY_CALL: {
   2377       Property* property = callee_expr->AsProperty();
   2378       VisitAndPushIntoRegisterList(property->obj(), &args);
   2379       VisitPropertyLoadForRegister(args[0], property, callee);
   2380       break;
   2381     }
   2382     case Call::GLOBAL_CALL: {
   2383       // Receiver is undefined for global calls.
   2384       BuildPushUndefinedIntoRegisterList(&args);
   2385       // Load callee as a global variable.
   2386       VariableProxy* proxy = callee_expr->AsVariableProxy();
   2387       BuildVariableLoadForAccumulatorValue(proxy->var(),
   2388                                            proxy->VariableFeedbackSlot(),
   2389                                            proxy->hole_check_mode());
   2390       builder()->StoreAccumulatorInRegister(callee);
   2391       break;
   2392     }
   2393     case Call::WITH_CALL: {
   2394       Register receiver = register_allocator()->GrowRegisterList(&args);
   2395       DCHECK(callee_expr->AsVariableProxy()->var()->IsLookupSlot());
   2396       {
   2397         RegisterAllocationScope inner_register_scope(this);
   2398         Register name = register_allocator()->NewRegister();
   2399 
   2400         // Call %LoadLookupSlotForCall to get the callee and receiver.
   2401         DCHECK(Register::AreContiguous(callee, receiver));
   2402         RegisterList result_pair(callee.index(), 2);
   2403         USE(receiver);
   2404         Variable* variable = callee_expr->AsVariableProxy()->var();
   2405         builder()
   2406             ->LoadLiteral(variable->name())
   2407             .StoreAccumulatorInRegister(name)
   2408             .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name,
   2409                                 result_pair);
   2410       }
   2411       break;
   2412     }
   2413     case Call::OTHER_CALL: {
   2414       BuildPushUndefinedIntoRegisterList(&args);
   2415       VisitForRegisterValue(callee_expr, callee);
   2416       break;
   2417     }
   2418     case Call::NAMED_SUPER_PROPERTY_CALL: {
   2419       Register receiver = register_allocator()->GrowRegisterList(&args);
   2420       Property* property = callee_expr->AsProperty();
   2421       VisitNamedSuperPropertyLoad(property, receiver);
   2422       builder()->StoreAccumulatorInRegister(callee);
   2423       break;
   2424     }
   2425     case Call::KEYED_SUPER_PROPERTY_CALL: {
   2426       Register receiver = register_allocator()->GrowRegisterList(&args);
   2427       Property* property = callee_expr->AsProperty();
   2428       VisitKeyedSuperPropertyLoad(property, receiver);
   2429       builder()->StoreAccumulatorInRegister(callee);
   2430       break;
   2431     }
   2432     case Call::SUPER_CALL:
   2433       UNREACHABLE();
   2434       break;
   2435   }
   2436 
   2437   // Evaluate all arguments to the function call and store in sequential args
   2438   // registers.
   2439   VisitArguments(expr->arguments(), &args);
   2440   CHECK_EQ(expr->arguments()->length() + 1, args.register_count());
   2441 
   2442   // Resolve callee for a potential direct eval call. This block will mutate the
   2443   // callee value.
   2444   if (expr->is_possibly_eval() && expr->arguments()->length() > 0) {
   2445     RegisterAllocationScope inner_register_scope(this);
   2446     // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
   2447     // strings and function closure, and loading language and
   2448     // position.
   2449     RegisterList runtime_call_args = register_allocator()->NewRegisterList(6);
   2450     builder()
   2451         ->MoveRegister(callee, runtime_call_args[0])
   2452         .MoveRegister(args[1], runtime_call_args[1])
   2453         .MoveRegister(Register::function_closure(), runtime_call_args[2])
   2454         .LoadLiteral(Smi::FromInt(language_mode()))
   2455         .StoreAccumulatorInRegister(runtime_call_args[3])
   2456         .LoadLiteral(
   2457             Smi::FromInt(execution_context()->scope()->start_position()))
   2458         .StoreAccumulatorInRegister(runtime_call_args[4])
   2459         .LoadLiteral(Smi::FromInt(expr->position()))
   2460         .StoreAccumulatorInRegister(runtime_call_args[5]);
   2461 
   2462     // Call ResolvePossiblyDirectEval and modify the callee.
   2463     builder()
   2464         ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args)
   2465         .StoreAccumulatorInRegister(callee);
   2466   }
   2467 
   2468   builder()->SetExpressionPosition(expr);
   2469 
   2470   int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
   2471   builder()->Call(callee, args, feedback_slot_index, call_type,
   2472                   expr->tail_call_mode());
   2473 }
   2474 
   2475 void BytecodeGenerator::VisitCallSuper(Call* expr) {
   2476   RegisterAllocationScope register_scope(this);
   2477   SuperCallReference* super = expr->expression()->AsSuperCallReference();
   2478 
   2479   // Prepare the constructor to the super call.
   2480   Register this_function = VisitForRegisterValue(super->this_function_var());
   2481   builder()->CallRuntime(Runtime::kInlineGetSuperConstructor, this_function);
   2482 
   2483   Register constructor = this_function;  // Re-use dead this_function register.
   2484   builder()->StoreAccumulatorInRegister(constructor);
   2485 
   2486   RegisterList args = register_allocator()->NewGrowableRegisterList();
   2487   VisitArguments(expr->arguments(), &args);
   2488 
   2489   // The new target is loaded into the accumulator from the
   2490   // {new.target} variable.
   2491   VisitForAccumulatorValue(super->new_target_var());
   2492 
   2493   // Call construct.
   2494   builder()->SetExpressionPosition(expr);
   2495   // TODO(turbofan): For now we do gather feedback on super constructor
   2496   // calls, utilizing the existing machinery to inline the actual call
   2497   // target and the JSCreate for the implicit receiver allocation. This
   2498   // is not an ideal solution for super constructor calls, but it gets
   2499   // the job done for now. In the long run we might want to revisit this
   2500   // and come up with a better way.
   2501   int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
   2502   builder()->New(constructor, args, feedback_slot_index);
   2503 }
   2504 
   2505 void BytecodeGenerator::VisitCallNew(CallNew* expr) {
   2506   Register constructor = VisitForRegisterValue(expr->expression());
   2507   RegisterList args = register_allocator()->NewGrowableRegisterList();
   2508   VisitArguments(expr->arguments(), &args);
   2509 
   2510   builder()->SetExpressionPosition(expr);
   2511   // The accumulator holds new target which is the same as the
   2512   // constructor for CallNew.
   2513   builder()
   2514       ->LoadAccumulatorWithRegister(constructor)
   2515       .New(constructor, args, feedback_index(expr->CallNewFeedbackSlot()));
   2516 }
   2517 
   2518 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   2519   if (expr->is_jsruntime()) {
   2520     RegisterList args = register_allocator()->NewGrowableRegisterList();
   2521     // Allocate a register for the receiver and load it with undefined.
   2522     BuildPushUndefinedIntoRegisterList(&args);
   2523     VisitArguments(expr->arguments(), &args);
   2524     builder()->CallJSRuntime(expr->context_index(), args);
   2525   } else {
   2526     // Evaluate all arguments to the runtime call.
   2527     RegisterList args = register_allocator()->NewGrowableRegisterList();
   2528     VisitArguments(expr->arguments(), &args);
   2529     Runtime::FunctionId function_id = expr->function()->function_id;
   2530     builder()->CallRuntime(function_id, args);
   2531   }
   2532 }
   2533 
   2534 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
   2535   VisitForEffect(expr->expression());
   2536   builder()->LoadUndefined();
   2537 }
   2538 
   2539 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
   2540   if (expr->expression()->IsVariableProxy()) {
   2541     // Typeof does not throw a reference error on global variables, hence we
   2542     // perform a non-contextual load in case the operand is a variable proxy.
   2543     VariableProxy* proxy = expr->expression()->AsVariableProxy();
   2544     BuildVariableLoadForAccumulatorValue(
   2545         proxy->var(), proxy->VariableFeedbackSlot(), proxy->hole_check_mode(),
   2546         INSIDE_TYPEOF);
   2547   } else {
   2548     VisitForAccumulatorValue(expr->expression());
   2549   }
   2550   builder()->TypeOf();
   2551 }
   2552 
   2553 void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
   2554   if (execution_result()->IsEffect()) {
   2555     VisitForEffect(expr->expression());
   2556   } else if (execution_result()->IsTest()) {
   2557     TestResultScope* test_result = execution_result()->AsTest();
   2558     // No actual logical negation happening, we just swap the control flow by
   2559     // swapping the target labels and the fallthrough branch.
   2560     VisitForTest(expr->expression(), test_result->else_labels(),
   2561                  test_result->then_labels(),
   2562                  test_result->inverted_fallthrough());
   2563     test_result->SetResultConsumedByTest();
   2564   } else {
   2565     VisitForAccumulatorValue(expr->expression());
   2566     builder()->LogicalNot();
   2567   }
   2568 }
   2569 
   2570 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
   2571   switch (expr->op()) {
   2572     case Token::Value::NOT:
   2573       VisitNot(expr);
   2574       break;
   2575     case Token::Value::TYPEOF:
   2576       VisitTypeOf(expr);
   2577       break;
   2578     case Token::Value::VOID:
   2579       VisitVoid(expr);
   2580       break;
   2581     case Token::Value::DELETE:
   2582       VisitDelete(expr);
   2583       break;
   2584     case Token::Value::BIT_NOT:
   2585     case Token::Value::ADD:
   2586     case Token::Value::SUB:
   2587       // These operators are converted to an equivalent binary operators in
   2588       // the parser. These operators are not expected to be visited here.
   2589       UNREACHABLE();
   2590     default:
   2591       UNREACHABLE();
   2592   }
   2593 }
   2594 
   2595 void BytecodeGenerator::VisitDelete(UnaryOperation* expr) {
   2596   if (expr->expression()->IsProperty()) {
   2597     // Delete of an object property is allowed both in sloppy
   2598     // and strict modes.
   2599     Property* property = expr->expression()->AsProperty();
   2600     Register object = VisitForRegisterValue(property->obj());
   2601     VisitForAccumulatorValue(property->key());
   2602     builder()->Delete(object, language_mode());
   2603   } else if (expr->expression()->IsVariableProxy()) {
   2604     // Delete of an unqualified identifier is allowed in sloppy mode but is
   2605     // not allowed in strict mode. Deleting 'this' is allowed in both modes.
   2606     VariableProxy* proxy = expr->expression()->AsVariableProxy();
   2607     Variable* variable = proxy->var();
   2608     DCHECK(is_sloppy(language_mode()) || variable->is_this());
   2609     switch (variable->location()) {
   2610       case VariableLocation::UNALLOCATED: {
   2611         // Global var, let, const or variables not explicitly declared.
   2612         Register native_context = register_allocator()->NewRegister();
   2613         Register global_object = register_allocator()->NewRegister();
   2614         builder()
   2615             ->LoadContextSlot(execution_context()->reg(),
   2616                               Context::NATIVE_CONTEXT_INDEX, 0)
   2617             .StoreAccumulatorInRegister(native_context)
   2618             .LoadContextSlot(native_context, Context::EXTENSION_INDEX, 0)
   2619             .StoreAccumulatorInRegister(global_object)
   2620             .LoadLiteral(variable->name())
   2621             .Delete(global_object, language_mode());
   2622         break;
   2623       }
   2624       case VariableLocation::PARAMETER:
   2625       case VariableLocation::LOCAL:
   2626       case VariableLocation::CONTEXT: {
   2627         // Deleting local var/let/const, context variables, and arguments
   2628         // does not have any effect.
   2629         if (variable->is_this()) {
   2630           builder()->LoadTrue();
   2631         } else {
   2632           builder()->LoadFalse();
   2633         }
   2634         break;
   2635       }
   2636       case VariableLocation::LOOKUP: {
   2637         Register name_reg = register_allocator()->NewRegister();
   2638         builder()
   2639             ->LoadLiteral(variable->name())
   2640             .StoreAccumulatorInRegister(name_reg)
   2641             .CallRuntime(Runtime::kDeleteLookupSlot, name_reg);
   2642         break;
   2643       }
   2644       default:
   2645         UNREACHABLE();
   2646     }
   2647   } else {
   2648     // Delete of an unresolvable reference returns true.
   2649     VisitForEffect(expr->expression());
   2650     builder()->LoadTrue();
   2651   }
   2652 }
   2653 
   2654 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
   2655   DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
   2656 
   2657   // Left-hand side can only be a property, a global or a variable slot.
   2658   Property* property = expr->expression()->AsProperty();
   2659   LhsKind assign_type = Property::GetAssignType(property);
   2660 
   2661   bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect();
   2662 
   2663   // Evaluate LHS expression and get old value.
   2664   Register object, key, old_value;
   2665   RegisterList super_property_args;
   2666   Handle<String> name;
   2667   switch (assign_type) {
   2668     case VARIABLE: {
   2669       VariableProxy* proxy = expr->expression()->AsVariableProxy();
   2670       BuildVariableLoadForAccumulatorValue(proxy->var(),
   2671                                            proxy->VariableFeedbackSlot(),
   2672                                            proxy->hole_check_mode());
   2673       break;
   2674     }
   2675     case NAMED_PROPERTY: {
   2676       FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   2677       object = VisitForRegisterValue(property->obj());
   2678       name = property->key()->AsLiteral()->AsPropertyName();
   2679       builder()->LoadNamedProperty(object, name, feedback_index(slot));
   2680       break;
   2681     }
   2682     case KEYED_PROPERTY: {
   2683       FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   2684       object = VisitForRegisterValue(property->obj());
   2685       // Use visit for accumulator here since we need the key in the accumulator
   2686       // for the LoadKeyedProperty.
   2687       key = register_allocator()->NewRegister();
   2688       VisitForAccumulatorValue(property->key());
   2689       builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
   2690           object, feedback_index(slot));
   2691       break;
   2692     }
   2693     case NAMED_SUPER_PROPERTY: {
   2694       super_property_args = register_allocator()->NewRegisterList(4);
   2695       RegisterList load_super_args = super_property_args.Truncate(3);
   2696       SuperPropertyReference* super_property =
   2697           property->obj()->AsSuperPropertyReference();
   2698       VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
   2699       VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
   2700       builder()
   2701           ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
   2702           .StoreAccumulatorInRegister(load_super_args[2])
   2703           .CallRuntime(Runtime::kLoadFromSuper, load_super_args);
   2704       break;
   2705     }
   2706     case KEYED_SUPER_PROPERTY: {
   2707       super_property_args = register_allocator()->NewRegisterList(4);
   2708       RegisterList load_super_args = super_property_args.Truncate(3);
   2709       SuperPropertyReference* super_property =
   2710           property->obj()->AsSuperPropertyReference();
   2711       VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
   2712       VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
   2713       VisitForRegisterValue(property->key(), load_super_args[2]);
   2714       builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, load_super_args);
   2715       break;
   2716     }
   2717   }
   2718 
   2719   // Save result for postfix expressions.
   2720   if (is_postfix) {
   2721     // Convert old value into a number before saving it.
   2722     old_value = register_allocator()->NewRegister();
   2723     builder()
   2724         ->ConvertAccumulatorToNumber(old_value)
   2725         .LoadAccumulatorWithRegister(old_value);
   2726   }
   2727 
   2728   // Perform +1/-1 operation.
   2729   FeedbackVectorSlot slot = expr->CountBinaryOpFeedbackSlot();
   2730   builder()->CountOperation(expr->binary_op(), feedback_index(slot));
   2731 
   2732   // Store the value.
   2733   builder()->SetExpressionPosition(expr);
   2734   FeedbackVectorSlot feedback_slot = expr->CountSlot();
   2735   switch (assign_type) {
   2736     case VARIABLE: {
   2737       VariableProxy* proxy = expr->expression()->AsVariableProxy();
   2738       BuildVariableAssignment(proxy->var(), expr->op(), feedback_slot,
   2739                               proxy->hole_check_mode());
   2740       break;
   2741     }
   2742     case NAMED_PROPERTY: {
   2743       builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot),
   2744                                     language_mode());
   2745       break;
   2746     }
   2747     case KEYED_PROPERTY: {
   2748       builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot),
   2749                                     language_mode());
   2750       break;
   2751     }
   2752     case NAMED_SUPER_PROPERTY: {
   2753       builder()
   2754           ->StoreAccumulatorInRegister(super_property_args[3])
   2755           .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
   2756       break;
   2757     }
   2758     case KEYED_SUPER_PROPERTY: {
   2759       builder()
   2760           ->StoreAccumulatorInRegister(super_property_args[3])
   2761           .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
   2762       break;
   2763     }
   2764   }
   2765 
   2766   // Restore old value for postfix expressions.
   2767   if (is_postfix) {
   2768     builder()->LoadAccumulatorWithRegister(old_value);
   2769   }
   2770 }
   2771 
   2772 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) {
   2773   switch (binop->op()) {
   2774     case Token::COMMA:
   2775       VisitCommaExpression(binop);
   2776       break;
   2777     case Token::OR:
   2778       VisitLogicalOrExpression(binop);
   2779       break;
   2780     case Token::AND:
   2781       VisitLogicalAndExpression(binop);
   2782       break;
   2783     default:
   2784       VisitArithmeticExpression(binop);
   2785       break;
   2786   }
   2787 }
   2788 
   2789 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   2790   Register lhs = VisitForRegisterValue(expr->left());
   2791   VisitForAccumulatorValue(expr->right());
   2792   builder()->SetExpressionPosition(expr);
   2793   FeedbackVectorSlot slot = expr->CompareOperationFeedbackSlot();
   2794   builder()->CompareOperation(expr->op(), lhs, feedback_index(slot));
   2795 }
   2796 
   2797 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
   2798   // TODO(rmcilroy): Special case "x * 1.0" and "x * -1" which are generated for
   2799   // +x and -x by the parser.
   2800   Register lhs = VisitForRegisterValue(expr->left());
   2801   VisitForAccumulatorValue(expr->right());
   2802   FeedbackVectorSlot slot = expr->BinaryOperationFeedbackSlot();
   2803   builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot));
   2804 }
   2805 
   2806 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
   2807 
   2808 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
   2809   UNREACHABLE();
   2810 }
   2811 
   2812 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
   2813   builder()->LoadAccumulatorWithRegister(Register::function_closure());
   2814 }
   2815 
   2816 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
   2817   // Handled by VisitCall().
   2818   UNREACHABLE();
   2819 }
   2820 
   2821 void BytecodeGenerator::VisitSuperPropertyReference(
   2822     SuperPropertyReference* expr) {
   2823   builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
   2824 }
   2825 
   2826 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
   2827   VisitForEffect(binop->left());
   2828   Visit(binop->right());
   2829 }
   2830 
   2831 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
   2832   Expression* left = binop->left();
   2833   Expression* right = binop->right();
   2834 
   2835   if (execution_result()->IsTest()) {
   2836     TestResultScope* test_result = execution_result()->AsTest();
   2837 
   2838     if (left->ToBooleanIsTrue()) {
   2839       builder()->Jump(test_result->NewThenLabel());
   2840     } else if (left->ToBooleanIsFalse() && right->ToBooleanIsFalse()) {
   2841       builder()->Jump(test_result->NewElseLabel());
   2842     } else {
   2843       BytecodeLabels test_right(zone());
   2844       VisitForTest(left, test_result->then_labels(), &test_right,
   2845                    TestFallthrough::kElse);
   2846       test_right.Bind(builder());
   2847       VisitForTest(right, test_result->then_labels(),
   2848                    test_result->else_labels(), test_result->fallthrough());
   2849     }
   2850     test_result->SetResultConsumedByTest();
   2851   } else {
   2852     if (left->ToBooleanIsTrue()) {
   2853       VisitForAccumulatorValue(left);
   2854     } else if (left->ToBooleanIsFalse()) {
   2855       VisitForAccumulatorValue(right);
   2856     } else {
   2857       BytecodeLabel end_label;
   2858       VisitForAccumulatorValue(left);
   2859       builder()->JumpIfTrue(&end_label);
   2860       VisitForAccumulatorValue(right);
   2861       builder()->Bind(&end_label);
   2862     }
   2863   }
   2864 }
   2865 
   2866 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
   2867   Expression* left = binop->left();
   2868   Expression* right = binop->right();
   2869 
   2870   if (execution_result()->IsTest()) {
   2871     TestResultScope* test_result = execution_result()->AsTest();
   2872 
   2873     if (left->ToBooleanIsFalse()) {
   2874       builder()->Jump(test_result->NewElseLabel());
   2875     } else if (left->ToBooleanIsTrue() && right->ToBooleanIsTrue()) {
   2876       builder()->Jump(test_result->NewThenLabel());
   2877     } else {
   2878       BytecodeLabels test_right(zone());
   2879       VisitForTest(left, &test_right, test_result->else_labels(),
   2880                    TestFallthrough::kThen);
   2881       test_right.Bind(builder());
   2882       VisitForTest(right, test_result->then_labels(),
   2883                    test_result->else_labels(), test_result->fallthrough());
   2884     }
   2885     test_result->SetResultConsumedByTest();
   2886   } else {
   2887     if (left->ToBooleanIsFalse()) {
   2888       VisitForAccumulatorValue(left);
   2889     } else if (left->ToBooleanIsTrue()) {
   2890       VisitForAccumulatorValue(right);
   2891     } else {
   2892       BytecodeLabel end_label;
   2893       VisitForAccumulatorValue(left);
   2894       builder()->JumpIfFalse(&end_label);
   2895       VisitForAccumulatorValue(right);
   2896       builder()->Bind(&end_label);
   2897     }
   2898   }
   2899 }
   2900 
   2901 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
   2902   Visit(expr->expression());
   2903 }
   2904 
   2905 void BytecodeGenerator::BuildNewLocalActivationContext() {
   2906   ValueResultScope value_execution_result(this);
   2907   Scope* scope = this->scope();
   2908 
   2909   // Create the appropriate context.
   2910   if (scope->is_script_scope()) {
   2911     RegisterList args = register_allocator()->NewRegisterList(2);
   2912     builder()
   2913         ->LoadAccumulatorWithRegister(Register::function_closure())
   2914         .StoreAccumulatorInRegister(args[0])
   2915         .LoadLiteral(scope->scope_info())
   2916         .StoreAccumulatorInRegister(args[1])
   2917         .CallRuntime(Runtime::kNewScriptContext, args);
   2918   } else if (scope->is_module_scope()) {
   2919     // We don't need to do anything for the outer script scope.
   2920     DCHECK(scope->outer_scope()->is_script_scope());
   2921 
   2922     // A JSFunction representing a module is called with the module object as
   2923     // its sole argument, which we pass on to PushModuleContext.
   2924     RegisterList args = register_allocator()->NewRegisterList(3);
   2925     builder()
   2926         ->MoveRegister(builder()->Parameter(1), args[0])
   2927         .LoadAccumulatorWithRegister(Register::function_closure())
   2928         .StoreAccumulatorInRegister(args[1])
   2929         .LoadLiteral(scope->scope_info())
   2930         .StoreAccumulatorInRegister(args[2])
   2931         .CallRuntime(Runtime::kPushModuleContext, args);
   2932   } else {
   2933     int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   2934     if (slot_count <= FastNewFunctionContextStub::kMaximumSlots) {
   2935       builder()->CreateFunctionContext(slot_count);
   2936     } else {
   2937       builder()->CallRuntime(Runtime::kNewFunctionContext,
   2938                              Register::function_closure());
   2939     }
   2940   }
   2941 }
   2942 
   2943 void BytecodeGenerator::BuildLocalActivationContextInitialization() {
   2944   DeclarationScope* scope = this->scope();
   2945 
   2946   if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
   2947     Variable* variable = scope->receiver();
   2948     Register receiver(builder()->Parameter(0));
   2949     // Context variable (at bottom of the context chain).
   2950     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   2951     builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
   2952         execution_context()->reg(), variable->index(), 0);
   2953   }
   2954 
   2955   // Copy parameters into context if necessary.
   2956   int num_parameters = scope->num_parameters();
   2957   for (int i = 0; i < num_parameters; i++) {
   2958     Variable* variable = scope->parameter(i);
   2959     if (!variable->IsContextSlot()) continue;
   2960 
   2961     // The parameter indices are shifted by 1 (receiver is variable
   2962     // index -1 but is parameter index 0 in BytecodeArrayBuilder).
   2963     Register parameter(builder()->Parameter(i + 1));
   2964     // Context variable (at bottom of the context chain).
   2965     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   2966     builder()->LoadAccumulatorWithRegister(parameter).StoreContextSlot(
   2967         execution_context()->reg(), variable->index(), 0);
   2968   }
   2969 }
   2970 
   2971 void BytecodeGenerator::BuildNewLocalBlockContext(Scope* scope) {
   2972   ValueResultScope value_execution_result(this);
   2973   DCHECK(scope->is_block_scope());
   2974 
   2975   VisitFunctionClosureForContext();
   2976   builder()->CreateBlockContext(scope->scope_info());
   2977 }
   2978 
   2979 void BytecodeGenerator::BuildNewLocalWithContext(Scope* scope) {
   2980   ValueResultScope value_execution_result(this);
   2981 
   2982   Register extension_object = register_allocator()->NewRegister();
   2983 
   2984   builder()->ConvertAccumulatorToObject(extension_object);
   2985   VisitFunctionClosureForContext();
   2986   builder()->CreateWithContext(extension_object, scope->scope_info());
   2987 }
   2988 
   2989 void BytecodeGenerator::BuildNewLocalCatchContext(Variable* variable,
   2990                                                   Scope* scope) {
   2991   ValueResultScope value_execution_result(this);
   2992   DCHECK(variable->IsContextSlot());
   2993 
   2994   Register exception = register_allocator()->NewRegister();
   2995   builder()->StoreAccumulatorInRegister(exception);
   2996   VisitFunctionClosureForContext();
   2997   builder()->CreateCatchContext(exception, variable->name(),
   2998                                 scope->scope_info());
   2999 }
   3000 
   3001 void BytecodeGenerator::VisitObjectLiteralAccessor(
   3002     Register home_object, ObjectLiteralProperty* property, Register value_out) {
   3003   if (property == nullptr) {
   3004     builder()->LoadNull().StoreAccumulatorInRegister(value_out);
   3005   } else {
   3006     VisitForRegisterValue(property->value(), value_out);
   3007     VisitSetHomeObject(value_out, home_object, property);
   3008   }
   3009 }
   3010 
   3011 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
   3012                                            LiteralProperty* property,
   3013                                            int slot_number) {
   3014   Expression* expr = property->value();
   3015   if (FunctionLiteral::NeedsHomeObject(expr)) {
   3016     FeedbackVectorSlot slot = property->GetSlot(slot_number);
   3017     builder()
   3018         ->LoadAccumulatorWithRegister(home_object)
   3019         .StoreNamedProperty(value, home_object_symbol(), feedback_index(slot),
   3020                             language_mode());
   3021   }
   3022 }
   3023 
   3024 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
   3025   if (variable == nullptr) return;
   3026 
   3027   DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
   3028 
   3029   // Allocate and initialize a new arguments object and assign to the
   3030   // {arguments} variable.
   3031   CreateArgumentsType type =
   3032       is_strict(language_mode()) || !info()->has_simple_parameters()
   3033           ? CreateArgumentsType::kUnmappedArguments
   3034           : CreateArgumentsType::kMappedArguments;
   3035   builder()->CreateArguments(type);
   3036   BuildVariableAssignment(variable, Token::ASSIGN,
   3037                           FeedbackVectorSlot::Invalid(),
   3038                           HoleCheckMode::kElided);
   3039 }
   3040 
   3041 void BytecodeGenerator::VisitRestArgumentsArray(Variable* rest) {
   3042   if (rest == nullptr) return;
   3043 
   3044   // Allocate and initialize a new rest parameter and assign to the {rest}
   3045   // variable.
   3046   builder()->CreateArguments(CreateArgumentsType::kRestParameter);
   3047   DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
   3048   BuildVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid(),
   3049                           HoleCheckMode::kElided);
   3050 }
   3051 
   3052 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
   3053   if (variable == nullptr) return;
   3054 
   3055   // Store the closure we were called with in the given variable.
   3056   builder()->LoadAccumulatorWithRegister(Register::function_closure());
   3057   BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(),
   3058                           HoleCheckMode::kElided);
   3059 }
   3060 
   3061 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
   3062   if (variable == nullptr) return;
   3063 
   3064   // Store the new target we were called with in the given variable.
   3065   builder()->LoadAccumulatorWithRegister(Register::new_target());
   3066   BuildVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid(),
   3067                           HoleCheckMode::kElided);
   3068 
   3069   // TODO(mstarzinger): The <new.target> register is not set by the deoptimizer
   3070   // and we need to make sure {BytecodeRegisterOptimizer} flushes its state
   3071   // before a local variable containing the <new.target> is used. Using a label
   3072   // as below flushes the entire pipeline, we should be more specific here.
   3073   BytecodeLabel flush_state_label;
   3074   builder()->Bind(&flush_state_label);
   3075 }
   3076 
   3077 void BytecodeGenerator::VisitFunctionClosureForContext() {
   3078   ValueResultScope value_execution_result(this);
   3079   DeclarationScope* closure_scope =
   3080       execution_context()->scope()->GetClosureScope();
   3081   if (closure_scope->is_script_scope()) {
   3082     // Contexts nested in the native context have a canonical empty function as
   3083     // their closure, not the anonymous closure containing the global code.
   3084     Register native_context = register_allocator()->NewRegister();
   3085     builder()
   3086         ->LoadContextSlot(execution_context()->reg(),
   3087                           Context::NATIVE_CONTEXT_INDEX, 0)
   3088         .StoreAccumulatorInRegister(native_context)
   3089         .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0);
   3090   } else if (closure_scope->is_eval_scope()) {
   3091     // Contexts created by a call to eval have the same closure as the
   3092     // context calling eval, not the anonymous closure containing the eval
   3093     // code. Fetch it from the context.
   3094     builder()->LoadContextSlot(execution_context()->reg(),
   3095                                Context::CLOSURE_INDEX, 0);
   3096   } else {
   3097     DCHECK(closure_scope->is_function_scope() ||
   3098            closure_scope->is_module_scope());
   3099     builder()->LoadAccumulatorWithRegister(Register::function_closure());
   3100   }
   3101 }
   3102 
   3103 // Visits the expression |expr| and places the result in the accumulator.
   3104 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
   3105   ValueResultScope accumulator_scope(this);
   3106   Visit(expr);
   3107 }
   3108 
   3109 void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) {
   3110   if (expr == nullptr) {
   3111     builder()->LoadTheHole();
   3112   } else {
   3113     VisitForAccumulatorValue(expr);
   3114   }
   3115 }
   3116 
   3117 // Visits the expression |expr| and discards the result.
   3118 void BytecodeGenerator::VisitForEffect(Expression* expr) {
   3119   EffectResultScope effect_scope(this);
   3120   Visit(expr);
   3121 }
   3122 
   3123 // Visits the expression |expr| and returns the register containing
   3124 // the expression result.
   3125 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
   3126   VisitForAccumulatorValue(expr);
   3127   Register result = register_allocator()->NewRegister();
   3128   builder()->StoreAccumulatorInRegister(result);
   3129   return result;
   3130 }
   3131 
   3132 // Visits the expression |expr| and stores the expression result in
   3133 // |destination|.
   3134 void BytecodeGenerator::VisitForRegisterValue(Expression* expr,
   3135                                               Register destination) {
   3136   ValueResultScope register_scope(this);
   3137   Visit(expr);
   3138   builder()->StoreAccumulatorInRegister(destination);
   3139 }
   3140 
   3141 // Visits the expression |expr| and pushes the result into a new register
   3142 // added to the end of |reg_list|.
   3143 void BytecodeGenerator::VisitAndPushIntoRegisterList(Expression* expr,
   3144                                                      RegisterList* reg_list) {
   3145   {
   3146     ValueResultScope register_scope(this);
   3147     Visit(expr);
   3148   }
   3149   // Grow the register list after visiting the expression to avoid reserving
   3150   // the register across the expression evaluation, which could cause memory
   3151   // leaks for deep expressions due to dead objects being kept alive by pointers
   3152   // in registers.
   3153   Register destination = register_allocator()->GrowRegisterList(reg_list);
   3154   builder()->StoreAccumulatorInRegister(destination);
   3155 }
   3156 
   3157 void BytecodeGenerator::BuildPushUndefinedIntoRegisterList(
   3158     RegisterList* reg_list) {
   3159   Register reg = register_allocator()->GrowRegisterList(reg_list);
   3160   builder()->LoadUndefined().StoreAccumulatorInRegister(reg);
   3161 }
   3162 
   3163 // Visits the expression |expr| for testing its boolean value and jumping to the
   3164 // |then| or |other| label depending on value and short-circuit semantics
   3165 void BytecodeGenerator::VisitForTest(Expression* expr,
   3166                                      BytecodeLabels* then_labels,
   3167                                      BytecodeLabels* else_labels,
   3168                                      TestFallthrough fallthrough) {
   3169   bool result_consumed;
   3170   {
   3171     // To make sure that all temporary registers are returned before generating
   3172     // jumps below, we ensure that the result scope is deleted before doing so.
   3173     // Dead registers might be materialized otherwise.
   3174     TestResultScope test_result(this, then_labels, else_labels, fallthrough);
   3175     Visit(expr);
   3176     result_consumed = test_result.ResultConsumedByTest();
   3177   }
   3178   if (!result_consumed) {
   3179     switch (fallthrough) {
   3180       case TestFallthrough::kThen:
   3181         builder()->JumpIfFalse(else_labels->New());
   3182         break;
   3183       case TestFallthrough::kElse:
   3184         builder()->JumpIfTrue(then_labels->New());
   3185         break;
   3186       case TestFallthrough::kNone:
   3187         builder()->JumpIfTrue(then_labels->New());
   3188         builder()->Jump(else_labels->New());
   3189     }
   3190   }
   3191 }
   3192 
   3193 void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
   3194   ContextScope context_scope(this, scope);
   3195   DCHECK(scope->declarations()->is_empty());
   3196   Visit(stmt);
   3197 }
   3198 
   3199 LanguageMode BytecodeGenerator::language_mode() const {
   3200   return execution_context()->scope()->language_mode();
   3201 }
   3202 
   3203 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
   3204   return TypeFeedbackVector::GetIndex(slot);
   3205 }
   3206 
   3207 Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() {
   3208   return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
   3209                                     : Runtime::kStoreToSuper_Sloppy;
   3210 }
   3211 
   3212 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
   3213   return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
   3214                                     : Runtime::kStoreKeyedToSuper_Sloppy;
   3215 }
   3216 
   3217 }  // namespace interpreter
   3218 }  // namespace internal
   3219 }  // namespace v8
   3220