Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/interpreter/bytecode-generator.h"
      6 
      7 #include "src/ast/scopes.h"
      8 #include "src/compiler.h"
      9 #include "src/interpreter/bytecode-register-allocator.h"
     10 #include "src/interpreter/control-flow-builders.h"
     11 #include "src/objects.h"
     12 #include "src/parsing/parser.h"
     13 #include "src/parsing/token.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 namespace interpreter {
     18 
     19 
     20 // Scoped class tracking context objects created by the visitor. Represents
     21 // mutations of the context chain within the function body, allowing pushing and
     22 // popping of the current {context_register} during visitation.
     23 class BytecodeGenerator::ContextScope BASE_EMBEDDED {
     24  public:
     25   ContextScope(BytecodeGenerator* generator, Scope* scope,
     26                bool should_pop_context = true)
     27       : generator_(generator),
     28         scope_(scope),
     29         outer_(generator_->execution_context()),
     30         register_(generator_->NextContextRegister()),
     31         depth_(0),
     32         should_pop_context_(should_pop_context) {
     33     if (outer_) {
     34       depth_ = outer_->depth_ + 1;
     35       generator_->builder()->PushContext(register_);
     36     }
     37     generator_->set_execution_context(this);
     38   }
     39 
     40   ~ContextScope() {
     41     if (outer_ && should_pop_context_) {
     42       generator_->builder()->PopContext(outer_->reg());
     43     }
     44     generator_->set_execution_context(outer_);
     45   }
     46 
     47   // Returns the depth of the given |scope| for the current execution context.
     48   int ContextChainDepth(Scope* scope) {
     49     return scope_->ContextChainLength(scope);
     50   }
     51 
     52   // Returns the execution context at |depth| in the current context chain if it
     53   // is a function local execution context, otherwise returns nullptr.
     54   ContextScope* Previous(int depth) {
     55     if (depth > depth_) {
     56       return nullptr;
     57     }
     58 
     59     ContextScope* previous = this;
     60     for (int i = depth; i > 0; --i) {
     61       previous = previous->outer_;
     62     }
     63     return previous;
     64   }
     65 
     66   Scope* scope() const { return scope_; }
     67   Register reg() const { return register_; }
     68 
     69  private:
     70   BytecodeGenerator* generator_;
     71   Scope* scope_;
     72   ContextScope* outer_;
     73   Register register_;
     74   int depth_;
     75   bool should_pop_context_;
     76 };
     77 
     78 
     79 // Scoped class for tracking control statements entered by the
     80 // visitor. The pattern derives AstGraphBuilder::ControlScope.
     81 class BytecodeGenerator::ControlScope BASE_EMBEDDED {
     82  public:
     83   explicit ControlScope(BytecodeGenerator* generator)
     84       : generator_(generator), outer_(generator->execution_control()) {
     85     generator_->set_execution_control(this);
     86   }
     87   virtual ~ControlScope() { generator_->set_execution_control(outer()); }
     88 
     89   void Break(Statement* stmt) { PerformCommand(CMD_BREAK, stmt); }
     90   void Continue(Statement* stmt) { PerformCommand(CMD_CONTINUE, stmt); }
     91 
     92  protected:
     93   enum Command { CMD_BREAK, CMD_CONTINUE };
     94   void PerformCommand(Command command, Statement* statement);
     95   virtual bool Execute(Command command, Statement* statement) = 0;
     96 
     97   BytecodeGenerator* generator() const { return generator_; }
     98   ControlScope* outer() const { return outer_; }
     99 
    100  private:
    101   BytecodeGenerator* generator_;
    102   ControlScope* outer_;
    103 
    104   DISALLOW_COPY_AND_ASSIGN(ControlScope);
    105 };
    106 
    107 
    108 // Scoped class for enabling break inside blocks and switch blocks.
    109 class BytecodeGenerator::ControlScopeForBreakable final
    110     : public BytecodeGenerator::ControlScope {
    111  public:
    112   ControlScopeForBreakable(BytecodeGenerator* generator,
    113                            BreakableStatement* statement,
    114                            BreakableControlFlowBuilder* control_builder)
    115       : ControlScope(generator),
    116         statement_(statement),
    117         control_builder_(control_builder) {}
    118 
    119  protected:
    120   virtual bool Execute(Command command, Statement* statement) {
    121     if (statement != statement_) return false;
    122     switch (command) {
    123       case CMD_BREAK:
    124         control_builder_->Break();
    125         return true;
    126       case CMD_CONTINUE:
    127         break;
    128     }
    129     return false;
    130   }
    131 
    132  private:
    133   Statement* statement_;
    134   BreakableControlFlowBuilder* control_builder_;
    135 };
    136 
    137 
    138 // Scoped class for enabling 'break' and 'continue' in iteration
    139 // constructs, e.g. do...while, while..., for...
    140 class BytecodeGenerator::ControlScopeForIteration final
    141     : public BytecodeGenerator::ControlScope {
    142  public:
    143   ControlScopeForIteration(BytecodeGenerator* generator,
    144                            IterationStatement* statement,
    145                            LoopBuilder* loop_builder)
    146       : ControlScope(generator),
    147         statement_(statement),
    148         loop_builder_(loop_builder) {}
    149 
    150  protected:
    151   virtual bool Execute(Command command, Statement* statement) {
    152     if (statement != statement_) return false;
    153     switch (command) {
    154       case CMD_BREAK:
    155         loop_builder_->Break();
    156         return true;
    157       case CMD_CONTINUE:
    158         loop_builder_->Continue();
    159         return true;
    160     }
    161     return false;
    162   }
    163 
    164  private:
    165   Statement* statement_;
    166   LoopBuilder* loop_builder_;
    167 };
    168 
    169 
    170 void BytecodeGenerator::ControlScope::PerformCommand(Command command,
    171                                                      Statement* statement) {
    172   ControlScope* current = this;
    173   do {
    174     if (current->Execute(command, statement)) return;
    175     current = current->outer();
    176   } while (current != nullptr);
    177   UNREACHABLE();
    178 }
    179 
    180 
    181 class BytecodeGenerator::RegisterAllocationScope {
    182  public:
    183   explicit RegisterAllocationScope(BytecodeGenerator* generator)
    184       : generator_(generator),
    185         outer_(generator->register_allocator()),
    186         allocator_(builder()) {
    187     generator_->set_register_allocator(this);
    188   }
    189 
    190   virtual ~RegisterAllocationScope() {
    191     generator_->set_register_allocator(outer_);
    192   }
    193 
    194   Register NewRegister() {
    195     RegisterAllocationScope* current_scope = generator()->register_allocator();
    196     if ((current_scope == this) ||
    197         (current_scope->outer() == this &&
    198          !current_scope->allocator_.HasConsecutiveAllocations())) {
    199       // Regular case - Allocating registers in current or outer context.
    200       // VisitForRegisterValue allocates register in outer context.
    201       return allocator_.NewRegister();
    202     } else {
    203       // If it is required to allocate a register other than current or outer
    204       // scopes, allocate a new temporary register. It might be expensive to
    205       // walk the full context chain and compute the list of consecutive
    206       // reservations in the innerscopes.
    207       UNIMPLEMENTED();
    208       return Register(-1);
    209     }
    210   }
    211 
    212   void PrepareForConsecutiveAllocations(size_t count) {
    213     allocator_.PrepareForConsecutiveAllocations(count);
    214   }
    215 
    216   Register NextConsecutiveRegister() {
    217     return allocator_.NextConsecutiveRegister();
    218   }
    219 
    220   bool RegisterIsAllocatedInThisScope(Register reg) const {
    221     return allocator_.RegisterIsAllocatedInThisScope(reg);
    222   }
    223 
    224   RegisterAllocationScope* outer() const { return outer_; }
    225 
    226  private:
    227   BytecodeGenerator* generator() const { return generator_; }
    228   BytecodeArrayBuilder* builder() const { return generator_->builder(); }
    229 
    230   BytecodeGenerator* generator_;
    231   RegisterAllocationScope* outer_;
    232   BytecodeRegisterAllocator allocator_;
    233 
    234   DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope);
    235 };
    236 
    237 
    238 // Scoped base class for determining where the result of an expression
    239 // is stored.
    240 class BytecodeGenerator::ExpressionResultScope {
    241  public:
    242   ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
    243       : generator_(generator),
    244         kind_(kind),
    245         outer_(generator->execution_result()),
    246         allocator_(generator),
    247         result_identified_(false) {
    248     generator_->set_execution_result(this);
    249   }
    250 
    251   virtual ~ExpressionResultScope() {
    252     generator_->set_execution_result(outer_);
    253     DCHECK(result_identified());
    254   }
    255 
    256   bool IsEffect() const { return kind_ == Expression::kEffect; }
    257   bool IsValue() const { return kind_ == Expression::kValue; }
    258 
    259   virtual void SetResultInAccumulator() = 0;
    260   virtual void SetResultInRegister(Register reg) = 0;
    261 
    262  protected:
    263   ExpressionResultScope* outer() const { return outer_; }
    264   BytecodeArrayBuilder* builder() const { return generator_->builder(); }
    265   const RegisterAllocationScope* allocator() const { return &allocator_; }
    266 
    267   void set_result_identified() {
    268     DCHECK(!result_identified());
    269     result_identified_ = true;
    270   }
    271 
    272   bool result_identified() const { return result_identified_; }
    273 
    274  private:
    275   BytecodeGenerator* generator_;
    276   Expression::Context kind_;
    277   ExpressionResultScope* outer_;
    278   RegisterAllocationScope allocator_;
    279   bool result_identified_;
    280 
    281   DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
    282 };
    283 
    284 
    285 // Scoped class used when the result of the current expression is not
    286 // expected to produce a result.
    287 class BytecodeGenerator::EffectResultScope final
    288     : public ExpressionResultScope {
    289  public:
    290   explicit EffectResultScope(BytecodeGenerator* generator)
    291       : ExpressionResultScope(generator, Expression::kEffect) {
    292     set_result_identified();
    293   }
    294 
    295   virtual void SetResultInAccumulator() {}
    296   virtual void SetResultInRegister(Register reg) {}
    297 };
    298 
    299 
    300 // Scoped class used when the result of the current expression to be
    301 // evaluated should go into the interpreter's accumulator register.
    302 class BytecodeGenerator::AccumulatorResultScope final
    303     : public ExpressionResultScope {
    304  public:
    305   explicit AccumulatorResultScope(BytecodeGenerator* generator)
    306       : ExpressionResultScope(generator, Expression::kValue) {}
    307 
    308   virtual void SetResultInAccumulator() { set_result_identified(); }
    309 
    310   virtual void SetResultInRegister(Register reg) {
    311     builder()->LoadAccumulatorWithRegister(reg);
    312     set_result_identified();
    313   }
    314 };
    315 
    316 
    317 // Scoped class used when the result of the current expression to be
    318 // evaluated should go into an interpreter register.
    319 class BytecodeGenerator::RegisterResultScope final
    320     : public ExpressionResultScope {
    321  public:
    322   explicit RegisterResultScope(BytecodeGenerator* generator)
    323       : ExpressionResultScope(generator, Expression::kValue) {}
    324 
    325   virtual void SetResultInAccumulator() {
    326     result_register_ = allocator()->outer()->NewRegister();
    327     builder()->StoreAccumulatorInRegister(result_register_);
    328     set_result_identified();
    329   }
    330 
    331   virtual void SetResultInRegister(Register reg) {
    332     DCHECK(builder()->RegisterIsParameterOrLocal(reg) ||
    333            (builder()->RegisterIsTemporary(reg) &&
    334             !allocator()->RegisterIsAllocatedInThisScope(reg)));
    335     result_register_ = reg;
    336     set_result_identified();
    337   }
    338 
    339   Register ResultRegister() const { return result_register_; }
    340 
    341  private:
    342   Register result_register_;
    343 };
    344 
    345 
    346 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone)
    347     : isolate_(isolate),
    348       zone_(zone),
    349       builder_(isolate, zone),
    350       info_(nullptr),
    351       scope_(nullptr),
    352       globals_(0, zone),
    353       execution_control_(nullptr),
    354       execution_context_(nullptr),
    355       execution_result_(nullptr),
    356       register_allocator_(nullptr) {
    357   InitializeAstVisitor(isolate);
    358 }
    359 
    360 
    361 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) {
    362   set_info(info);
    363   set_scope(info->scope());
    364 
    365   // Initialize the incoming context.
    366   ContextScope incoming_context(this, scope(), false);
    367 
    368   builder()->set_parameter_count(info->num_parameters_including_this());
    369   builder()->set_locals_count(scope()->num_stack_slots());
    370   builder()->set_context_count(scope()->MaxNestedContextChainLength());
    371 
    372   // Build function context only if there are context allocated variables.
    373   if (scope()->NeedsContext()) {
    374     // Push a new inner context scope for the function.
    375     VisitNewLocalFunctionContext();
    376     ContextScope local_function_context(this, scope(), false);
    377     VisitBuildLocalActivationContext();
    378     MakeBytecodeBody();
    379   } else {
    380     MakeBytecodeBody();
    381   }
    382 
    383   set_scope(nullptr);
    384   set_info(nullptr);
    385   return builder_.ToBytecodeArray();
    386 }
    387 
    388 
    389 void BytecodeGenerator::MakeBytecodeBody() {
    390   // Build the arguments object if it is used.
    391   VisitArgumentsObject(scope()->arguments());
    392 
    393   // TODO(mythria): Build rest arguments array if it is used.
    394   int rest_index;
    395   if (scope()->rest_parameter(&rest_index)) {
    396     UNIMPLEMENTED();
    397   }
    398 
    399   // Build assignment to {.this_function} variable if it is used.
    400   VisitThisFunctionVariable(scope()->this_function_var());
    401 
    402   // Build assignment to {new.target} variable if it is used.
    403   VisitNewTargetVariable(scope()->new_target_var());
    404 
    405   // TODO(rmcilroy): Emit tracing call if requested to do so.
    406   if (FLAG_trace) {
    407     UNIMPLEMENTED();
    408   }
    409 
    410   // Visit illegal re-declaration and bail out if it exists.
    411   if (scope()->HasIllegalRedeclaration()) {
    412     Visit(scope()->GetIllegalRedeclaration());
    413     return;
    414   }
    415 
    416   // Visit declarations within the function scope.
    417   VisitDeclarations(scope()->declarations());
    418 
    419   // Visit statements in the function body.
    420   VisitStatements(info()->literal()->body());
    421 }
    422 
    423 
    424 void BytecodeGenerator::VisitBlock(Block* stmt) {
    425   BlockBuilder block_builder(this->builder());
    426   ControlScopeForBreakable execution_control(this, stmt, &block_builder);
    427 
    428   if (stmt->scope() == NULL) {
    429     // Visit statements in the same scope, no declarations.
    430     VisitStatements(stmt->statements());
    431   } else {
    432     // Visit declarations and statements in a block scope.
    433     if (stmt->scope()->NeedsContext()) {
    434       VisitNewLocalBlockContext(stmt->scope());
    435       ContextScope scope(this, stmt->scope());
    436       VisitDeclarations(stmt->scope()->declarations());
    437       VisitStatements(stmt->statements());
    438     } else {
    439       VisitDeclarations(stmt->scope()->declarations());
    440       VisitStatements(stmt->statements());
    441     }
    442   }
    443   if (stmt->labels() != nullptr) block_builder.EndBlock();
    444 }
    445 
    446 
    447 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
    448   Variable* variable = decl->proxy()->var();
    449   VariableMode mode = decl->mode();
    450   // Const and let variables are initialized with the hole so that we can
    451   // check that they are only assigned once.
    452   bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
    453   switch (variable->location()) {
    454     case VariableLocation::GLOBAL:
    455     case VariableLocation::UNALLOCATED: {
    456       Handle<Oddball> value = variable->binding_needs_init()
    457                                   ? isolate()->factory()->the_hole_value()
    458                                   : isolate()->factory()->undefined_value();
    459       globals()->push_back(variable->name());
    460       globals()->push_back(value);
    461       break;
    462     }
    463     case VariableLocation::LOCAL:
    464       if (hole_init) {
    465         Register destination(variable->index());
    466         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
    467       }
    468       break;
    469     case VariableLocation::PARAMETER:
    470       if (hole_init) {
    471         // The parameter indices are shifted by 1 (receiver is variable
    472         // index -1 but is parameter index 0 in BytecodeArrayBuilder).
    473         Register destination(builder()->Parameter(variable->index() + 1));
    474         builder()->LoadTheHole().StoreAccumulatorInRegister(destination);
    475       }
    476       break;
    477     case VariableLocation::CONTEXT:
    478       if (hole_init) {
    479         builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(),
    480                                                   variable->index());
    481       }
    482       break;
    483     case VariableLocation::LOOKUP:
    484       UNIMPLEMENTED();
    485       break;
    486   }
    487 }
    488 
    489 
    490 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
    491   Variable* variable = decl->proxy()->var();
    492   switch (variable->location()) {
    493     case VariableLocation::GLOBAL:
    494     case VariableLocation::UNALLOCATED: {
    495       Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
    496           decl->fun(), info()->script(), info());
    497       // Check for stack-overflow exception.
    498       if (function.is_null()) return SetStackOverflow();
    499       globals()->push_back(variable->name());
    500       globals()->push_back(function);
    501       break;
    502     }
    503     case VariableLocation::PARAMETER:
    504     case VariableLocation::LOCAL: {
    505       VisitForAccumulatorValue(decl->fun());
    506       VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid());
    507       break;
    508     }
    509     case VariableLocation::CONTEXT: {
    510       DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
    511       VisitForAccumulatorValue(decl->fun());
    512       builder()->StoreContextSlot(execution_context()->reg(),
    513                                   variable->index());
    514       break;
    515     }
    516     case VariableLocation::LOOKUP:
    517       UNIMPLEMENTED();
    518   }
    519 }
    520 
    521 
    522 void BytecodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
    523   UNIMPLEMENTED();
    524 }
    525 
    526 
    527 void BytecodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
    528   UNIMPLEMENTED();
    529 }
    530 
    531 
    532 void BytecodeGenerator::VisitDeclarations(
    533     ZoneList<Declaration*>* declarations) {
    534   RegisterAllocationScope register_scope(this);
    535   DCHECK(globals()->empty());
    536   AstVisitor::VisitDeclarations(declarations);
    537   if (globals()->empty()) return;
    538   int array_index = 0;
    539   Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
    540       static_cast<int>(globals()->size()), TENURED);
    541   for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
    542   int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
    543                       DeclareGlobalsNativeFlag::encode(info()->is_native()) |
    544                       DeclareGlobalsLanguageMode::encode(language_mode());
    545 
    546   Register pairs = register_allocator()->NewRegister();
    547   builder()->LoadLiteral(data);
    548   builder()->StoreAccumulatorInRegister(pairs);
    549 
    550   Register flags = register_allocator()->NewRegister();
    551   builder()->LoadLiteral(Smi::FromInt(encoded_flags));
    552   builder()->StoreAccumulatorInRegister(flags);
    553   DCHECK(flags.index() == pairs.index() + 1);
    554 
    555   builder()->CallRuntime(Runtime::kDeclareGlobals, pairs, 2);
    556   globals()->clear();
    557 }
    558 
    559 
    560 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
    561   for (int i = 0; i < statements->length(); i++) {
    562     // Allocate an outer register allocations scope for the statement.
    563     RegisterAllocationScope allocation_scope(this);
    564     Statement* stmt = statements->at(i);
    565     Visit(stmt);
    566     if (stmt->IsJump()) break;
    567   }
    568 }
    569 
    570 
    571 void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
    572   VisitForEffect(stmt->expression());
    573 }
    574 
    575 
    576 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
    577 }
    578 
    579 
    580 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
    581   BytecodeLabel else_label, end_label;
    582   if (stmt->condition()->ToBooleanIsTrue()) {
    583     // Generate then block unconditionally as always true.
    584     Visit(stmt->then_statement());
    585   } else if (stmt->condition()->ToBooleanIsFalse()) {
    586     // Generate else block unconditionally if it exists.
    587     if (stmt->HasElseStatement()) {
    588       Visit(stmt->else_statement());
    589     }
    590   } else {
    591     // TODO(oth): If then statement is BreakStatement or
    592     // ContinueStatement we can reduce number of generated
    593     // jump/jump_ifs here. See BasicLoops test.
    594     VisitForAccumulatorValue(stmt->condition());
    595     builder()->JumpIfFalse(&else_label);
    596     Visit(stmt->then_statement());
    597     if (stmt->HasElseStatement()) {
    598       builder()->Jump(&end_label);
    599       builder()->Bind(&else_label);
    600       Visit(stmt->else_statement());
    601     } else {
    602       builder()->Bind(&else_label);
    603     }
    604     builder()->Bind(&end_label);
    605   }
    606 }
    607 
    608 
    609 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
    610     SloppyBlockFunctionStatement* stmt) {
    611   Visit(stmt->statement());
    612 }
    613 
    614 
    615 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
    616   execution_control()->Continue(stmt->target());
    617 }
    618 
    619 
    620 void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
    621   execution_control()->Break(stmt->target());
    622 }
    623 
    624 
    625 void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
    626   VisitForAccumulatorValue(stmt->expression());
    627   builder()->Return();
    628 }
    629 
    630 
    631 void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
    632   UNIMPLEMENTED();
    633 }
    634 
    635 
    636 void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
    637   // We need this scope because we visit for register values. We have to
    638   // maintain a execution result scope where registers can be allocated.
    639   ZoneList<CaseClause*>* clauses = stmt->cases();
    640   SwitchBuilder switch_builder(builder(), clauses->length());
    641   ControlScopeForBreakable scope(this, stmt, &switch_builder);
    642   int default_index = -1;
    643 
    644   // Keep the switch value in a register until a case matches.
    645   Register tag = VisitForRegisterValue(stmt->tag());
    646 
    647   // Iterate over all cases and create nodes for label comparison.
    648   BytecodeLabel done_label;
    649   for (int i = 0; i < clauses->length(); i++) {
    650     CaseClause* clause = clauses->at(i);
    651 
    652     // The default is not a test, remember index.
    653     if (clause->is_default()) {
    654       default_index = i;
    655       continue;
    656     }
    657 
    658     // Perform label comparison as if via '===' with tag.
    659     VisitForAccumulatorValue(clause->label());
    660     builder()->CompareOperation(Token::Value::EQ_STRICT, tag,
    661                                 language_mode_strength());
    662     switch_builder.Case(i);
    663   }
    664 
    665   if (default_index >= 0) {
    666     // Emit default jump if there is a default case.
    667     switch_builder.DefaultAt(default_index);
    668   } else {
    669     // Otherwise if we have reached here none of the cases matched, so jump to
    670     // done.
    671     builder()->Jump(&done_label);
    672   }
    673 
    674   // Iterate over all cases and create the case bodies.
    675   for (int i = 0; i < clauses->length(); i++) {
    676     CaseClause* clause = clauses->at(i);
    677     switch_builder.SetCaseTarget(i);
    678     VisitStatements(clause->statements());
    679   }
    680   builder()->Bind(&done_label);
    681 
    682   switch_builder.SetBreakTarget(done_label);
    683 }
    684 
    685 
    686 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
    687   // Handled entirely in VisitSwitchStatement.
    688   UNREACHABLE();
    689 }
    690 
    691 
    692 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
    693   LoopBuilder loop_builder(builder());
    694   ControlScopeForIteration execution_control(this, stmt, &loop_builder);
    695   loop_builder.LoopHeader();
    696   if (stmt->cond()->ToBooleanIsFalse()) {
    697     Visit(stmt->body());
    698     loop_builder.Condition();
    699   } else if (stmt->cond()->ToBooleanIsTrue()) {
    700     loop_builder.Condition();
    701     Visit(stmt->body());
    702     loop_builder.JumpToHeader();
    703   } else {
    704     Visit(stmt->body());
    705     loop_builder.Condition();
    706     VisitForAccumulatorValue(stmt->cond());
    707     loop_builder.JumpToHeaderIfTrue();
    708   }
    709   loop_builder.EndLoop();
    710 }
    711 
    712 
    713 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
    714   if (stmt->cond()->ToBooleanIsFalse()) {
    715     // If the condition is false there is no need to generate the loop.
    716     return;
    717   }
    718 
    719   LoopBuilder loop_builder(builder());
    720   ControlScopeForIteration execution_control(this, stmt, &loop_builder);
    721   loop_builder.LoopHeader();
    722   loop_builder.Condition();
    723   if (!stmt->cond()->ToBooleanIsTrue()) {
    724     VisitForAccumulatorValue(stmt->cond());
    725     loop_builder.BreakIfFalse();
    726   }
    727   Visit(stmt->body());
    728   loop_builder.JumpToHeader();
    729   loop_builder.EndLoop();
    730 }
    731 
    732 
    733 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
    734   if (stmt->init() != nullptr) {
    735     Visit(stmt->init());
    736   }
    737   if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
    738     // If the condition is known to be false there is no need to generate
    739     // body, next or condition blocks. Init block should be generated.
    740     return;
    741   }
    742 
    743   LoopBuilder loop_builder(builder());
    744   ControlScopeForIteration execution_control(this, stmt, &loop_builder);
    745 
    746   loop_builder.LoopHeader();
    747   loop_builder.Condition();
    748   if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
    749     VisitForAccumulatorValue(stmt->cond());
    750     loop_builder.BreakIfFalse();
    751   }
    752   Visit(stmt->body());
    753   if (stmt->next() != nullptr) {
    754     loop_builder.Next();
    755     Visit(stmt->next());
    756   }
    757   loop_builder.JumpToHeader();
    758   loop_builder.EndLoop();
    759 }
    760 
    761 
    762 void BytecodeGenerator::VisitForInAssignment(Expression* expr,
    763                                              FeedbackVectorSlot slot) {
    764   DCHECK(expr->IsValidReferenceExpression());
    765 
    766   // Evaluate assignment starting with the value to be stored in the
    767   // accumulator.
    768   Property* property = expr->AsProperty();
    769   LhsKind assign_type = Property::GetAssignType(property);
    770   switch (assign_type) {
    771     case VARIABLE: {
    772       Variable* variable = expr->AsVariableProxy()->var();
    773       VisitVariableAssignment(variable, slot);
    774       break;
    775     }
    776     case NAMED_PROPERTY: {
    777       RegisterAllocationScope register_scope(this);
    778       Register value = register_allocator()->NewRegister();
    779       builder()->StoreAccumulatorInRegister(value);
    780       Register object = VisitForRegisterValue(property->obj());
    781       Handle<String> name = property->key()->AsLiteral()->AsPropertyName();
    782       builder()->LoadAccumulatorWithRegister(value);
    783       builder()->StoreNamedProperty(object, name, feedback_index(slot),
    784                                     language_mode());
    785       break;
    786     }
    787     case KEYED_PROPERTY: {
    788       RegisterAllocationScope register_scope(this);
    789       Register value = register_allocator()->NewRegister();
    790       builder()->StoreAccumulatorInRegister(value);
    791       Register object = VisitForRegisterValue(property->obj());
    792       Register key = VisitForRegisterValue(property->key());
    793       builder()->LoadAccumulatorWithRegister(value);
    794       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
    795                                     language_mode());
    796       break;
    797     }
    798     case NAMED_SUPER_PROPERTY:
    799     case KEYED_SUPER_PROPERTY:
    800       UNIMPLEMENTED();
    801   }
    802 }
    803 
    804 
    805 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
    806   if (stmt->subject()->IsNullLiteral() ||
    807       stmt->subject()->IsUndefinedLiteral(isolate())) {
    808     // ForIn generates lots of code, skip if it wouldn't produce any effects.
    809     return;
    810   }
    811 
    812   LoopBuilder loop_builder(builder());
    813   ControlScopeForIteration control_scope(this, stmt, &loop_builder);
    814   BytecodeLabel subject_null_label, subject_undefined_label, not_object_label;
    815 
    816   // Prepare the state for executing ForIn.
    817   VisitForAccumulatorValue(stmt->subject());
    818   builder()->JumpIfUndefined(&subject_undefined_label);
    819   builder()->JumpIfNull(&subject_null_label);
    820   Register receiver = register_allocator()->NewRegister();
    821   builder()->CastAccumulatorToJSObject();
    822   builder()->JumpIfNull(&not_object_label);
    823   builder()->StoreAccumulatorInRegister(receiver);
    824   Register cache_type = register_allocator()->NewRegister();
    825   Register cache_array = register_allocator()->NewRegister();
    826   Register cache_length = register_allocator()->NewRegister();
    827   builder()->ForInPrepare(cache_type, cache_array, cache_length);
    828 
    829   // Set up loop counter
    830   Register index = register_allocator()->NewRegister();
    831   builder()->LoadLiteral(Smi::FromInt(0));
    832   builder()->StoreAccumulatorInRegister(index);
    833 
    834   // The loop
    835   loop_builder.LoopHeader();
    836   loop_builder.Condition();
    837   builder()->ForInDone(index, cache_length);
    838   loop_builder.BreakIfTrue();
    839   builder()->ForInNext(receiver, cache_type, cache_array, index);
    840   loop_builder.ContinueIfUndefined();
    841   VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
    842   Visit(stmt->body());
    843   loop_builder.Next();
    844   builder()->ForInStep(index);
    845   builder()->StoreAccumulatorInRegister(index);
    846   loop_builder.JumpToHeader();
    847   loop_builder.EndLoop();
    848   builder()->Bind(&not_object_label);
    849   builder()->Bind(&subject_null_label);
    850   builder()->Bind(&subject_undefined_label);
    851 }
    852 
    853 
    854 void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
    855   UNIMPLEMENTED();
    856 }
    857 
    858 
    859 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
    860   if (FLAG_ignition_fake_try_catch) {
    861     Visit(stmt->try_block());
    862     return;
    863   }
    864   UNIMPLEMENTED();
    865 }
    866 
    867 
    868 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
    869   if (FLAG_ignition_fake_try_catch) {
    870     Visit(stmt->try_block());
    871     Visit(stmt->finally_block());
    872     return;
    873   }
    874   UNIMPLEMENTED();
    875 }
    876 
    877 
    878 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
    879   UNIMPLEMENTED();
    880 }
    881 
    882 
    883 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
    884   // Find or build a shared function info.
    885   Handle<SharedFunctionInfo> shared_info =
    886       Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
    887   CHECK(!shared_info.is_null());  // TODO(rmcilroy): Set stack overflow?
    888   builder()->CreateClosure(shared_info,
    889                            expr->pretenure() ? TENURED : NOT_TENURED);
    890   execution_result()->SetResultInAccumulator();
    891 }
    892 
    893 
    894 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
    895   UNIMPLEMENTED();
    896 }
    897 
    898 
    899 void BytecodeGenerator::VisitNativeFunctionLiteral(
    900     NativeFunctionLiteral* expr) {
    901   UNIMPLEMENTED();
    902 }
    903 
    904 
    905 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
    906   UNIMPLEMENTED();
    907 }
    908 
    909 
    910 void BytecodeGenerator::VisitConditional(Conditional* expr) {
    911   // TODO(rmcilroy): Spot easy cases where there code would not need to
    912   // emit the then block or the else block, e.g. condition is
    913   // obviously true/1/false/0.
    914 
    915   BytecodeLabel else_label, end_label;
    916 
    917   VisitForAccumulatorValue(expr->condition());
    918   builder()->JumpIfFalse(&else_label);
    919 
    920   VisitForAccumulatorValue(expr->then_expression());
    921   builder()->Jump(&end_label);
    922 
    923   builder()->Bind(&else_label);
    924   VisitForAccumulatorValue(expr->else_expression());
    925   builder()->Bind(&end_label);
    926 
    927   execution_result()->SetResultInAccumulator();
    928 }
    929 
    930 
    931 void BytecodeGenerator::VisitLiteral(Literal* expr) {
    932   if (!execution_result()->IsEffect()) {
    933     Handle<Object> value = expr->value();
    934     if (value->IsSmi()) {
    935       builder()->LoadLiteral(Smi::cast(*value));
    936     } else if (value->IsUndefined()) {
    937       builder()->LoadUndefined();
    938     } else if (value->IsTrue()) {
    939       builder()->LoadTrue();
    940     } else if (value->IsFalse()) {
    941       builder()->LoadFalse();
    942     } else if (value->IsNull()) {
    943       builder()->LoadNull();
    944     } else if (value->IsTheHole()) {
    945       builder()->LoadTheHole();
    946     } else {
    947       builder()->LoadLiteral(value);
    948     }
    949     execution_result()->SetResultInAccumulator();
    950   }
    951 }
    952 
    953 
    954 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
    955   // Materialize a regular expression literal.
    956   builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(),
    957                                  expr->flags());
    958   execution_result()->SetResultInAccumulator();
    959 }
    960 
    961 
    962 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
    963   // Deep-copy the literal boilerplate.
    964   builder()->CreateObjectLiteral(expr->constant_properties(),
    965                                  expr->literal_index(),
    966                                  expr->ComputeFlags(true));
    967   Register literal;
    968 
    969   // Store computed values into the literal.
    970   bool literal_in_accumulator = true;
    971   int property_index = 0;
    972   AccessorTable accessor_table(zone());
    973   for (; property_index < expr->properties()->length(); property_index++) {
    974     ObjectLiteral::Property* property = expr->properties()->at(property_index);
    975     if (property->is_computed_name()) break;
    976     if (property->IsCompileTimeValue()) continue;
    977 
    978     if (literal_in_accumulator) {
    979       literal = register_allocator()->NewRegister();
    980       builder()->StoreAccumulatorInRegister(literal);
    981       literal_in_accumulator = false;
    982     }
    983 
    984     RegisterAllocationScope inner_register_scope(this);
    985     Literal* literal_key = property->key()->AsLiteral();
    986     switch (property->kind()) {
    987       case ObjectLiteral::Property::CONSTANT:
    988         UNREACHABLE();
    989       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
    990         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
    991       // Fall through.
    992       case ObjectLiteral::Property::COMPUTED: {
    993         // It is safe to use [[Put]] here because the boilerplate already
    994         // contains computed properties with an uninitialized value.
    995         if (literal_key->value()->IsInternalizedString()) {
    996           if (property->emit_store()) {
    997             VisitForAccumulatorValue(property->value());
    998             builder()->StoreNamedProperty(
    999                 literal, literal_key->AsPropertyName(),
   1000                 feedback_index(property->GetSlot(0)), language_mode());
   1001           } else {
   1002             VisitForEffect(property->value());
   1003           }
   1004         } else {
   1005           register_allocator()->PrepareForConsecutiveAllocations(3);
   1006           Register key = register_allocator()->NextConsecutiveRegister();
   1007           Register value = register_allocator()->NextConsecutiveRegister();
   1008           Register language = register_allocator()->NextConsecutiveRegister();
   1009           // TODO(oth): This is problematic - can't assume contiguous here.
   1010           // literal is allocated in outer register scope, whereas key, value,
   1011           // language are in another.
   1012           DCHECK(Register::AreContiguous(literal, key, value, language));
   1013           VisitForAccumulatorValue(property->key());
   1014           builder()->StoreAccumulatorInRegister(key);
   1015           VisitForAccumulatorValue(property->value());
   1016           builder()->StoreAccumulatorInRegister(value);
   1017           if (property->emit_store()) {
   1018             builder()
   1019                 ->LoadLiteral(Smi::FromInt(SLOPPY))
   1020                 .StoreAccumulatorInRegister(language)
   1021                 .CallRuntime(Runtime::kSetProperty, literal, 4);
   1022             VisitSetHomeObject(value, literal, property);
   1023           }
   1024         }
   1025         break;
   1026       }
   1027       case ObjectLiteral::Property::PROTOTYPE: {
   1028         register_allocator()->PrepareForConsecutiveAllocations(1);
   1029         DCHECK(property->emit_store());
   1030         Register value = register_allocator()->NextConsecutiveRegister();
   1031         DCHECK(Register::AreContiguous(literal, value));
   1032         VisitForAccumulatorValue(property->value());
   1033         builder()->StoreAccumulatorInRegister(value).CallRuntime(
   1034             Runtime::kInternalSetPrototype, literal, 2);
   1035         break;
   1036       }
   1037       case ObjectLiteral::Property::GETTER:
   1038         if (property->emit_store()) {
   1039           accessor_table.lookup(literal_key)->second->getter = property;
   1040         }
   1041         break;
   1042       case ObjectLiteral::Property::SETTER:
   1043         if (property->emit_store()) {
   1044           accessor_table.lookup(literal_key)->second->setter = property;
   1045         }
   1046         break;
   1047     }
   1048   }
   1049 
   1050   // Define accessors, using only a single call to the runtime for each pair of
   1051   // corresponding getters and setters.
   1052   for (AccessorTable::Iterator it = accessor_table.begin();
   1053        it != accessor_table.end(); ++it) {
   1054     RegisterAllocationScope inner_register_scope(this);
   1055     register_allocator()->PrepareForConsecutiveAllocations(4);
   1056     Register name = register_allocator()->NextConsecutiveRegister();
   1057     Register getter = register_allocator()->NextConsecutiveRegister();
   1058     Register setter = register_allocator()->NextConsecutiveRegister();
   1059     Register attr = register_allocator()->NextConsecutiveRegister();
   1060     DCHECK(Register::AreContiguous(literal, name, getter, setter, attr));
   1061     VisitForAccumulatorValue(it->first);
   1062     builder()->StoreAccumulatorInRegister(name);
   1063     VisitObjectLiteralAccessor(literal, it->second->getter, getter);
   1064     VisitObjectLiteralAccessor(literal, it->second->setter, setter);
   1065     builder()
   1066         ->LoadLiteral(Smi::FromInt(NONE))
   1067         .StoreAccumulatorInRegister(attr)
   1068         .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, literal, 5);
   1069   }
   1070 
   1071   // Object literals have two parts. The "static" part on the left contains no
   1072   // computed property names, and so we can compute its map ahead of time; see
   1073   // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
   1074   // with the first computed property name and continues with all properties to
   1075   // its right. All the code from above initializes the static component of the
   1076   // object literal, and arranges for the map of the result to reflect the
   1077   // static order in which the keys appear. For the dynamic properties, we
   1078   // compile them into a series of "SetOwnProperty" runtime calls. This will
   1079   // preserve insertion order.
   1080   for (; property_index < expr->properties()->length(); property_index++) {
   1081     if (literal_in_accumulator) {
   1082       literal = register_allocator()->NewRegister();
   1083       builder()->StoreAccumulatorInRegister(literal);
   1084       literal_in_accumulator = false;
   1085     }
   1086 
   1087     ObjectLiteral::Property* property = expr->properties()->at(property_index);
   1088     RegisterAllocationScope inner_register_scope(this);
   1089     if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
   1090       DCHECK(property->emit_store());
   1091       Register value = register_allocator()->NewRegister();
   1092       DCHECK(Register::AreContiguous(literal, value));
   1093       VisitForAccumulatorValue(property->value());
   1094       builder()->StoreAccumulatorInRegister(value).CallRuntime(
   1095           Runtime::kInternalSetPrototype, literal, 2);
   1096       continue;
   1097     }
   1098 
   1099     register_allocator()->PrepareForConsecutiveAllocations(3);
   1100     Register key = register_allocator()->NextConsecutiveRegister();
   1101     Register value = register_allocator()->NextConsecutiveRegister();
   1102     Register attr = register_allocator()->NextConsecutiveRegister();
   1103     DCHECK(Register::AreContiguous(literal, key, value, attr));
   1104 
   1105     VisitForAccumulatorValue(property->key());
   1106     builder()->CastAccumulatorToName().StoreAccumulatorInRegister(key);
   1107     VisitForAccumulatorValue(property->value());
   1108     builder()->StoreAccumulatorInRegister(value);
   1109     VisitSetHomeObject(value, literal, property);
   1110     builder()->LoadLiteral(Smi::FromInt(NONE)).StoreAccumulatorInRegister(attr);
   1111     Runtime::FunctionId function_id = static_cast<Runtime::FunctionId>(-1);
   1112     switch (property->kind()) {
   1113       case ObjectLiteral::Property::CONSTANT:
   1114       case ObjectLiteral::Property::COMPUTED:
   1115       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   1116         function_id = Runtime::kDefineDataPropertyUnchecked;
   1117         break;
   1118       case ObjectLiteral::Property::PROTOTYPE:
   1119         UNREACHABLE();  // Handled specially above.
   1120         break;
   1121       case ObjectLiteral::Property::GETTER:
   1122         function_id = Runtime::kDefineGetterPropertyUnchecked;
   1123         break;
   1124       case ObjectLiteral::Property::SETTER:
   1125         function_id = Runtime::kDefineSetterPropertyUnchecked;
   1126         break;
   1127     }
   1128     builder()->CallRuntime(function_id, literal, 4);
   1129   }
   1130 
   1131   // Transform literals that contain functions to fast properties.
   1132   if (expr->has_function()) {
   1133     DCHECK(!literal_in_accumulator);
   1134     builder()->CallRuntime(Runtime::kToFastProperties, literal, 1);
   1135   }
   1136 
   1137   if (!literal_in_accumulator) {
   1138     // Restore literal array into accumulator.
   1139     builder()->LoadAccumulatorWithRegister(literal);
   1140   }
   1141   execution_result()->SetResultInAccumulator();
   1142 }
   1143 
   1144 
   1145 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
   1146   // Deep-copy the literal boilerplate.
   1147   builder()->CreateArrayLiteral(expr->constant_elements(),
   1148                                 expr->literal_index(),
   1149                                 expr->ComputeFlags(true));
   1150   Register index, literal;
   1151 
   1152   // Evaluate all the non-constant subexpressions and store them into the
   1153   // newly cloned array.
   1154   bool literal_in_accumulator = true;
   1155   for (int array_index = 0; array_index < expr->values()->length();
   1156        array_index++) {
   1157     Expression* subexpr = expr->values()->at(array_index);
   1158     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
   1159     if (subexpr->IsSpread()) {
   1160       // TODO(rmcilroy): Deal with spread expressions.
   1161       UNIMPLEMENTED();
   1162     }
   1163 
   1164     if (literal_in_accumulator) {
   1165       index = register_allocator()->NewRegister();
   1166       literal = register_allocator()->NewRegister();
   1167       builder()->StoreAccumulatorInRegister(literal);
   1168       literal_in_accumulator = false;
   1169     }
   1170 
   1171     FeedbackVectorSlot slot = expr->LiteralFeedbackSlot();
   1172     builder()
   1173         ->LoadLiteral(Smi::FromInt(array_index))
   1174         .StoreAccumulatorInRegister(index);
   1175     VisitForAccumulatorValue(subexpr);
   1176     builder()->StoreKeyedProperty(literal, index, feedback_index(slot),
   1177                                   language_mode());
   1178   }
   1179 
   1180   if (!literal_in_accumulator) {
   1181     // Restore literal array into accumulator.
   1182     builder()->LoadAccumulatorWithRegister(literal);
   1183   }
   1184   execution_result()->SetResultInAccumulator();
   1185 }
   1186 
   1187 
   1188 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
   1189   VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
   1190 }
   1191 
   1192 
   1193 void BytecodeGenerator::VisitVariableLoad(Variable* variable,
   1194                                           FeedbackVectorSlot slot,
   1195                                           TypeofMode typeof_mode) {
   1196   switch (variable->location()) {
   1197     case VariableLocation::LOCAL: {
   1198       Register source(Register(variable->index()));
   1199       builder()->LoadAccumulatorWithRegister(source);
   1200       execution_result()->SetResultInAccumulator();
   1201       break;
   1202     }
   1203     case VariableLocation::PARAMETER: {
   1204       // The parameter indices are shifted by 1 (receiver is variable
   1205       // index -1 but is parameter index 0 in BytecodeArrayBuilder).
   1206       Register source = builder()->Parameter(variable->index() + 1);
   1207       builder()->LoadAccumulatorWithRegister(source);
   1208       execution_result()->SetResultInAccumulator();
   1209       break;
   1210     }
   1211     case VariableLocation::GLOBAL:
   1212     case VariableLocation::UNALLOCATED: {
   1213       builder()->LoadGlobal(variable->name(), feedback_index(slot),
   1214                             language_mode(), typeof_mode);
   1215       execution_result()->SetResultInAccumulator();
   1216       break;
   1217     }
   1218     case VariableLocation::CONTEXT: {
   1219       int depth = execution_context()->ContextChainDepth(variable->scope());
   1220       ContextScope* context = execution_context()->Previous(depth);
   1221       Register context_reg;
   1222       if (context) {
   1223         context_reg = context->reg();
   1224       } else {
   1225         context_reg = register_allocator()->NewRegister();
   1226         // Walk the context chain to find the context at the given depth.
   1227         // TODO(rmcilroy): Perform this work in a bytecode handler once we have
   1228         // a generic mechanism for performing jumps in interpreter.cc.
   1229         // TODO(mythria): Also update bytecode graph builder with correct depth
   1230         // when this changes.
   1231         builder()
   1232             ->LoadAccumulatorWithRegister(execution_context()->reg())
   1233             .StoreAccumulatorInRegister(context_reg);
   1234         for (int i = 0; i < depth; ++i) {
   1235           builder()
   1236               ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
   1237               .StoreAccumulatorInRegister(context_reg);
   1238         }
   1239       }
   1240       builder()->LoadContextSlot(context_reg, variable->index());
   1241       execution_result()->SetResultInAccumulator();
   1242       // TODO(rmcilroy): Perform check for uninitialized legacy const, const and
   1243       // let variables.
   1244       break;
   1245     }
   1246     case VariableLocation::LOOKUP: {
   1247       builder()->LoadLookupSlot(variable->name(), typeof_mode);
   1248       execution_result()->SetResultInAccumulator();
   1249       break;
   1250     }
   1251   }
   1252 }
   1253 
   1254 
   1255 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue(
   1256     Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
   1257   AccumulatorResultScope accumulator_result(this);
   1258   VisitVariableLoad(variable, slot, typeof_mode);
   1259 }
   1260 
   1261 
   1262 Register BytecodeGenerator::VisitVariableLoadForRegisterValue(
   1263     Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
   1264   RegisterResultScope register_scope(this);
   1265   VisitVariableLoad(variable, slot, typeof_mode);
   1266   return register_scope.ResultRegister();
   1267 }
   1268 
   1269 
   1270 void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
   1271                                                 FeedbackVectorSlot slot) {
   1272   switch (variable->location()) {
   1273     case VariableLocation::LOCAL: {
   1274       // TODO(rmcilroy): support const mode initialization.
   1275       Register destination(variable->index());
   1276       builder()->StoreAccumulatorInRegister(destination);
   1277       break;
   1278     }
   1279     case VariableLocation::PARAMETER: {
   1280       // The parameter indices are shifted by 1 (receiver is variable
   1281       // index -1 but is parameter index 0 in BytecodeArrayBuilder).
   1282       Register destination(builder()->Parameter(variable->index() + 1));
   1283       builder()->StoreAccumulatorInRegister(destination);
   1284       break;
   1285     }
   1286     case VariableLocation::GLOBAL:
   1287     case VariableLocation::UNALLOCATED: {
   1288       builder()->StoreGlobal(variable->name(), feedback_index(slot),
   1289                              language_mode());
   1290       break;
   1291     }
   1292     case VariableLocation::CONTEXT: {
   1293       // TODO(rmcilroy): support const mode initialization.
   1294       int depth = execution_context()->ContextChainDepth(variable->scope());
   1295       ContextScope* context = execution_context()->Previous(depth);
   1296       Register context_reg;
   1297       if (context) {
   1298         context_reg = context->reg();
   1299       } else {
   1300         Register value_temp = register_allocator()->NewRegister();
   1301         context_reg = register_allocator()->NewRegister();
   1302         // Walk the context chain to find the context at the given depth.
   1303         // TODO(rmcilroy): Perform this work in a bytecode handler once we have
   1304         // a generic mechanism for performing jumps in interpreter.cc.
   1305         // TODO(mythria): Also update bytecode graph builder with correct depth
   1306         // when this changes.
   1307         builder()
   1308             ->StoreAccumulatorInRegister(value_temp)
   1309             .LoadAccumulatorWithRegister(execution_context()->reg())
   1310             .StoreAccumulatorInRegister(context_reg);
   1311         for (int i = 0; i < depth; ++i) {
   1312           builder()
   1313               ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX)
   1314               .StoreAccumulatorInRegister(context_reg);
   1315         }
   1316         builder()->LoadAccumulatorWithRegister(value_temp);
   1317       }
   1318       builder()->StoreContextSlot(context_reg, variable->index());
   1319       break;
   1320     }
   1321     case VariableLocation::LOOKUP: {
   1322       builder()->StoreLookupSlot(variable->name(), language_mode());
   1323       break;
   1324     }
   1325   }
   1326 }
   1327 
   1328 
   1329 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
   1330   DCHECK(expr->target()->IsValidReferenceExpression());
   1331   Register object, key;
   1332   Handle<String> name;
   1333 
   1334   // Left-hand side can only be a property, a global or a variable slot.
   1335   Property* property = expr->target()->AsProperty();
   1336   LhsKind assign_type = Property::GetAssignType(property);
   1337 
   1338   // Evaluate LHS expression.
   1339   switch (assign_type) {
   1340     case VARIABLE:
   1341       // Nothing to do to evaluate variable assignment LHS.
   1342       break;
   1343     case NAMED_PROPERTY: {
   1344       object = VisitForRegisterValue(property->obj());
   1345       name = property->key()->AsLiteral()->AsPropertyName();
   1346       break;
   1347     }
   1348     case KEYED_PROPERTY: {
   1349       object = VisitForRegisterValue(property->obj());
   1350       if (expr->is_compound()) {
   1351         // Use VisitForAccumulator and store to register so that the key is
   1352         // still in the accumulator for loading the old value below.
   1353         key = register_allocator()->NewRegister();
   1354         VisitForAccumulatorValue(property->key());
   1355         builder()->StoreAccumulatorInRegister(key);
   1356       } else {
   1357         key = VisitForRegisterValue(property->key());
   1358       }
   1359       break;
   1360     }
   1361     case NAMED_SUPER_PROPERTY:
   1362     case KEYED_SUPER_PROPERTY:
   1363       UNIMPLEMENTED();
   1364   }
   1365 
   1366   // Evaluate the value and potentially handle compound assignments by loading
   1367   // the left-hand side value and performing a binary operation.
   1368   if (expr->is_compound()) {
   1369     Register old_value;
   1370     switch (assign_type) {
   1371       case VARIABLE: {
   1372         VariableProxy* proxy = expr->target()->AsVariableProxy();
   1373         old_value = VisitVariableLoadForRegisterValue(
   1374             proxy->var(), proxy->VariableFeedbackSlot());
   1375         break;
   1376       }
   1377       case NAMED_PROPERTY: {
   1378         FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   1379         old_value = register_allocator()->NewRegister();
   1380         builder()
   1381             ->LoadNamedProperty(object, name, feedback_index(slot),
   1382                                 language_mode())
   1383             .StoreAccumulatorInRegister(old_value);
   1384         break;
   1385       }
   1386       case KEYED_PROPERTY: {
   1387         // Key is already in accumulator at this point due to evaluating the
   1388         // LHS above.
   1389         FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   1390         old_value = register_allocator()->NewRegister();
   1391         builder()
   1392             ->LoadKeyedProperty(object, feedback_index(slot), language_mode())
   1393             .StoreAccumulatorInRegister(old_value);
   1394         break;
   1395       }
   1396       case NAMED_SUPER_PROPERTY:
   1397       case KEYED_SUPER_PROPERTY:
   1398         UNIMPLEMENTED();
   1399         break;
   1400     }
   1401     VisitForAccumulatorValue(expr->value());
   1402     builder()->BinaryOperation(expr->binary_op(), old_value,
   1403                                language_mode_strength());
   1404   } else {
   1405     VisitForAccumulatorValue(expr->value());
   1406   }
   1407 
   1408   // Store the value.
   1409   FeedbackVectorSlot slot = expr->AssignmentSlot();
   1410   switch (assign_type) {
   1411     case VARIABLE: {
   1412       // TODO(oth): The VisitVariableAssignment() call is hard to reason about.
   1413       // Is the value in the accumulator safe? Yes, but scary.
   1414       Variable* variable = expr->target()->AsVariableProxy()->var();
   1415       VisitVariableAssignment(variable, slot);
   1416       break;
   1417     }
   1418     case NAMED_PROPERTY:
   1419       builder()->StoreNamedProperty(object, name, feedback_index(slot),
   1420                                     language_mode());
   1421       break;
   1422     case KEYED_PROPERTY:
   1423       builder()->StoreKeyedProperty(object, key, feedback_index(slot),
   1424                                     language_mode());
   1425       break;
   1426     case NAMED_SUPER_PROPERTY:
   1427     case KEYED_SUPER_PROPERTY:
   1428       UNIMPLEMENTED();
   1429   }
   1430   execution_result()->SetResultInAccumulator();
   1431 }
   1432 
   1433 
   1434 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); }
   1435 
   1436 
   1437 void BytecodeGenerator::VisitThrow(Throw* expr) {
   1438   VisitForAccumulatorValue(expr->exception());
   1439   builder()->Throw();
   1440 }
   1441 
   1442 
   1443 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
   1444   LhsKind property_kind = Property::GetAssignType(expr);
   1445   FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
   1446   switch (property_kind) {
   1447     case VARIABLE:
   1448       UNREACHABLE();
   1449     case NAMED_PROPERTY: {
   1450       builder()->LoadNamedProperty(obj,
   1451                                    expr->key()->AsLiteral()->AsPropertyName(),
   1452                                    feedback_index(slot), language_mode());
   1453       break;
   1454     }
   1455     case KEYED_PROPERTY: {
   1456       VisitForAccumulatorValue(expr->key());
   1457       builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode());
   1458       break;
   1459     }
   1460     case NAMED_SUPER_PROPERTY:
   1461     case KEYED_SUPER_PROPERTY:
   1462       UNIMPLEMENTED();
   1463   }
   1464   execution_result()->SetResultInAccumulator();
   1465 }
   1466 
   1467 
   1468 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj,
   1469                                                         Property* expr) {
   1470   AccumulatorResultScope result_scope(this);
   1471   VisitPropertyLoad(obj, expr);
   1472 }
   1473 
   1474 
   1475 void BytecodeGenerator::VisitProperty(Property* expr) {
   1476   Register obj = VisitForRegisterValue(expr->obj());
   1477   VisitPropertyLoad(obj, expr);
   1478 }
   1479 
   1480 
   1481 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) {
   1482   if (args->length() == 0) {
   1483     return Register();
   1484   }
   1485 
   1486   // Visit arguments and place in a contiguous block of temporary
   1487   // registers.  Return the first temporary register corresponding to
   1488   // the first argument.
   1489   //
   1490   // NB the caller may have already called
   1491   // PrepareForConsecutiveAllocations() with args->length() + N. The
   1492   // second call here will be a no-op provided there have been N or
   1493   // less calls to NextConsecutiveRegister(). Otherwise, the arguments
   1494   // here will be consecutive, but they will not be consecutive with
   1495   // earlier consecutive allocations made by the caller.
   1496   register_allocator()->PrepareForConsecutiveAllocations(args->length());
   1497 
   1498   // Visit for first argument that goes into returned register
   1499   Register first_arg = register_allocator()->NextConsecutiveRegister();
   1500   VisitForAccumulatorValue(args->at(0));
   1501   builder()->StoreAccumulatorInRegister(first_arg);
   1502 
   1503   // Visit remaining arguments
   1504   for (int i = 1; i < static_cast<int>(args->length()); i++) {
   1505     Register ith_arg = register_allocator()->NextConsecutiveRegister();
   1506     VisitForAccumulatorValue(args->at(i));
   1507     builder()->StoreAccumulatorInRegister(ith_arg);
   1508     DCHECK(ith_arg.index() - i == first_arg.index());
   1509   }
   1510   return first_arg;
   1511 }
   1512 
   1513 
   1514 void BytecodeGenerator::VisitCall(Call* expr) {
   1515   Expression* callee_expr = expr->expression();
   1516   Call::CallType call_type = expr->GetCallType(isolate());
   1517 
   1518   // Prepare the callee and the receiver to the function call. This depends on
   1519   // the semantics of the underlying call type.
   1520 
   1521   // The receiver and arguments need to be allocated consecutively for
   1522   // Call(). We allocate the callee and receiver consecutively for calls to
   1523   // kLoadLookupSlot. Future optimizations could avoid this there are no
   1524   // arguments or the receiver and arguments are already consecutive.
   1525   ZoneList<Expression*>* args = expr->arguments();
   1526   register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2);
   1527   Register callee = register_allocator()->NextConsecutiveRegister();
   1528   Register receiver = register_allocator()->NextConsecutiveRegister();
   1529 
   1530   switch (call_type) {
   1531     case Call::NAMED_PROPERTY_CALL:
   1532     case Call::KEYED_PROPERTY_CALL: {
   1533       Property* property = callee_expr->AsProperty();
   1534       VisitForAccumulatorValue(property->obj());
   1535       builder()->StoreAccumulatorInRegister(receiver);
   1536       VisitPropertyLoadForAccumulator(receiver, property);
   1537       builder()->StoreAccumulatorInRegister(callee);
   1538       break;
   1539     }
   1540     case Call::GLOBAL_CALL: {
   1541       // Receiver is undefined for global calls.
   1542       builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
   1543       // Load callee as a global variable.
   1544       VariableProxy* proxy = callee_expr->AsVariableProxy();
   1545       VisitVariableLoadForAccumulatorValue(proxy->var(),
   1546                                            proxy->VariableFeedbackSlot());
   1547       builder()->StoreAccumulatorInRegister(callee);
   1548       break;
   1549     }
   1550     case Call::LOOKUP_SLOT_CALL:
   1551     case Call::POSSIBLY_EVAL_CALL: {
   1552       if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) {
   1553         RegisterAllocationScope inner_register_scope(this);
   1554         register_allocator()->PrepareForConsecutiveAllocations(2);
   1555         Register context = register_allocator()->NextConsecutiveRegister();
   1556         Register name = register_allocator()->NextConsecutiveRegister();
   1557 
   1558         // Call LoadLookupSlot to get the callee and receiver.
   1559         DCHECK(Register::AreContiguous(callee, receiver));
   1560         Variable* variable = callee_expr->AsVariableProxy()->var();
   1561         builder()
   1562             ->MoveRegister(Register::function_context(), context)
   1563             .LoadLiteral(variable->name())
   1564             .StoreAccumulatorInRegister(name)
   1565             .CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee);
   1566         break;
   1567       }
   1568       // Fall through.
   1569       DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL);
   1570     }
   1571     case Call::OTHER_CALL: {
   1572       builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
   1573       VisitForAccumulatorValue(callee_expr);
   1574       builder()->StoreAccumulatorInRegister(callee);
   1575       break;
   1576     }
   1577     case Call::NAMED_SUPER_PROPERTY_CALL:
   1578     case Call::KEYED_SUPER_PROPERTY_CALL:
   1579     case Call::SUPER_CALL:
   1580       UNIMPLEMENTED();
   1581   }
   1582 
   1583   // Evaluate all arguments to the function call and store in sequential
   1584   // registers.
   1585   Register arg = VisitArguments(args);
   1586   CHECK(args->length() == 0 || arg.index() == receiver.index() + 1);
   1587 
   1588   // Resolve callee for a potential direct eval call. This block will mutate the
   1589   // callee value.
   1590   if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) {
   1591     RegisterAllocationScope inner_register_scope(this);
   1592     register_allocator()->PrepareForConsecutiveAllocations(5);
   1593     Register callee_for_eval = register_allocator()->NextConsecutiveRegister();
   1594     Register source = register_allocator()->NextConsecutiveRegister();
   1595     Register function = register_allocator()->NextConsecutiveRegister();
   1596     Register language = register_allocator()->NextConsecutiveRegister();
   1597     Register position = register_allocator()->NextConsecutiveRegister();
   1598 
   1599     // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
   1600     // strings and function closure, and loading language and
   1601     // position.
   1602     builder()
   1603         ->MoveRegister(callee, callee_for_eval)
   1604         .MoveRegister(arg, source)
   1605         .MoveRegister(Register::function_closure(), function)
   1606         .LoadLiteral(Smi::FromInt(language_mode()))
   1607         .StoreAccumulatorInRegister(language)
   1608         .LoadLiteral(
   1609             Smi::FromInt(execution_context()->scope()->start_position()))
   1610         .StoreAccumulatorInRegister(position);
   1611 
   1612     // Call ResolvePossiblyDirectEval and modify the callee.
   1613     builder()
   1614         ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5)
   1615         .StoreAccumulatorInRegister(callee);
   1616   }
   1617 
   1618   // TODO(rmcilroy): Use CallIC to allow call type feedback.
   1619   builder()->Call(callee, receiver, args->length(),
   1620                   feedback_index(expr->CallFeedbackICSlot()));
   1621   execution_result()->SetResultInAccumulator();
   1622 }
   1623 
   1624 
   1625 void BytecodeGenerator::VisitCallNew(CallNew* expr) {
   1626   Register constructor = register_allocator()->NewRegister();
   1627   VisitForAccumulatorValue(expr->expression());
   1628   builder()->StoreAccumulatorInRegister(constructor);
   1629 
   1630   ZoneList<Expression*>* args = expr->arguments();
   1631   Register first_arg = VisitArguments(args);
   1632   builder()->New(constructor, first_arg, args->length());
   1633   execution_result()->SetResultInAccumulator();
   1634 }
   1635 
   1636 
   1637 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
   1638   ZoneList<Expression*>* args = expr->arguments();
   1639   Register receiver;
   1640   if (expr->is_jsruntime()) {
   1641     // Allocate a register for the receiver and load it with undefined.
   1642     register_allocator()->PrepareForConsecutiveAllocations(args->length() + 1);
   1643     receiver = register_allocator()->NextConsecutiveRegister();
   1644     builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
   1645   }
   1646   // Evaluate all arguments to the runtime call.
   1647   Register first_arg = VisitArguments(args);
   1648 
   1649   if (expr->is_jsruntime()) {
   1650     DCHECK(args->length() == 0 || first_arg.index() == receiver.index() + 1);
   1651     builder()->CallJSRuntime(expr->context_index(), receiver, args->length());
   1652   } else {
   1653     Runtime::FunctionId function_id = expr->function()->function_id;
   1654     builder()->CallRuntime(function_id, first_arg, args->length());
   1655   }
   1656   execution_result()->SetResultInAccumulator();
   1657 }
   1658 
   1659 
   1660 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
   1661   VisitForEffect(expr->expression());
   1662   builder()->LoadUndefined();
   1663   execution_result()->SetResultInAccumulator();
   1664 }
   1665 
   1666 
   1667 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
   1668   if (expr->expression()->IsVariableProxy()) {
   1669     // Typeof does not throw a reference error on global variables, hence we
   1670     // perform a non-contextual load in case the operand is a variable proxy.
   1671     VariableProxy* proxy = expr->expression()->AsVariableProxy();
   1672     VisitVariableLoadForAccumulatorValue(
   1673         proxy->var(), proxy->VariableFeedbackSlot(), INSIDE_TYPEOF);
   1674   } else {
   1675     VisitForAccumulatorValue(expr->expression());
   1676   }
   1677   builder()->TypeOf();
   1678   execution_result()->SetResultInAccumulator();
   1679 }
   1680 
   1681 
   1682 void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
   1683   VisitForAccumulatorValue(expr->expression());
   1684   builder()->LogicalNot();
   1685   execution_result()->SetResultInAccumulator();
   1686 }
   1687 
   1688 
   1689 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
   1690   switch (expr->op()) {
   1691     case Token::Value::NOT:
   1692       VisitNot(expr);
   1693       break;
   1694     case Token::Value::TYPEOF:
   1695       VisitTypeOf(expr);
   1696       break;
   1697     case Token::Value::VOID:
   1698       VisitVoid(expr);
   1699       break;
   1700     case Token::Value::DELETE:
   1701       VisitDelete(expr);
   1702       break;
   1703     case Token::Value::BIT_NOT:
   1704     case Token::Value::ADD:
   1705     case Token::Value::SUB:
   1706       // These operators are converted to an equivalent binary operators in
   1707       // the parser. These operators are not expected to be visited here.
   1708       UNREACHABLE();
   1709     default:
   1710       UNREACHABLE();
   1711   }
   1712 }
   1713 
   1714 
   1715 void BytecodeGenerator::VisitDelete(UnaryOperation* expr) {
   1716   if (expr->expression()->IsProperty()) {
   1717     // Delete of an object property is allowed both in sloppy
   1718     // and strict modes.
   1719     Property* property = expr->expression()->AsProperty();
   1720     Register object = VisitForRegisterValue(property->obj());
   1721     VisitForAccumulatorValue(property->key());
   1722     builder()->Delete(object, language_mode());
   1723   } else if (expr->expression()->IsVariableProxy()) {
   1724     // Delete of an unqualified identifier is allowed in sloppy mode but is
   1725     // not allowed in strict mode. Deleting 'this' is allowed in both modes.
   1726     VariableProxy* proxy = expr->expression()->AsVariableProxy();
   1727     Variable* variable = proxy->var();
   1728     DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate()));
   1729     switch (variable->location()) {
   1730       case VariableLocation::GLOBAL:
   1731       case VariableLocation::UNALLOCATED: {
   1732         // Global var, let, const or variables not explicitly declared.
   1733         Register native_context = register_allocator()->NewRegister();
   1734         Register global_object = register_allocator()->NewRegister();
   1735         builder()
   1736             ->LoadContextSlot(execution_context()->reg(),
   1737                               Context::NATIVE_CONTEXT_INDEX)
   1738             .StoreAccumulatorInRegister(native_context)
   1739             .LoadContextSlot(native_context, Context::EXTENSION_INDEX)
   1740             .StoreAccumulatorInRegister(global_object)
   1741             .LoadLiteral(variable->name())
   1742             .Delete(global_object, language_mode());
   1743         break;
   1744       }
   1745       case VariableLocation::PARAMETER:
   1746       case VariableLocation::LOCAL:
   1747       case VariableLocation::CONTEXT: {
   1748         // Deleting local var/let/const, context variables, and arguments
   1749         // does not have any effect.
   1750         if (variable->HasThisName(isolate())) {
   1751           builder()->LoadTrue();
   1752         } else {
   1753           builder()->LoadFalse();
   1754         }
   1755         break;
   1756       }
   1757       case VariableLocation::LOOKUP: {
   1758         builder()->LoadLiteral(variable->name()).DeleteLookupSlot();
   1759         break;
   1760       }
   1761       default:
   1762         UNREACHABLE();
   1763     }
   1764   } else {
   1765     // Delete of an unresolvable reference returns true.
   1766     VisitForEffect(expr->expression());
   1767     builder()->LoadTrue();
   1768   }
   1769   execution_result()->SetResultInAccumulator();
   1770 }
   1771 
   1772 
   1773 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
   1774   DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
   1775 
   1776   // Left-hand side can only be a property, a global or a variable slot.
   1777   Property* property = expr->expression()->AsProperty();
   1778   LhsKind assign_type = Property::GetAssignType(property);
   1779 
   1780   // TODO(rmcilroy): Set is_postfix to false if visiting for effect.
   1781   bool is_postfix = expr->is_postfix();
   1782 
   1783   // Evaluate LHS expression and get old value.
   1784   Register obj, key, old_value;
   1785   Handle<String> name;
   1786   switch (assign_type) {
   1787     case VARIABLE: {
   1788       VariableProxy* proxy = expr->expression()->AsVariableProxy();
   1789       VisitVariableLoadForAccumulatorValue(proxy->var(),
   1790                                            proxy->VariableFeedbackSlot());
   1791       break;
   1792     }
   1793     case NAMED_PROPERTY: {
   1794       FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   1795       obj = VisitForRegisterValue(property->obj());
   1796       name = property->key()->AsLiteral()->AsPropertyName();
   1797       builder()->LoadNamedProperty(obj, name, feedback_index(slot),
   1798                                    language_mode());
   1799       break;
   1800     }
   1801     case KEYED_PROPERTY: {
   1802       FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
   1803       obj = VisitForRegisterValue(property->obj());
   1804       // Use visit for accumulator here since we need the key in the accumulator
   1805       // for the LoadKeyedProperty.
   1806       key = register_allocator()->NewRegister();
   1807       VisitForAccumulatorValue(property->key());
   1808       builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
   1809           obj, feedback_index(slot), language_mode());
   1810       break;
   1811     }
   1812     case NAMED_SUPER_PROPERTY:
   1813     case KEYED_SUPER_PROPERTY:
   1814       UNIMPLEMENTED();
   1815   }
   1816 
   1817   // Convert old value into a number.
   1818   if (!is_strong(language_mode())) {
   1819     builder()->CastAccumulatorToNumber();
   1820   }
   1821 
   1822   // Save result for postfix expressions.
   1823   if (is_postfix) {
   1824     old_value = register_allocator()->outer()->NewRegister();
   1825     builder()->StoreAccumulatorInRegister(old_value);
   1826   }
   1827 
   1828   // Perform +1/-1 operation.
   1829   builder()->CountOperation(expr->binary_op(), language_mode_strength());
   1830 
   1831   // Store the value.
   1832   FeedbackVectorSlot feedback_slot = expr->CountSlot();
   1833   switch (assign_type) {
   1834     case VARIABLE: {
   1835       Variable* variable = expr->expression()->AsVariableProxy()->var();
   1836       VisitVariableAssignment(variable, feedback_slot);
   1837       break;
   1838     }
   1839     case NAMED_PROPERTY: {
   1840       builder()->StoreNamedProperty(obj, name, feedback_index(feedback_slot),
   1841                                     language_mode());
   1842       break;
   1843     }
   1844     case KEYED_PROPERTY: {
   1845       builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot),
   1846                                     language_mode());
   1847       break;
   1848     }
   1849     case NAMED_SUPER_PROPERTY:
   1850     case KEYED_SUPER_PROPERTY:
   1851       UNIMPLEMENTED();
   1852   }
   1853 
   1854   // Restore old value for postfix expressions.
   1855   if (is_postfix) {
   1856     execution_result()->SetResultInRegister(old_value);
   1857   } else {
   1858     execution_result()->SetResultInAccumulator();
   1859   }
   1860 }
   1861 
   1862 
   1863 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) {
   1864   switch (binop->op()) {
   1865     case Token::COMMA:
   1866       VisitCommaExpression(binop);
   1867       break;
   1868     case Token::OR:
   1869       VisitLogicalOrExpression(binop);
   1870       break;
   1871     case Token::AND:
   1872       VisitLogicalAndExpression(binop);
   1873       break;
   1874     default:
   1875       VisitArithmeticExpression(binop);
   1876       break;
   1877   }
   1878 }
   1879 
   1880 
   1881 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
   1882   Register lhs = VisitForRegisterValue(expr->left());
   1883   VisitForAccumulatorValue(expr->right());
   1884   builder()->CompareOperation(expr->op(), lhs, language_mode_strength());
   1885   execution_result()->SetResultInAccumulator();
   1886 }
   1887 
   1888 
   1889 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
   1890   Register lhs = VisitForRegisterValue(expr->left());
   1891   VisitForAccumulatorValue(expr->right());
   1892   builder()->BinaryOperation(expr->op(), lhs, language_mode_strength());
   1893   execution_result()->SetResultInAccumulator();
   1894 }
   1895 
   1896 
   1897 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
   1898 
   1899 
   1900 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
   1901   UNREACHABLE();
   1902 }
   1903 
   1904 
   1905 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
   1906   execution_result()->SetResultInRegister(Register::function_closure());
   1907 }
   1908 
   1909 
   1910 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
   1911   UNIMPLEMENTED();
   1912 }
   1913 
   1914 
   1915 void BytecodeGenerator::VisitSuperPropertyReference(
   1916     SuperPropertyReference* expr) {
   1917   UNIMPLEMENTED();
   1918 }
   1919 
   1920 
   1921 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
   1922   VisitForEffect(binop->left());
   1923   Visit(binop->right());
   1924 }
   1925 
   1926 
   1927 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
   1928   Expression* left = binop->left();
   1929   Expression* right = binop->right();
   1930 
   1931   // Short-circuit evaluation- If it is known that left is always true,
   1932   // no need to visit right
   1933   if (left->ToBooleanIsTrue()) {
   1934     VisitForAccumulatorValue(left);
   1935   } else {
   1936     BytecodeLabel end_label;
   1937     VisitForAccumulatorValue(left);
   1938     builder()->JumpIfTrue(&end_label);
   1939     VisitForAccumulatorValue(right);
   1940     builder()->Bind(&end_label);
   1941   }
   1942   execution_result()->SetResultInAccumulator();
   1943 }
   1944 
   1945 
   1946 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
   1947   Expression* left = binop->left();
   1948   Expression* right = binop->right();
   1949 
   1950   // Short-circuit evaluation- If it is known that left is always false,
   1951   // no need to visit right
   1952   if (left->ToBooleanIsFalse()) {
   1953     VisitForAccumulatorValue(left);
   1954   } else {
   1955     BytecodeLabel end_label;
   1956     VisitForAccumulatorValue(left);
   1957     builder()->JumpIfFalse(&end_label);
   1958     VisitForAccumulatorValue(right);
   1959     builder()->Bind(&end_label);
   1960   }
   1961   execution_result()->SetResultInAccumulator();
   1962 }
   1963 
   1964 
   1965 void BytecodeGenerator::VisitRewritableAssignmentExpression(
   1966     RewritableAssignmentExpression* expr) {
   1967   Visit(expr->expression());
   1968 }
   1969 
   1970 
   1971 void BytecodeGenerator::VisitNewLocalFunctionContext() {
   1972   AccumulatorResultScope accumulator_execution_result(this);
   1973   Scope* scope = this->scope();
   1974 
   1975   // Allocate a new local context.
   1976   if (scope->is_script_scope()) {
   1977     RegisterAllocationScope register_scope(this);
   1978     Register closure = register_allocator()->NewRegister();
   1979     Register scope_info = register_allocator()->NewRegister();
   1980     DCHECK(Register::AreContiguous(closure, scope_info));
   1981     builder()
   1982         ->LoadAccumulatorWithRegister(Register::function_closure())
   1983         .StoreAccumulatorInRegister(closure)
   1984         .LoadLiteral(scope->GetScopeInfo(isolate()))
   1985         .StoreAccumulatorInRegister(scope_info)
   1986         .CallRuntime(Runtime::kNewScriptContext, closure, 2);
   1987   } else {
   1988     builder()->CallRuntime(Runtime::kNewFunctionContext,
   1989                            Register::function_closure(), 1);
   1990   }
   1991   execution_result()->SetResultInAccumulator();
   1992 }
   1993 
   1994 
   1995 void BytecodeGenerator::VisitBuildLocalActivationContext() {
   1996   Scope* scope = this->scope();
   1997 
   1998   if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
   1999     Variable* variable = scope->receiver();
   2000     Register receiver(builder()->Parameter(0));
   2001     // Context variable (at bottom of the context chain).
   2002     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   2003     builder()->LoadAccumulatorWithRegister(receiver).StoreContextSlot(
   2004         execution_context()->reg(), variable->index());
   2005   }
   2006 
   2007   // Copy parameters into context if necessary.
   2008   int num_parameters = scope->num_parameters();
   2009   for (int i = 0; i < num_parameters; i++) {
   2010     Variable* variable = scope->parameter(i);
   2011     if (!variable->IsContextSlot()) continue;
   2012 
   2013     // The parameter indices are shifted by 1 (receiver is variable
   2014     // index -1 but is parameter index 0 in BytecodeArrayBuilder).
   2015     Register parameter(builder()->Parameter(i + 1));
   2016     // Context variable (at bottom of the context chain).
   2017     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   2018     builder()->LoadAccumulatorWithRegister(parameter)
   2019         .StoreContextSlot(execution_context()->reg(), variable->index());
   2020   }
   2021 }
   2022 
   2023 
   2024 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
   2025   AccumulatorResultScope accumulator_execution_result(this);
   2026   DCHECK(scope->is_block_scope());
   2027 
   2028   // Allocate a new local block context.
   2029   register_allocator()->PrepareForConsecutiveAllocations(2);
   2030   Register scope_info = register_allocator()->NextConsecutiveRegister();
   2031   Register closure = register_allocator()->NextConsecutiveRegister();
   2032 
   2033   builder()
   2034       ->LoadLiteral(scope->GetScopeInfo(isolate()))
   2035       .StoreAccumulatorInRegister(scope_info);
   2036   VisitFunctionClosureForContext();
   2037   builder()
   2038       ->StoreAccumulatorInRegister(closure)
   2039       .CallRuntime(Runtime::kPushBlockContext, scope_info, 2);
   2040   execution_result()->SetResultInAccumulator();
   2041 }
   2042 
   2043 
   2044 void BytecodeGenerator::VisitObjectLiteralAccessor(
   2045     Register home_object, ObjectLiteralProperty* property, Register value_out) {
   2046   // TODO(rmcilroy): Replace value_out with VisitForRegister();
   2047   if (property == nullptr) {
   2048     builder()->LoadNull().StoreAccumulatorInRegister(value_out);
   2049   } else {
   2050     VisitForAccumulatorValue(property->value());
   2051     builder()->StoreAccumulatorInRegister(value_out);
   2052     VisitSetHomeObject(value_out, home_object, property);
   2053   }
   2054 }
   2055 
   2056 
   2057 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
   2058                                            ObjectLiteralProperty* property,
   2059                                            int slot_number) {
   2060   Expression* expr = property->value();
   2061   if (!FunctionLiteral::NeedsHomeObject(expr)) return;
   2062 
   2063   UNIMPLEMENTED();
   2064 }
   2065 
   2066 
   2067 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) {
   2068   if (variable == nullptr) return;
   2069 
   2070   DCHECK(variable->IsContextSlot() || variable->IsStackAllocated());
   2071 
   2072   // Allocate and initialize a new arguments object and assign to the
   2073   // {arguments} variable.
   2074   CreateArgumentsType type =
   2075       is_strict(language_mode()) || !info()->has_simple_parameters()
   2076           ? CreateArgumentsType::kUnmappedArguments
   2077           : CreateArgumentsType::kMappedArguments;
   2078   builder()->CreateArguments(type);
   2079   VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid());
   2080 }
   2081 
   2082 
   2083 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) {
   2084   if (variable == nullptr) return;
   2085 
   2086   // TODO(rmcilroy): Remove once we have tests which exercise this code path.
   2087   UNIMPLEMENTED();
   2088 
   2089   // Store the closure we were called with in the given variable.
   2090   builder()->LoadAccumulatorWithRegister(Register::function_closure());
   2091   VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid());
   2092 }
   2093 
   2094 
   2095 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) {
   2096   if (variable == nullptr) return;
   2097 
   2098   // Store the new target we were called with in the given variable.
   2099   builder()->LoadAccumulatorWithRegister(Register::new_target());
   2100   VisitVariableAssignment(variable, FeedbackVectorSlot::Invalid());
   2101 }
   2102 
   2103 
   2104 void BytecodeGenerator::VisitFunctionClosureForContext() {
   2105   AccumulatorResultScope accumulator_execution_result(this);
   2106   Scope* closure_scope = execution_context()->scope()->ClosureScope();
   2107   if (closure_scope->is_script_scope() ||
   2108       closure_scope->is_module_scope()) {
   2109     // Contexts nested in the native context have a canonical empty function as
   2110     // their closure, not the anonymous closure containing the global code.
   2111     Register native_context = register_allocator()->NewRegister();
   2112     builder()
   2113         ->LoadContextSlot(execution_context()->reg(),
   2114                           Context::NATIVE_CONTEXT_INDEX)
   2115         .StoreAccumulatorInRegister(native_context)
   2116         .LoadContextSlot(native_context, Context::CLOSURE_INDEX);
   2117   } else {
   2118     DCHECK(closure_scope->is_function_scope());
   2119     builder()->LoadAccumulatorWithRegister(Register::function_closure());
   2120   }
   2121   execution_result()->SetResultInAccumulator();
   2122 }
   2123 
   2124 
   2125 // Visits the expression |expr| and places the result in the accumulator.
   2126 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
   2127   AccumulatorResultScope accumulator_scope(this);
   2128   Visit(expr);
   2129 }
   2130 
   2131 
   2132 // Visits the expression |expr| and discards the result.
   2133 void BytecodeGenerator::VisitForEffect(Expression* expr) {
   2134   EffectResultScope effect_scope(this);
   2135   Visit(expr);
   2136 }
   2137 
   2138 
   2139 // Visits the expression |expr| and returns the register containing
   2140 // the expression result.
   2141 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
   2142   RegisterResultScope register_scope(this);
   2143   Visit(expr);
   2144   return register_scope.ResultRegister();
   2145 }
   2146 
   2147 
   2148 Register BytecodeGenerator::NextContextRegister() const {
   2149   if (execution_context() == nullptr) {
   2150     // Return the incoming function context for the outermost execution context.
   2151     return Register::function_context();
   2152   }
   2153   Register previous = execution_context()->reg();
   2154   if (previous == Register::function_context()) {
   2155     // If the previous context was the incoming function context, then the next
   2156     // context register is the first local context register.
   2157     return builder_.first_context_register();
   2158   } else {
   2159     // Otherwise use the next local context register.
   2160     DCHECK_LT(previous.index(), builder_.last_context_register().index());
   2161     return Register(previous.index() + 1);
   2162   }
   2163 }
   2164 
   2165 
   2166 LanguageMode BytecodeGenerator::language_mode() const {
   2167   return info()->language_mode();
   2168 }
   2169 
   2170 
   2171 Strength BytecodeGenerator::language_mode_strength() const {
   2172   return strength(language_mode());
   2173 }
   2174 
   2175 
   2176 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
   2177   return info()->feedback_vector()->GetIndex(slot);
   2178 }
   2179 
   2180 }  // namespace interpreter
   2181 }  // namespace internal
   2182 }  // namespace v8
   2183