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