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