Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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/compiler/ast-graph-builder.h"
      6 
      7 #include "src/ast/scopes.h"
      8 #include "src/compiler.h"
      9 #include "src/compiler/ast-loop-assignment-analyzer.h"
     10 #include "src/compiler/control-builders.h"
     11 #include "src/compiler/linkage.h"
     12 #include "src/compiler/liveness-analyzer.h"
     13 #include "src/compiler/machine-operator.h"
     14 #include "src/compiler/node-matchers.h"
     15 #include "src/compiler/node-properties.h"
     16 #include "src/compiler/operator-properties.h"
     17 #include "src/compiler/state-values-utils.h"
     18 #include "src/compiler/type-hint-analyzer.h"
     19 #include "src/parsing/parser.h"
     20 
     21 namespace v8 {
     22 namespace internal {
     23 namespace compiler {
     24 
     25 
     26 // Each expression in the AST is evaluated in a specific context. This context
     27 // decides how the evaluation result is passed up the visitor.
     28 class AstGraphBuilder::AstContext BASE_EMBEDDED {
     29  public:
     30   bool IsEffect() const { return kind_ == Expression::kEffect; }
     31   bool IsValue() const { return kind_ == Expression::kValue; }
     32   bool IsTest() const { return kind_ == Expression::kTest; }
     33 
     34   // Determines how to combine the frame state with the value
     35   // that is about to be plugged into this AstContext.
     36   OutputFrameStateCombine GetStateCombine() {
     37     return IsEffect() ? OutputFrameStateCombine::Ignore()
     38                       : OutputFrameStateCombine::Push();
     39   }
     40 
     41   // Plug a node into this expression context.  Call this function in tail
     42   // position in the Visit functions for expressions.
     43   virtual void ProduceValue(Node* value) = 0;
     44 
     45   // Unplugs a node from this expression context.  Call this to retrieve the
     46   // result of another Visit function that already plugged the context.
     47   virtual Node* ConsumeValue() = 0;
     48 
     49   // Shortcut for "context->ProduceValue(context->ConsumeValue())".
     50   void ReplaceValue() { ProduceValue(ConsumeValue()); }
     51 
     52  protected:
     53   AstContext(AstGraphBuilder* owner, Expression::Context kind);
     54   virtual ~AstContext();
     55 
     56   AstGraphBuilder* owner() const { return owner_; }
     57   Environment* environment() const { return owner_->environment(); }
     58 
     59 // We want to be able to assert, in a context-specific way, that the stack
     60 // height makes sense when the context is filled.
     61 #ifdef DEBUG
     62   int original_height_;
     63 #endif
     64 
     65  private:
     66   Expression::Context kind_;
     67   AstGraphBuilder* owner_;
     68   AstContext* outer_;
     69 };
     70 
     71 
     72 // Context to evaluate expression for its side effects only.
     73 class AstGraphBuilder::AstEffectContext final : public AstContext {
     74  public:
     75   explicit AstEffectContext(AstGraphBuilder* owner)
     76       : AstContext(owner, Expression::kEffect) {}
     77   ~AstEffectContext() final;
     78   void ProduceValue(Node* value) final;
     79   Node* ConsumeValue() final;
     80 };
     81 
     82 
     83 // Context to evaluate expression for its value (and side effects).
     84 class AstGraphBuilder::AstValueContext final : public AstContext {
     85  public:
     86   explicit AstValueContext(AstGraphBuilder* owner)
     87       : AstContext(owner, Expression::kValue) {}
     88   ~AstValueContext() final;
     89   void ProduceValue(Node* value) final;
     90   Node* ConsumeValue() final;
     91 };
     92 
     93 
     94 // Context to evaluate expression for a condition value (and side effects).
     95 class AstGraphBuilder::AstTestContext final : public AstContext {
     96  public:
     97   AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id)
     98       : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {}
     99   ~AstTestContext() final;
    100   void ProduceValue(Node* value) final;
    101   Node* ConsumeValue() final;
    102 
    103  private:
    104   TypeFeedbackId const feedback_id_;
    105 };
    106 
    107 
    108 // Scoped class tracking context objects created by the visitor. Represents
    109 // mutations of the context chain within the function body and allows to
    110 // change the current {scope} and {context} during visitation.
    111 class AstGraphBuilder::ContextScope BASE_EMBEDDED {
    112  public:
    113   ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context)
    114       : builder_(builder),
    115         outer_(builder->execution_context()),
    116         scope_(scope),
    117         depth_(builder_->environment()->context_chain_length()) {
    118     builder_->environment()->PushContext(context);  // Push.
    119     builder_->set_execution_context(this);
    120   }
    121 
    122   ~ContextScope() {
    123     builder_->set_execution_context(outer_);  // Pop.
    124     builder_->environment()->PopContext();
    125     CHECK_EQ(depth_, builder_->environment()->context_chain_length());
    126   }
    127 
    128   // Current scope during visitation.
    129   Scope* scope() const { return scope_; }
    130 
    131  private:
    132   AstGraphBuilder* builder_;
    133   ContextScope* outer_;
    134   Scope* scope_;
    135   int depth_;
    136 };
    137 
    138 
    139 // Scoped class tracking control statements entered by the visitor. There are
    140 // different types of statements participating in this stack to properly track
    141 // local as well as non-local control flow:
    142 //  - IterationStatement : Allows proper 'break' and 'continue' behavior.
    143 //  - BreakableStatement : Allows 'break' from block and switch statements.
    144 //  - TryCatchStatement  : Intercepts 'throw' and implicit exceptional edges.
    145 //  - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'.
    146 class AstGraphBuilder::ControlScope BASE_EMBEDDED {
    147  public:
    148   explicit ControlScope(AstGraphBuilder* builder)
    149       : builder_(builder),
    150         outer_(builder->execution_control()),
    151         context_length_(builder->environment()->context_chain_length()),
    152         stack_height_(builder->environment()->stack_height()) {
    153     builder_->set_execution_control(this);  // Push.
    154   }
    155 
    156   virtual ~ControlScope() {
    157     builder_->set_execution_control(outer_);  // Pop.
    158   }
    159 
    160   // Either 'break' or 'continue' to the target statement.
    161   void BreakTo(BreakableStatement* target);
    162   void ContinueTo(BreakableStatement* target);
    163 
    164   // Either 'return' or 'throw' the given value.
    165   void ReturnValue(Node* return_value);
    166   void ThrowValue(Node* exception_value);
    167 
    168   class DeferredCommands;
    169 
    170  protected:
    171   enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW };
    172 
    173   // Performs one of the above commands on this stack of control scopes. This
    174   // walks through the stack giving each scope a chance to execute or defer the
    175   // given command by overriding the {Execute} method appropriately. Note that
    176   // this also drops extra operands from the environment for each skipped scope.
    177   void PerformCommand(Command cmd, Statement* target, Node* value);
    178 
    179   // Interface to execute a given command in this scope. Returning {true} here
    180   // indicates successful execution whereas {false} requests to skip scope.
    181   virtual bool Execute(Command cmd, Statement* target, Node* value) {
    182     // For function-level control.
    183     switch (cmd) {
    184       case CMD_THROW:
    185         builder()->BuildThrow(value);
    186         return true;
    187       case CMD_RETURN:
    188         builder()->BuildReturn(value);
    189         return true;
    190       case CMD_BREAK:
    191       case CMD_CONTINUE:
    192         break;
    193     }
    194     return false;
    195   }
    196 
    197   Environment* environment() { return builder_->environment(); }
    198   AstGraphBuilder* builder() const { return builder_; }
    199   int context_length() const { return context_length_; }
    200   int stack_height() const { return stack_height_; }
    201 
    202  private:
    203   AstGraphBuilder* builder_;
    204   ControlScope* outer_;
    205   int context_length_;
    206   int stack_height_;
    207 };
    208 
    209 
    210 // Helper class for a try-finally control scope. It can record intercepted
    211 // control-flow commands that cause entry into a finally-block, and re-apply
    212 // them after again leaving that block. Special tokens are used to identify
    213 // paths going through the finally-block to dispatch after leaving the block.
    214 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
    215  public:
    216   explicit DeferredCommands(AstGraphBuilder* owner)
    217       : owner_(owner), deferred_(owner->local_zone()) {}
    218 
    219   // One recorded control-flow command.
    220   struct Entry {
    221     Command command;       // The command type being applied on this path.
    222     Statement* statement;  // The target statement for the command or {nullptr}.
    223     Node* token;           // A token identifying this particular path.
    224   };
    225 
    226   // Records a control-flow command while entering the finally-block. This also
    227   // generates a new dispatch token that identifies one particular path.
    228   Node* RecordCommand(Command cmd, Statement* stmt, Node* value) {
    229     Node* token = NewPathTokenForDeferredCommand();
    230     deferred_.push_back({cmd, stmt, token});
    231     return token;
    232   }
    233 
    234   // Returns the dispatch token to be used to identify the implicit fall-through
    235   // path at the end of a try-block into the corresponding finally-block.
    236   Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); }
    237 
    238   // Applies all recorded control-flow commands after the finally-block again.
    239   // This generates a dynamic dispatch on the token from the entry point.
    240   void ApplyDeferredCommands(Node* token, Node* value) {
    241     SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size()));
    242     dispatch.BeginSwitch();
    243     for (size_t i = 0; i < deferred_.size(); ++i) {
    244       Node* condition = NewPathDispatchCondition(token, deferred_[i].token);
    245       dispatch.BeginLabel(static_cast<int>(i), condition);
    246       dispatch.EndLabel();
    247     }
    248     for (size_t i = 0; i < deferred_.size(); ++i) {
    249       dispatch.BeginCase(static_cast<int>(i));
    250       owner_->execution_control()->PerformCommand(
    251           deferred_[i].command, deferred_[i].statement, value);
    252       dispatch.EndCase();
    253     }
    254     dispatch.EndSwitch();
    255   }
    256 
    257  protected:
    258   Node* NewPathTokenForDeferredCommand() {
    259     return owner_->jsgraph()->Constant(static_cast<int>(deferred_.size()));
    260   }
    261   Node* NewPathTokenForImplicitFallThrough() {
    262     return owner_->jsgraph()->Constant(-1);
    263   }
    264   Node* NewPathDispatchCondition(Node* t1, Node* t2) {
    265     // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi
    266     // nodes all have kRepTagged|kTypeAny, which causes representation mismatch.
    267     return owner_->NewNode(owner_->javascript()->StrictEqual(), t1, t2);
    268   }
    269 
    270  private:
    271   AstGraphBuilder* owner_;
    272   ZoneVector<Entry> deferred_;
    273 };
    274 
    275 
    276 // Control scope implementation for a BreakableStatement.
    277 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope {
    278  public:
    279   ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target,
    280                            ControlBuilder* control)
    281       : ControlScope(owner), target_(target), control_(control) {}
    282 
    283  protected:
    284   bool Execute(Command cmd, Statement* target, Node* value) override {
    285     if (target != target_) return false;  // We are not the command target.
    286     switch (cmd) {
    287       case CMD_BREAK:
    288         control_->Break();
    289         return true;
    290       case CMD_CONTINUE:
    291       case CMD_THROW:
    292       case CMD_RETURN:
    293         break;
    294     }
    295     return false;
    296   }
    297 
    298  private:
    299   BreakableStatement* target_;
    300   ControlBuilder* control_;
    301 };
    302 
    303 
    304 // Control scope implementation for an IterationStatement.
    305 class AstGraphBuilder::ControlScopeForIteration : public ControlScope {
    306  public:
    307   ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target,
    308                            LoopBuilder* control)
    309       : ControlScope(owner), target_(target), control_(control) {}
    310 
    311  protected:
    312   bool Execute(Command cmd, Statement* target, Node* value) override {
    313     if (target != target_) return false;  // We are not the command target.
    314     switch (cmd) {
    315       case CMD_BREAK:
    316         control_->Break();
    317         return true;
    318       case CMD_CONTINUE:
    319         control_->Continue();
    320         return true;
    321       case CMD_THROW:
    322       case CMD_RETURN:
    323         break;
    324     }
    325     return false;
    326   }
    327 
    328  private:
    329   BreakableStatement* target_;
    330   LoopBuilder* control_;
    331 };
    332 
    333 
    334 // Control scope implementation for a TryCatchStatement.
    335 class AstGraphBuilder::ControlScopeForCatch : public ControlScope {
    336  public:
    337   ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control)
    338       : ControlScope(owner), control_(control) {
    339     builder()->try_nesting_level_++;  // Increment nesting.
    340     builder()->try_catch_nesting_level_++;
    341   }
    342   ~ControlScopeForCatch() {
    343     builder()->try_nesting_level_--;  // Decrement nesting.
    344     builder()->try_catch_nesting_level_--;
    345   }
    346 
    347  protected:
    348   bool Execute(Command cmd, Statement* target, Node* value) override {
    349     switch (cmd) {
    350       case CMD_THROW:
    351         control_->Throw(value);
    352         return true;
    353       case CMD_BREAK:
    354       case CMD_CONTINUE:
    355       case CMD_RETURN:
    356         break;
    357     }
    358     return false;
    359   }
    360 
    361  private:
    362   TryCatchBuilder* control_;
    363 };
    364 
    365 
    366 // Control scope implementation for a TryFinallyStatement.
    367 class AstGraphBuilder::ControlScopeForFinally : public ControlScope {
    368  public:
    369   ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands,
    370                          TryFinallyBuilder* control)
    371       : ControlScope(owner), commands_(commands), control_(control) {
    372     builder()->try_nesting_level_++;  // Increment nesting.
    373   }
    374   ~ControlScopeForFinally() {
    375     builder()->try_nesting_level_--;  // Decrement nesting.
    376   }
    377 
    378  protected:
    379   bool Execute(Command cmd, Statement* target, Node* value) override {
    380     Node* token = commands_->RecordCommand(cmd, target, value);
    381     control_->LeaveTry(token, value);
    382     return true;
    383   }
    384 
    385  private:
    386   DeferredCommands* commands_;
    387   TryFinallyBuilder* control_;
    388 };
    389 
    390 
    391 // Helper for generating before and after frame states.
    392 class AstGraphBuilder::FrameStateBeforeAndAfter {
    393  public:
    394   FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before)
    395       : builder_(builder), frame_state_before_(nullptr) {
    396     frame_state_before_ = id_before == BailoutId::None()
    397                               ? builder_->jsgraph()->EmptyFrameState()
    398                               : builder_->environment()->Checkpoint(id_before);
    399   }
    400 
    401   void AddToNode(
    402       Node* node, BailoutId id_after,
    403       OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore()) {
    404     int count = OperatorProperties::GetFrameStateInputCount(node->op());
    405     DCHECK_LE(count, 2);
    406 
    407     if (count >= 1) {
    408       // Add the frame state for after the operation.
    409       DCHECK_EQ(IrOpcode::kDead,
    410                 NodeProperties::GetFrameStateInput(node, 0)->opcode());
    411 
    412       Node* frame_state_after =
    413           id_after == BailoutId::None()
    414               ? builder_->jsgraph()->EmptyFrameState()
    415               : builder_->environment()->Checkpoint(id_after, combine);
    416 
    417       NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
    418     }
    419 
    420     if (count >= 2) {
    421       // Add the frame state for before the operation.
    422       DCHECK_EQ(IrOpcode::kDead,
    423                 NodeProperties::GetFrameStateInput(node, 1)->opcode());
    424       NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
    425     }
    426   }
    427 
    428  private:
    429   AstGraphBuilder* builder_;
    430   Node* frame_state_before_;
    431 };
    432 
    433 
    434 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
    435                                  JSGraph* jsgraph, LoopAssignmentAnalysis* loop,
    436                                  TypeHintAnalysis* type_hint_analysis)
    437     : isolate_(info->isolate()),
    438       local_zone_(local_zone),
    439       info_(info),
    440       jsgraph_(jsgraph),
    441       environment_(nullptr),
    442       ast_context_(nullptr),
    443       globals_(0, local_zone),
    444       execution_control_(nullptr),
    445       execution_context_(nullptr),
    446       try_catch_nesting_level_(0),
    447       try_nesting_level_(0),
    448       input_buffer_size_(0),
    449       input_buffer_(nullptr),
    450       exit_controls_(local_zone),
    451       loop_assignment_analysis_(loop),
    452       type_hint_analysis_(type_hint_analysis),
    453       state_values_cache_(jsgraph),
    454       liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()),
    455                          local_zone),
    456       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
    457           FrameStateType::kJavaScriptFunction, info->num_parameters() + 1,
    458           info->scope()->num_stack_slots(), info->shared_info(),
    459           CALL_MAINTAINS_NATIVE_CONTEXT)) {
    460   InitializeAstVisitor(info->isolate());
    461 }
    462 
    463 
    464 Node* AstGraphBuilder::GetFunctionClosureForContext() {
    465   Scope* closure_scope = current_scope()->ClosureScope();
    466   if (closure_scope->is_script_scope() ||
    467       closure_scope->is_module_scope()) {
    468     // Contexts nested in the native context have a canonical empty function as
    469     // their closure, not the anonymous closure containing the global code.
    470     return BuildLoadNativeContextField(Context::CLOSURE_INDEX);
    471   } else {
    472     DCHECK(closure_scope->is_function_scope());
    473     return GetFunctionClosure();
    474   }
    475 }
    476 
    477 
    478 Node* AstGraphBuilder::GetFunctionClosure() {
    479   if (!function_closure_.is_set()) {
    480     int index = Linkage::kJSCallClosureParamIndex;
    481     const Operator* op = common()->Parameter(index, "%closure");
    482     Node* node = NewNode(op, graph()->start());
    483     function_closure_.set(node);
    484   }
    485   return function_closure_.get();
    486 }
    487 
    488 
    489 Node* AstGraphBuilder::GetFunctionContext() {
    490   if (!function_context_.is_set()) {
    491     int params = info()->num_parameters_including_this();
    492     int index = Linkage::GetJSCallContextParamIndex(params);
    493     const Operator* op = common()->Parameter(index, "%context");
    494     Node* node = NewNode(op, graph()->start());
    495     function_context_.set(node);
    496   }
    497   return function_context_.get();
    498 }
    499 
    500 
    501 Node* AstGraphBuilder::GetNewTarget() {
    502   if (!new_target_.is_set()) {
    503     int params = info()->num_parameters_including_this();
    504     int index = Linkage::GetJSCallNewTargetParamIndex(params);
    505     const Operator* op = common()->Parameter(index, "%new.target");
    506     Node* node = NewNode(op, graph()->start());
    507     new_target_.set(node);
    508   }
    509   return new_target_.get();
    510 }
    511 
    512 
    513 bool AstGraphBuilder::CreateGraph(bool stack_check) {
    514   Scope* scope = info()->scope();
    515   DCHECK_NOT_NULL(graph());
    516 
    517   // Set up the basic structure of the graph. Outputs for {Start} are the formal
    518   // parameters (including the receiver) plus new target, number of arguments,
    519   // context and closure.
    520   int actual_parameter_count = info()->num_parameters_including_this() + 4;
    521   graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
    522 
    523   // Initialize the top-level environment.
    524   Environment env(this, scope, graph()->start());
    525   set_environment(&env);
    526 
    527   if (info()->is_osr()) {
    528     // Use OSR normal entry as the start of the top-level environment.
    529     // It will be replaced with {Dead} after typing and optimizations.
    530     NewNode(common()->OsrNormalEntry());
    531   }
    532 
    533   // Initialize the incoming context.
    534   ContextScope incoming(this, scope, GetFunctionContext());
    535 
    536   // Initialize control scope.
    537   ControlScope control(this);
    538 
    539   // TODO(mstarzinger): For now we cannot assume that the {this} parameter is
    540   // not {the_hole}, because for derived classes {this} has a TDZ and the
    541   // JSConstructStubForDerived magically passes {the_hole} as a receiver.
    542   if (scope->has_this_declaration() && scope->receiver()->is_const_mode()) {
    543     env.RawParameterBind(0, jsgraph()->TheHoleConstant());
    544   }
    545 
    546   // Build local context only if there are context allocated variables.
    547   if (info()->num_heap_slots() > 0) {
    548     // Push a new inner context scope for the current activation.
    549     Node* inner_context = BuildLocalActivationContext(GetFunctionContext());
    550     ContextScope top_context(this, scope, inner_context);
    551     CreateGraphBody(stack_check);
    552   } else {
    553     // Simply use the outer function context in building the graph.
    554     CreateGraphBody(stack_check);
    555   }
    556 
    557   // Finish the basic structure of the graph.
    558   DCHECK_NE(0u, exit_controls_.size());
    559   int const input_count = static_cast<int>(exit_controls_.size());
    560   Node** const inputs = &exit_controls_.front();
    561   Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
    562   graph()->SetEnd(end);
    563 
    564   // Compute local variable liveness information and use it to relax
    565   // frame states.
    566   ClearNonLiveSlotsInFrameStates();
    567 
    568   // Failures indicated by stack overflow.
    569   return !HasStackOverflow();
    570 }
    571 
    572 
    573 void AstGraphBuilder::CreateGraphBody(bool stack_check) {
    574   Scope* scope = info()->scope();
    575 
    576   // Build the arguments object if it is used.
    577   BuildArgumentsObject(scope->arguments());
    578 
    579   // Build rest arguments array if it is used.
    580   int rest_index;
    581   Variable* rest_parameter = scope->rest_parameter(&rest_index);
    582   BuildRestArgumentsArray(rest_parameter, rest_index);
    583 
    584   // Build assignment to {.this_function} variable if it is used.
    585   BuildThisFunctionVariable(scope->this_function_var());
    586 
    587   // Build assignment to {new.target} variable if it is used.
    588   BuildNewTargetVariable(scope->new_target_var());
    589 
    590   // Emit tracing call if requested to do so.
    591   if (FLAG_trace) {
    592     NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0));
    593   }
    594 
    595   // Visit illegal re-declaration and bail out if it exists.
    596   if (scope->HasIllegalRedeclaration()) {
    597     VisitForEffect(scope->GetIllegalRedeclaration());
    598     return;
    599   }
    600 
    601   // Visit declarations within the function scope.
    602   VisitDeclarations(scope->declarations());
    603 
    604   // Build a stack-check before the body.
    605   if (stack_check) {
    606     Node* node = NewNode(javascript()->StackCheck());
    607     PrepareFrameState(node, BailoutId::FunctionEntry());
    608   }
    609 
    610   // Visit statements in the function body.
    611   VisitStatements(info()->literal()->body());
    612 
    613   // Emit tracing call if requested to do so.
    614   if (FLAG_trace) {
    615     // TODO(mstarzinger): Only traces implicit return.
    616     Node* return_value = jsgraph()->UndefinedConstant();
    617     NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
    618   }
    619 
    620   // Return 'undefined' in case we can fall off the end.
    621   BuildReturn(jsgraph()->UndefinedConstant());
    622 }
    623 
    624 
    625 void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
    626   if (!FLAG_analyze_environment_liveness ||
    627       !info()->is_deoptimization_enabled()) {
    628     return;
    629   }
    630 
    631   NonLiveFrameStateSlotReplacer replacer(
    632       &state_values_cache_, jsgraph()->UndefinedConstant(),
    633       liveness_analyzer()->local_count(), local_zone());
    634   Variable* arguments = info()->scope()->arguments();
    635   if (arguments != nullptr && arguments->IsStackAllocated()) {
    636     replacer.MarkPermanentlyLive(arguments->index());
    637   }
    638   liveness_analyzer()->Run(&replacer);
    639   if (FLAG_trace_environment_liveness) {
    640     OFStream os(stdout);
    641     liveness_analyzer()->Print(os);
    642   }
    643 }
    644 
    645 
    646 // Gets the bailout id just before reading a variable proxy, but only for
    647 // unallocated variables.
    648 static BailoutId BeforeId(VariableProxy* proxy) {
    649   return proxy->var()->IsUnallocatedOrGlobalSlot() ? proxy->BeforeId()
    650                                                    : BailoutId::None();
    651 }
    652 
    653 
    654 static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) {
    655 #if DEBUG
    656   const AstRawString* name = scope->parameter(index)->raw_name();
    657   if (name && name->length() > 0) {
    658     char* data = zone->NewArray<char>(name->length() + 1);
    659     data[name->length()] = 0;
    660     memcpy(data, name->raw_data(), name->length());
    661     return data;
    662   }
    663 #endif
    664   return nullptr;
    665 }
    666 
    667 
    668 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
    669                                           Scope* scope,
    670                                           Node* control_dependency)
    671     : builder_(builder),
    672       parameters_count_(scope->num_parameters() + 1),
    673       locals_count_(scope->num_stack_slots()),
    674       liveness_block_(IsLivenessAnalysisEnabled()
    675                           ? builder_->liveness_analyzer()->NewBlock()
    676                           : nullptr),
    677       values_(builder_->local_zone()),
    678       contexts_(builder_->local_zone()),
    679       control_dependency_(control_dependency),
    680       effect_dependency_(control_dependency),
    681       parameters_node_(nullptr),
    682       locals_node_(nullptr),
    683       stack_node_(nullptr) {
    684   DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
    685 
    686   // Bind the receiver variable.
    687   int param_num = 0;
    688   if (builder->info()->is_this_defined()) {
    689     const Operator* op = common()->Parameter(param_num++, "%this");
    690     Node* receiver = builder->graph()->NewNode(op, builder->graph()->start());
    691     values()->push_back(receiver);
    692   } else {
    693     values()->push_back(builder->jsgraph()->UndefinedConstant());
    694   }
    695 
    696   // Bind all parameter variables. The parameter indices are shifted by 1
    697   // (receiver is variable index -1 but {Parameter} node index 0 and located at
    698   // index 0 in the environment).
    699   for (int i = 0; i < scope->num_parameters(); ++i) {
    700     const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i);
    701     const Operator* op = common()->Parameter(param_num++, debug_name);
    702     Node* parameter = builder->graph()->NewNode(op, builder->graph()->start());
    703     values()->push_back(parameter);
    704   }
    705 
    706   // Bind all local variables to undefined.
    707   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
    708   values()->insert(values()->end(), locals_count(), undefined_constant);
    709 }
    710 
    711 
    712 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy,
    713                                           LivenessAnalyzerBlock* liveness_block)
    714     : builder_(copy->builder_),
    715       parameters_count_(copy->parameters_count_),
    716       locals_count_(copy->locals_count_),
    717       liveness_block_(liveness_block),
    718       values_(copy->zone()),
    719       contexts_(copy->zone()),
    720       control_dependency_(copy->control_dependency_),
    721       effect_dependency_(copy->effect_dependency_),
    722       parameters_node_(copy->parameters_node_),
    723       locals_node_(copy->locals_node_),
    724       stack_node_(copy->stack_node_) {
    725   const size_t kStackEstimate = 7;  // optimum from experimentation!
    726   values_.reserve(copy->values_.size() + kStackEstimate);
    727   values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end());
    728   contexts_.reserve(copy->contexts_.size());
    729   contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
    730                    copy->contexts_.end());
    731 }
    732 
    733 
    734 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) {
    735   DCHECK(variable->IsStackAllocated());
    736   if (variable->IsParameter()) {
    737     // The parameter indices are shifted by 1 (receiver is variable
    738     // index -1 but located at index 0 in the environment).
    739     values()->at(variable->index() + 1) = node;
    740   } else {
    741     DCHECK(variable->IsStackLocal());
    742     values()->at(variable->index() + parameters_count_) = node;
    743     DCHECK(IsLivenessBlockConsistent());
    744     if (liveness_block() != nullptr) {
    745       liveness_block()->Bind(variable->index());
    746     }
    747   }
    748 }
    749 
    750 
    751 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
    752   DCHECK(variable->IsStackAllocated());
    753   if (variable->IsParameter()) {
    754     // The parameter indices are shifted by 1 (receiver is variable
    755     // index -1 but located at index 0 in the environment).
    756     return values()->at(variable->index() + 1);
    757   } else {
    758     DCHECK(variable->IsStackLocal());
    759     DCHECK(IsLivenessBlockConsistent());
    760     if (liveness_block() != nullptr) {
    761       liveness_block()->Lookup(variable->index());
    762     }
    763     return values()->at(variable->index() + parameters_count_);
    764   }
    765 }
    766 
    767 
    768 void AstGraphBuilder::Environment::MarkAllLocalsLive() {
    769   DCHECK(IsLivenessBlockConsistent());
    770   if (liveness_block() != nullptr) {
    771     for (int i = 0; i < locals_count_; i++) {
    772       liveness_block()->Lookup(i);
    773     }
    774   }
    775 }
    776 
    777 
    778 void AstGraphBuilder::Environment::RawParameterBind(int index, Node* node) {
    779   DCHECK_LT(index, parameters_count());
    780   values()->at(index) = node;
    781 }
    782 
    783 
    784 Node* AstGraphBuilder::Environment::RawParameterLookup(int index) {
    785   DCHECK_LT(index, parameters_count());
    786   return values()->at(index);
    787 }
    788 
    789 
    790 AstGraphBuilder::Environment*
    791 AstGraphBuilder::Environment::CopyForConditional() {
    792   LivenessAnalyzerBlock* copy_liveness_block = nullptr;
    793   if (liveness_block() != nullptr) {
    794     copy_liveness_block =
    795         builder_->liveness_analyzer()->NewBlock(liveness_block());
    796     liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
    797   }
    798   return new (zone()) Environment(this, copy_liveness_block);
    799 }
    800 
    801 
    802 AstGraphBuilder::Environment*
    803 AstGraphBuilder::Environment::CopyAsUnreachable() {
    804   Environment* env = new (zone()) Environment(this, nullptr);
    805   env->MarkAsUnreachable();
    806   return env;
    807 }
    808 
    809 
    810 AstGraphBuilder::Environment*
    811 AstGraphBuilder::Environment::CopyAndShareLiveness() {
    812   if (liveness_block() != nullptr) {
    813     // Finish the current liveness block before copying.
    814     liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
    815   }
    816   Environment* env = new (zone()) Environment(this, liveness_block());
    817   return env;
    818 }
    819 
    820 
    821 AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop(
    822     BitVector* assigned, bool is_osr) {
    823   PrepareForLoop(assigned, is_osr);
    824   return CopyAndShareLiveness();
    825 }
    826 
    827 
    828 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
    829                                                      int offset, int count) {
    830   bool should_update = false;
    831   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
    832   if (*state_values == nullptr || (*state_values)->InputCount() != count) {
    833     should_update = true;
    834   } else {
    835     DCHECK(static_cast<size_t>(offset + count) <= values()->size());
    836     for (int i = 0; i < count; i++) {
    837       if ((*state_values)->InputAt(i) != env_values[i]) {
    838         should_update = true;
    839         break;
    840       }
    841     }
    842   }
    843   if (should_update) {
    844     const Operator* op = common()->StateValues(count);
    845     (*state_values) = graph()->NewNode(op, count, env_values);
    846   }
    847 }
    848 
    849 
    850 void AstGraphBuilder::Environment::UpdateStateValuesWithCache(
    851     Node** state_values, int offset, int count) {
    852   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
    853   *state_values = builder_->state_values_cache_.GetNodeForValues(
    854       env_values, static_cast<size_t>(count));
    855 }
    856 
    857 
    858 Node* AstGraphBuilder::Environment::Checkpoint(
    859     BailoutId ast_id, OutputFrameStateCombine combine) {
    860   if (!builder()->info()->is_deoptimization_enabled()) {
    861     return builder()->jsgraph()->EmptyFrameState();
    862   }
    863 
    864   UpdateStateValues(&parameters_node_, 0, parameters_count());
    865   UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count());
    866   UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
    867                     stack_height());
    868 
    869   const Operator* op = common()->FrameState(
    870       ast_id, combine, builder()->frame_state_function_info());
    871 
    872   Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
    873                                   stack_node_, builder()->current_context(),
    874                                   builder()->GetFunctionClosure(),
    875                                   builder()->graph()->start());
    876 
    877   DCHECK(IsLivenessBlockConsistent());
    878   if (liveness_block() != nullptr) {
    879     liveness_block()->Checkpoint(result);
    880   }
    881   return result;
    882 }
    883 
    884 
    885 bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() {
    886   return FLAG_analyze_environment_liveness &&
    887          builder()->info()->is_deoptimization_enabled();
    888 }
    889 
    890 
    891 bool AstGraphBuilder::Environment::IsLivenessBlockConsistent() {
    892   return (!IsLivenessAnalysisEnabled() || IsMarkedAsUnreachable()) ==
    893          (liveness_block() == nullptr);
    894 }
    895 
    896 
    897 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
    898                                         Expression::Context kind)
    899     : kind_(kind), owner_(own), outer_(own->ast_context()) {
    900   owner()->set_ast_context(this);  // Push.
    901 #ifdef DEBUG
    902   original_height_ = environment()->stack_height();
    903 #endif
    904 }
    905 
    906 
    907 AstGraphBuilder::AstContext::~AstContext() {
    908   owner()->set_ast_context(outer_);  // Pop.
    909 }
    910 
    911 
    912 AstGraphBuilder::AstEffectContext::~AstEffectContext() {
    913   DCHECK(environment()->stack_height() == original_height_);
    914 }
    915 
    916 
    917 AstGraphBuilder::AstValueContext::~AstValueContext() {
    918   DCHECK(environment()->stack_height() == original_height_ + 1);
    919 }
    920 
    921 
    922 AstGraphBuilder::AstTestContext::~AstTestContext() {
    923   DCHECK(environment()->stack_height() == original_height_ + 1);
    924 }
    925 
    926 
    927 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) {
    928   // The value is ignored.
    929 }
    930 
    931 
    932 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) {
    933   environment()->Push(value);
    934 }
    935 
    936 
    937 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) {
    938   environment()->Push(owner()->BuildToBoolean(value, feedback_id_));
    939 }
    940 
    941 
    942 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; }
    943 
    944 
    945 Node* AstGraphBuilder::AstValueContext::ConsumeValue() {
    946   return environment()->Pop();
    947 }
    948 
    949 
    950 Node* AstGraphBuilder::AstTestContext::ConsumeValue() {
    951   return environment()->Pop();
    952 }
    953 
    954 
    955 Scope* AstGraphBuilder::current_scope() const {
    956   return execution_context_->scope();
    957 }
    958 
    959 
    960 Node* AstGraphBuilder::current_context() const {
    961   return environment()->Context();
    962 }
    963 
    964 
    965 void AstGraphBuilder::ControlScope::PerformCommand(Command command,
    966                                                    Statement* target,
    967                                                    Node* value) {
    968   Environment* env = environment()->CopyAsUnreachable();
    969   ControlScope* current = this;
    970   while (current != nullptr) {
    971     environment()->TrimStack(current->stack_height());
    972     environment()->TrimContextChain(current->context_length());
    973     if (current->Execute(command, target, value)) break;
    974     current = current->outer_;
    975   }
    976   builder()->set_environment(env);
    977   DCHECK_NOT_NULL(current);  // Always handled (unless stack is malformed).
    978 }
    979 
    980 
    981 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) {
    982   PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant());
    983 }
    984 
    985 
    986 void AstGraphBuilder::ControlScope::ContinueTo(BreakableStatement* stmt) {
    987   PerformCommand(CMD_CONTINUE, stmt, builder()->jsgraph()->TheHoleConstant());
    988 }
    989 
    990 
    991 void AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) {
    992   PerformCommand(CMD_RETURN, nullptr, return_value);
    993 }
    994 
    995 
    996 void AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) {
    997   PerformCommand(CMD_THROW, nullptr, exception_value);
    998 }
    999 
   1000 
   1001 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) {
   1002   if (expr == nullptr) {
   1003     return environment()->Push(jsgraph()->NullConstant());
   1004   }
   1005   VisitForValue(expr);
   1006 }
   1007 
   1008 
   1009 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) {
   1010   if (expr == nullptr) {
   1011     return environment()->Push(jsgraph()->TheHoleConstant());
   1012   }
   1013   VisitForValue(expr);
   1014 }
   1015 
   1016 
   1017 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
   1018   for (int i = 0; i < exprs->length(); ++i) {
   1019     VisitForValue(exprs->at(i));
   1020   }
   1021 }
   1022 
   1023 
   1024 void AstGraphBuilder::VisitForValue(Expression* expr) {
   1025   AstValueContext for_value(this);
   1026   if (!CheckStackOverflow()) {
   1027     expr->Accept(this);
   1028   } else {
   1029     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   1030   }
   1031 }
   1032 
   1033 
   1034 void AstGraphBuilder::VisitForEffect(Expression* expr) {
   1035   AstEffectContext for_effect(this);
   1036   if (!CheckStackOverflow()) {
   1037     expr->Accept(this);
   1038   } else {
   1039     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   1040   }
   1041 }
   1042 
   1043 
   1044 void AstGraphBuilder::VisitForTest(Expression* expr) {
   1045   AstTestContext for_condition(this, expr->test_id());
   1046   if (!CheckStackOverflow()) {
   1047     expr->Accept(this);
   1048   } else {
   1049     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   1050   }
   1051 }
   1052 
   1053 
   1054 void AstGraphBuilder::Visit(Expression* expr) {
   1055   // Reuses enclosing AstContext.
   1056   if (!CheckStackOverflow()) {
   1057     expr->Accept(this);
   1058   } else {
   1059     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   1060   }
   1061 }
   1062 
   1063 
   1064 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
   1065   Variable* variable = decl->proxy()->var();
   1066   VariableMode mode = decl->mode();
   1067   bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
   1068   switch (variable->location()) {
   1069     case VariableLocation::GLOBAL:
   1070     case VariableLocation::UNALLOCATED: {
   1071       Handle<Oddball> value = variable->binding_needs_init()
   1072                                   ? isolate()->factory()->the_hole_value()
   1073                                   : isolate()->factory()->undefined_value();
   1074       globals()->push_back(variable->name());
   1075       globals()->push_back(value);
   1076       break;
   1077     }
   1078     case VariableLocation::PARAMETER:
   1079     case VariableLocation::LOCAL:
   1080       if (hole_init) {
   1081         Node* value = jsgraph()->TheHoleConstant();
   1082         environment()->Bind(variable, value);
   1083       }
   1084       break;
   1085     case VariableLocation::CONTEXT:
   1086       if (hole_init) {
   1087         Node* value = jsgraph()->TheHoleConstant();
   1088         const Operator* op = javascript()->StoreContext(0, variable->index());
   1089         NewNode(op, current_context(), value);
   1090       }
   1091       break;
   1092     case VariableLocation::LOOKUP:
   1093       UNIMPLEMENTED();
   1094   }
   1095 }
   1096 
   1097 
   1098 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
   1099   Variable* variable = decl->proxy()->var();
   1100   switch (variable->location()) {
   1101     case VariableLocation::GLOBAL:
   1102     case VariableLocation::UNALLOCATED: {
   1103       Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
   1104           decl->fun(), info()->script(), info());
   1105       // Check for stack-overflow exception.
   1106       if (function.is_null()) return SetStackOverflow();
   1107       globals()->push_back(variable->name());
   1108       globals()->push_back(function);
   1109       break;
   1110     }
   1111     case VariableLocation::PARAMETER:
   1112     case VariableLocation::LOCAL: {
   1113       VisitForValue(decl->fun());
   1114       Node* value = environment()->Pop();
   1115       environment()->Bind(variable, value);
   1116       break;
   1117     }
   1118     case VariableLocation::CONTEXT: {
   1119       VisitForValue(decl->fun());
   1120       Node* value = environment()->Pop();
   1121       const Operator* op = javascript()->StoreContext(0, variable->index());
   1122       NewNode(op, current_context(), value);
   1123       break;
   1124     }
   1125     case VariableLocation::LOOKUP:
   1126       UNIMPLEMENTED();
   1127   }
   1128 }
   1129 
   1130 
   1131 void AstGraphBuilder::VisitImportDeclaration(ImportDeclaration* decl) {
   1132   UNREACHABLE();
   1133 }
   1134 
   1135 
   1136 void AstGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) {
   1137   UNREACHABLE();
   1138 }
   1139 
   1140 
   1141 void AstGraphBuilder::VisitBlock(Block* stmt) {
   1142   BlockBuilder block(this);
   1143   ControlScopeForBreakable scope(this, stmt, &block);
   1144   if (stmt->labels() != nullptr) block.BeginBlock();
   1145   if (stmt->scope() == nullptr) {
   1146     // Visit statements in the same scope, no declarations.
   1147     VisitStatements(stmt->statements());
   1148   } else {
   1149     // Visit declarations and statements in a block scope.
   1150     if (stmt->scope()->NeedsContext()) {
   1151       Node* context = BuildLocalBlockContext(stmt->scope());
   1152       ContextScope scope(this, stmt->scope(), context);
   1153       VisitDeclarations(stmt->scope()->declarations());
   1154       VisitStatements(stmt->statements());
   1155     } else {
   1156       VisitDeclarations(stmt->scope()->declarations());
   1157       VisitStatements(stmt->statements());
   1158     }
   1159   }
   1160   if (stmt->labels() != nullptr) block.EndBlock();
   1161 }
   1162 
   1163 
   1164 void AstGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
   1165   VisitForEffect(stmt->expression());
   1166 }
   1167 
   1168 
   1169 void AstGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
   1170   // Do nothing.
   1171 }
   1172 
   1173 
   1174 void AstGraphBuilder::VisitSloppyBlockFunctionStatement(
   1175     SloppyBlockFunctionStatement* stmt) {
   1176   Visit(stmt->statement());
   1177 }
   1178 
   1179 
   1180 void AstGraphBuilder::VisitIfStatement(IfStatement* stmt) {
   1181   IfBuilder compare_if(this);
   1182   VisitForTest(stmt->condition());
   1183   Node* condition = environment()->Pop();
   1184   compare_if.If(condition);
   1185   compare_if.Then();
   1186   Visit(stmt->then_statement());
   1187   compare_if.Else();
   1188   Visit(stmt->else_statement());
   1189   compare_if.End();
   1190 }
   1191 
   1192 
   1193 void AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
   1194   execution_control()->ContinueTo(stmt->target());
   1195 }
   1196 
   1197 
   1198 void AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
   1199   execution_control()->BreakTo(stmt->target());
   1200 }
   1201 
   1202 
   1203 void AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
   1204   VisitForValue(stmt->expression());
   1205   Node* result = environment()->Pop();
   1206   execution_control()->ReturnValue(result);
   1207 }
   1208 
   1209 
   1210 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
   1211   VisitForValue(stmt->expression());
   1212   Node* value = environment()->Pop();
   1213   Node* object = BuildToObject(value, stmt->ToObjectId());
   1214   const Operator* op = javascript()->CreateWithContext();
   1215   Node* context = NewNode(op, object, GetFunctionClosureForContext());
   1216   PrepareFrameState(context, stmt->EntryId());
   1217   VisitInScope(stmt->statement(), stmt->scope(), context);
   1218 }
   1219 
   1220 
   1221 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
   1222   ZoneList<CaseClause*>* clauses = stmt->cases();
   1223   SwitchBuilder compare_switch(this, clauses->length());
   1224   ControlScopeForBreakable scope(this, stmt, &compare_switch);
   1225   compare_switch.BeginSwitch();
   1226   int default_index = -1;
   1227 
   1228   // Keep the switch value on the stack until a case matches.
   1229   VisitForValue(stmt->tag());
   1230 
   1231   // Iterate over all cases and create nodes for label comparison.
   1232   for (int i = 0; i < clauses->length(); i++) {
   1233     CaseClause* clause = clauses->at(i);
   1234 
   1235     // The default is not a test, remember index.
   1236     if (clause->is_default()) {
   1237       default_index = i;
   1238       continue;
   1239     }
   1240 
   1241     // Create nodes to perform label comparison as if via '==='. The switch
   1242     // value is still on the operand stack while the label is evaluated.
   1243     VisitForValue(clause->label());
   1244     Node* label = environment()->Pop();
   1245     Node* tag = environment()->Top();
   1246     const Operator* op = javascript()->StrictEqual();
   1247     Node* condition = NewNode(op, tag, label);
   1248     compare_switch.BeginLabel(i, condition);
   1249 
   1250     // Discard the switch value at label match.
   1251     environment()->Pop();
   1252     compare_switch.EndLabel();
   1253   }
   1254 
   1255   // Discard the switch value and mark the default case.
   1256   environment()->Pop();
   1257   if (default_index >= 0) {
   1258     compare_switch.DefaultAt(default_index);
   1259   }
   1260 
   1261   // Iterate over all cases and create nodes for case bodies.
   1262   for (int i = 0; i < clauses->length(); i++) {
   1263     CaseClause* clause = clauses->at(i);
   1264     compare_switch.BeginCase(i);
   1265     VisitStatements(clause->statements());
   1266     compare_switch.EndCase();
   1267   }
   1268 
   1269   compare_switch.EndSwitch();
   1270 }
   1271 
   1272 
   1273 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
   1274   LoopBuilder while_loop(this);
   1275   while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1276   VisitIterationBody(stmt, &while_loop);
   1277   while_loop.EndBody();
   1278   VisitForTest(stmt->cond());
   1279   Node* condition = environment()->Pop();
   1280   while_loop.BreakUnless(condition);
   1281   while_loop.EndLoop();
   1282 }
   1283 
   1284 
   1285 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
   1286   LoopBuilder while_loop(this);
   1287   while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1288   VisitForTest(stmt->cond());
   1289   Node* condition = environment()->Pop();
   1290   while_loop.BreakUnless(condition);
   1291   VisitIterationBody(stmt, &while_loop);
   1292   while_loop.EndBody();
   1293   while_loop.EndLoop();
   1294 }
   1295 
   1296 
   1297 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
   1298   LoopBuilder for_loop(this);
   1299   VisitIfNotNull(stmt->init());
   1300   for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1301   if (stmt->cond() != nullptr) {
   1302     VisitForTest(stmt->cond());
   1303     Node* condition = environment()->Pop();
   1304     for_loop.BreakUnless(condition);
   1305   } else {
   1306     for_loop.BreakUnless(jsgraph()->TrueConstant());
   1307   }
   1308   VisitIterationBody(stmt, &for_loop);
   1309   for_loop.EndBody();
   1310   VisitIfNotNull(stmt->next());
   1311   for_loop.EndLoop();
   1312 }
   1313 
   1314 
   1315 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
   1316   VisitForValue(stmt->subject());
   1317   Node* object = environment()->Pop();
   1318   BlockBuilder for_block(this);
   1319   for_block.BeginBlock();
   1320   // Check for null or undefined before entering loop.
   1321   Node* is_null_cond =
   1322       NewNode(javascript()->StrictEqual(), object, jsgraph()->NullConstant());
   1323   for_block.BreakWhen(is_null_cond, BranchHint::kFalse);
   1324   Node* is_undefined_cond = NewNode(javascript()->StrictEqual(), object,
   1325                                     jsgraph()->UndefinedConstant());
   1326   for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse);
   1327   {
   1328     // Convert object to jsobject.
   1329     object = BuildToObject(object, stmt->ToObjectId());
   1330     environment()->Push(object);
   1331 
   1332     // Prepare for-in cache.
   1333     Node* prepare = NewNode(javascript()->ForInPrepare(), object);
   1334     PrepareFrameState(prepare, stmt->EnumId(), OutputFrameStateCombine::Push());
   1335     Node* cache_type = NewNode(common()->Projection(0), prepare);
   1336     Node* cache_array = NewNode(common()->Projection(1), prepare);
   1337     Node* cache_length = NewNode(common()->Projection(2), prepare);
   1338 
   1339     // Construct the rest of the environment.
   1340     environment()->Push(cache_type);
   1341     environment()->Push(cache_array);
   1342     environment()->Push(cache_length);
   1343     environment()->Push(jsgraph()->ZeroConstant());
   1344 
   1345     // Build the actual loop body.
   1346     LoopBuilder for_loop(this);
   1347     for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1348     {
   1349       // These stack values are renamed in the case of OSR, so reload them
   1350       // from the environment.
   1351       Node* index = environment()->Peek(0);
   1352       Node* cache_length = environment()->Peek(1);
   1353       Node* cache_array = environment()->Peek(2);
   1354       Node* cache_type = environment()->Peek(3);
   1355       Node* object = environment()->Peek(4);
   1356 
   1357       // Check loop termination condition.
   1358       Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
   1359       for_loop.BreakWhen(exit_cond);
   1360 
   1361       // Compute the next enumerated value.
   1362       Node* value = NewNode(javascript()->ForInNext(), object, cache_array,
   1363                             cache_type, index);
   1364       PrepareFrameState(value, stmt->FilterId(),
   1365                         OutputFrameStateCombine::Push());
   1366       IfBuilder test_value(this);
   1367       Node* test_value_cond = NewNode(javascript()->StrictEqual(), value,
   1368                                       jsgraph()->UndefinedConstant());
   1369       test_value.If(test_value_cond, BranchHint::kFalse);
   1370       test_value.Then();
   1371       test_value.Else();
   1372       {
   1373         // Bind value and do loop body.
   1374         VectorSlotPair feedback =
   1375             CreateVectorSlotPair(stmt->EachFeedbackSlot());
   1376         VisitForInAssignment(stmt->each(), value, feedback, stmt->FilterId(),
   1377                              stmt->AssignmentId());
   1378         VisitIterationBody(stmt, &for_loop);
   1379       }
   1380       test_value.End();
   1381       index = environment()->Peek(0);
   1382       for_loop.EndBody();
   1383 
   1384       // Increment counter and continue.
   1385       index = NewNode(javascript()->ForInStep(), index);
   1386       environment()->Poke(0, index);
   1387     }
   1388     for_loop.EndLoop();
   1389     environment()->Drop(5);
   1390   }
   1391   for_block.EndBlock();
   1392 }
   1393 
   1394 
   1395 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
   1396   LoopBuilder for_loop(this);
   1397   VisitForEffect(stmt->assign_iterator());
   1398   for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   1399   VisitForEffect(stmt->next_result());
   1400   VisitForTest(stmt->result_done());
   1401   Node* condition = environment()->Pop();
   1402   for_loop.BreakWhen(condition);
   1403   VisitForEffect(stmt->assign_each());
   1404   VisitIterationBody(stmt, &for_loop);
   1405   for_loop.EndBody();
   1406   for_loop.EndLoop();
   1407 }
   1408 
   1409 
   1410 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
   1411   TryCatchBuilder try_control(this);
   1412 
   1413   // Evaluate the try-block inside a control scope. This simulates a handler
   1414   // that is intercepting 'throw' control commands.
   1415   try_control.BeginTry();
   1416   {
   1417     ControlScopeForCatch scope(this, &try_control);
   1418     STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
   1419     environment()->Push(current_context());
   1420     Visit(stmt->try_block());
   1421     environment()->Pop();
   1422   }
   1423   try_control.EndTry();
   1424 
   1425   // Insert lazy bailout point.
   1426   // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout
   1427   // point. Ideally, we whould not re-enter optimized code when deoptimized
   1428   // lazily. Tracked by issue v8:4195.
   1429   NewNode(common()->LazyBailout(),
   1430           jsgraph()->ZeroConstant(),                      // dummy target.
   1431           environment()->Checkpoint(stmt->HandlerId()));  // frame state.
   1432 
   1433   // Clear message object as we enter the catch block.
   1434   Node* the_hole = jsgraph()->TheHoleConstant();
   1435   NewNode(javascript()->StoreMessage(), the_hole);
   1436 
   1437   // Create a catch scope that binds the exception.
   1438   Node* exception = try_control.GetExceptionNode();
   1439   Handle<String> name = stmt->variable()->name();
   1440   const Operator* op = javascript()->CreateCatchContext(name);
   1441   Node* context = NewNode(op, exception, GetFunctionClosureForContext());
   1442 
   1443   // Evaluate the catch-block.
   1444   VisitInScope(stmt->catch_block(), stmt->scope(), context);
   1445   try_control.EndCatch();
   1446 }
   1447 
   1448 
   1449 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
   1450   TryFinallyBuilder try_control(this);
   1451 
   1452   // We keep a record of all paths that enter the finally-block to be able to
   1453   // dispatch to the correct continuation point after the statements in the
   1454   // finally-block have been evaluated.
   1455   //
   1456   // The try-finally construct can enter the finally-block in three ways:
   1457   // 1. By exiting the try-block normally, falling through at the end.
   1458   // 2. By exiting the try-block with a function-local control flow transfer
   1459   //    (i.e. through break/continue/return statements).
   1460   // 3. By exiting the try-block with a thrown exception.
   1461   Node* fallthrough_result = jsgraph()->TheHoleConstant();
   1462   ControlScope::DeferredCommands* commands =
   1463       new (local_zone()) ControlScope::DeferredCommands(this);
   1464 
   1465   // Evaluate the try-block inside a control scope. This simulates a handler
   1466   // that is intercepting all control commands.
   1467   try_control.BeginTry();
   1468   {
   1469     ControlScopeForFinally scope(this, commands, &try_control);
   1470     STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
   1471     environment()->Push(current_context());
   1472     Visit(stmt->try_block());
   1473     environment()->Pop();
   1474   }
   1475   try_control.EndTry(commands->GetFallThroughToken(), fallthrough_result);
   1476 
   1477   // Insert lazy bailout point.
   1478   // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout
   1479   // point. Ideally, we whould not re-enter optimized code when deoptimized
   1480   // lazily. Tracked by issue v8:4195.
   1481   NewNode(common()->LazyBailout(),
   1482           jsgraph()->ZeroConstant(),                      // dummy target.
   1483           environment()->Checkpoint(stmt->HandlerId()));  // frame state.
   1484 
   1485   // The result value semantics depend on how the block was entered:
   1486   //  - ReturnStatement: It represents the return value being returned.
   1487   //  - ThrowStatement: It represents the exception being thrown.
   1488   //  - BreakStatement/ContinueStatement: Filled with the hole.
   1489   //  - Falling through into finally-block: Filled with the hole.
   1490   Node* result = try_control.GetResultValueNode();
   1491   Node* token = try_control.GetDispatchTokenNode();
   1492 
   1493   // The result value, dispatch token and message is expected on the operand
   1494   // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
   1495   Node* message = NewNode(javascript()->LoadMessage());
   1496   environment()->Push(token);  // TODO(mstarzinger): Cook token!
   1497   environment()->Push(result);
   1498   environment()->Push(message);
   1499 
   1500   // Clear message object as we enter the finally block.
   1501   Node* the_hole = jsgraph()->TheHoleConstant();
   1502   NewNode(javascript()->StoreMessage(), the_hole);
   1503 
   1504   // Evaluate the finally-block.
   1505   Visit(stmt->finally_block());
   1506   try_control.EndFinally();
   1507 
   1508   // The result value, dispatch token and message is restored from the operand
   1509   // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock).
   1510   message = environment()->Pop();
   1511   result = environment()->Pop();
   1512   token = environment()->Pop();  // TODO(mstarzinger): Uncook token!
   1513   NewNode(javascript()->StoreMessage(), message);
   1514 
   1515   // Dynamic dispatch after the finally-block.
   1516   commands->ApplyDeferredCommands(token, result);
   1517 
   1518   // TODO(mstarzinger): Remove bailout once everything works.
   1519   if (!FLAG_turbo_try_finally) SetStackOverflow();
   1520 }
   1521 
   1522 
   1523 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
   1524   Node* node =
   1525       NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement, 0));
   1526   PrepareFrameState(node, stmt->DebugBreakId());
   1527   environment()->MarkAllLocalsLive();
   1528 }
   1529 
   1530 
   1531 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
   1532   // Find or build a shared function info.
   1533   Handle<SharedFunctionInfo> shared_info =
   1534       Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
   1535   CHECK(!shared_info.is_null());  // TODO(mstarzinger): Set stack overflow?
   1536 
   1537   // Create node to instantiate a new closure.
   1538   PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED;
   1539   const Operator* op = javascript()->CreateClosure(shared_info, pretenure);
   1540   Node* value = NewNode(op);
   1541   ast_context()->ProduceValue(value);
   1542 }
   1543 
   1544 
   1545 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
   1546   // Visit declarations and class literal in a block scope.
   1547   if (expr->scope()->ContextLocalCount() > 0) {
   1548     Node* context = BuildLocalBlockContext(expr->scope());
   1549     ContextScope scope(this, expr->scope(), context);
   1550     VisitDeclarations(expr->scope()->declarations());
   1551     VisitClassLiteralContents(expr);
   1552   } else {
   1553     VisitDeclarations(expr->scope()->declarations());
   1554     VisitClassLiteralContents(expr);
   1555   }
   1556 }
   1557 
   1558 
   1559 void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
   1560   Node* class_name = expr->raw_name() ? jsgraph()->Constant(expr->name())
   1561                                       : jsgraph()->UndefinedConstant();
   1562 
   1563   // The class name is expected on the operand stack.
   1564   environment()->Push(class_name);
   1565   VisitForValueOrTheHole(expr->extends());
   1566   VisitForValue(expr->constructor());
   1567 
   1568   // Create node to instantiate a new class.
   1569   Node* constructor = environment()->Pop();
   1570   Node* extends = environment()->Pop();
   1571   Node* name = environment()->Pop();
   1572   Node* start = jsgraph()->Constant(expr->start_position());
   1573   Node* end = jsgraph()->Constant(expr->end_position());
   1574   const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass, 5);
   1575   Node* literal = NewNode(opc, name, extends, constructor, start, end);
   1576   PrepareFrameState(literal, expr->CreateLiteralId(),
   1577                     OutputFrameStateCombine::Push());
   1578 
   1579   // The prototype is ensured to exist by Runtime_DefineClass. No access check
   1580   // is needed here since the constructor is created by the class literal.
   1581   Node* prototype =
   1582       BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset);
   1583 
   1584   // The class literal and the prototype are both expected on the operand stack
   1585   // during evaluation of the method values.
   1586   environment()->Push(literal);
   1587   environment()->Push(prototype);
   1588 
   1589   // Create nodes to store method values into the literal.
   1590   for (int i = 0; i < expr->properties()->length(); i++) {
   1591     ObjectLiteral::Property* property = expr->properties()->at(i);
   1592     environment()->Push(environment()->Peek(property->is_static() ? 1 : 0));
   1593 
   1594     VisitForValue(property->key());
   1595     Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i));
   1596     environment()->Push(name);
   1597 
   1598     // The static prototype property is read only. We handle the non computed
   1599     // property name case in the parser. Since this is the only case where we
   1600     // need to check for an own read only property we special case this so we do
   1601     // not need to do this for every property.
   1602     if (property->is_static() && property->is_computed_name()) {
   1603       Node* check = BuildThrowIfStaticPrototype(environment()->Pop(),
   1604                                                 expr->GetIdForProperty(i));
   1605       environment()->Push(check);
   1606     }
   1607 
   1608     VisitForValue(property->value());
   1609     Node* value = environment()->Pop();
   1610     Node* key = environment()->Pop();
   1611     Node* receiver = environment()->Pop();
   1612 
   1613     BuildSetHomeObject(value, receiver, property);
   1614 
   1615     switch (property->kind()) {
   1616       case ObjectLiteral::Property::CONSTANT:
   1617       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   1618       case ObjectLiteral::Property::PROTOTYPE:
   1619         UNREACHABLE();
   1620       case ObjectLiteral::Property::COMPUTED: {
   1621         const Operator* op =
   1622             javascript()->CallRuntime(Runtime::kDefineClassMethod, 3);
   1623         NewNode(op, receiver, key, value);
   1624         break;
   1625       }
   1626       case ObjectLiteral::Property::GETTER: {
   1627         Node* attr = jsgraph()->Constant(DONT_ENUM);
   1628         const Operator* op = javascript()->CallRuntime(
   1629             Runtime::kDefineGetterPropertyUnchecked, 4);
   1630         NewNode(op, receiver, key, value, attr);
   1631         break;
   1632       }
   1633       case ObjectLiteral::Property::SETTER: {
   1634         Node* attr = jsgraph()->Constant(DONT_ENUM);
   1635         const Operator* op = javascript()->CallRuntime(
   1636             Runtime::kDefineSetterPropertyUnchecked, 4);
   1637         NewNode(op, receiver, key, value, attr);
   1638         break;
   1639       }
   1640     }
   1641   }
   1642 
   1643   // Set both the prototype and constructor to have fast properties, and also
   1644   // freeze them in strong mode.
   1645   prototype = environment()->Pop();
   1646   literal = environment()->Pop();
   1647   const Operator* op =
   1648       javascript()->CallRuntime(Runtime::kFinalizeClassDefinition, 2);
   1649   literal = NewNode(op, literal, prototype);
   1650 
   1651   // Assign to class variable.
   1652   if (expr->class_variable_proxy() != nullptr) {
   1653     Variable* var = expr->class_variable_proxy()->var();
   1654     FrameStateBeforeAndAfter states(this, BailoutId::None());
   1655     VectorSlotPair feedback = CreateVectorSlotPair(
   1656         expr->NeedsProxySlot() ? expr->ProxySlot()
   1657                                : FeedbackVectorSlot::Invalid());
   1658     BuildVariableAssignment(var, literal, Token::INIT, feedback,
   1659                             BailoutId::None(), states);
   1660   }
   1661   ast_context()->ProduceValue(literal);
   1662 }
   1663 
   1664 
   1665 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
   1666   UNREACHABLE();
   1667 }
   1668 
   1669 
   1670 void AstGraphBuilder::VisitDoExpression(DoExpression* expr) {
   1671   VisitBlock(expr->block());
   1672   VisitVariableProxy(expr->result());
   1673   ast_context()->ReplaceValue();
   1674 }
   1675 
   1676 
   1677 void AstGraphBuilder::VisitConditional(Conditional* expr) {
   1678   IfBuilder compare_if(this);
   1679   VisitForTest(expr->condition());
   1680   Node* condition = environment()->Pop();
   1681   compare_if.If(condition);
   1682   compare_if.Then();
   1683   Visit(expr->then_expression());
   1684   compare_if.Else();
   1685   Visit(expr->else_expression());
   1686   compare_if.End();
   1687   ast_context()->ReplaceValue();
   1688 }
   1689 
   1690 
   1691 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
   1692   VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
   1693   FrameStateBeforeAndAfter states(this, BeforeId(expr));
   1694   Node* value = BuildVariableLoad(expr->var(), expr->id(), states, pair,
   1695                                   ast_context()->GetStateCombine());
   1696   ast_context()->ProduceValue(value);
   1697 }
   1698 
   1699 
   1700 void AstGraphBuilder::VisitLiteral(Literal* expr) {
   1701   Node* value = jsgraph()->Constant(expr->value());
   1702   ast_context()->ProduceValue(value);
   1703 }
   1704 
   1705 
   1706 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
   1707   Node* closure = GetFunctionClosure();
   1708 
   1709   // Create node to materialize a regular expression literal.
   1710   const Operator* op = javascript()->CreateLiteralRegExp(
   1711       expr->pattern(), expr->flags(), expr->literal_index());
   1712   Node* literal = NewNode(op, closure);
   1713   PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
   1714   ast_context()->ProduceValue(literal);
   1715 }
   1716 
   1717 
   1718 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
   1719   Node* closure = GetFunctionClosure();
   1720 
   1721   // Create node to deep-copy the literal boilerplate.
   1722   const Operator* op = javascript()->CreateLiteralObject(
   1723       expr->constant_properties(), expr->ComputeFlags(true),
   1724       expr->literal_index());
   1725   Node* literal = NewNode(op, closure);
   1726   PrepareFrameState(literal, expr->CreateLiteralId(),
   1727                     OutputFrameStateCombine::Push());
   1728 
   1729   // The object is expected on the operand stack during computation of the
   1730   // property values and is the value of the entire expression.
   1731   environment()->Push(literal);
   1732 
   1733   // Create nodes to store computed values into the literal.
   1734   int property_index = 0;
   1735   AccessorTable accessor_table(local_zone());
   1736   for (; property_index < expr->properties()->length(); property_index++) {
   1737     ObjectLiteral::Property* property = expr->properties()->at(property_index);
   1738     if (property->is_computed_name()) break;
   1739     if (property->IsCompileTimeValue()) continue;
   1740 
   1741     Literal* key = property->key()->AsLiteral();
   1742     switch (property->kind()) {
   1743       case ObjectLiteral::Property::CONSTANT:
   1744         UNREACHABLE();
   1745       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
   1746         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
   1747       // Fall through.
   1748       case ObjectLiteral::Property::COMPUTED: {
   1749         // It is safe to use [[Put]] here because the boilerplate already
   1750         // contains computed properties with an uninitialized value.
   1751         if (key->value()->IsInternalizedString()) {
   1752           if (property->emit_store()) {
   1753             VisitForValue(property->value());
   1754             FrameStateBeforeAndAfter states(this, property->value()->id());
   1755             Node* value = environment()->Pop();
   1756             Node* literal = environment()->Top();
   1757             Handle<Name> name = key->AsPropertyName();
   1758             VectorSlotPair feedback =
   1759                 CreateVectorSlotPair(property->GetSlot(0));
   1760             Node* store = BuildNamedStore(literal, name, value, feedback);
   1761             states.AddToNode(store, key->id(),
   1762                              OutputFrameStateCombine::Ignore());
   1763             BuildSetHomeObject(value, literal, property, 1);
   1764           } else {
   1765             VisitForEffect(property->value());
   1766           }
   1767           break;
   1768         }
   1769         environment()->Push(environment()->Top());  // Duplicate receiver.
   1770         VisitForValue(property->key());
   1771         VisitForValue(property->value());
   1772         Node* value = environment()->Pop();
   1773         Node* key = environment()->Pop();
   1774         Node* receiver = environment()->Pop();
   1775         if (property->emit_store()) {
   1776           Node* language = jsgraph()->Constant(SLOPPY);
   1777           const Operator* op =
   1778               javascript()->CallRuntime(Runtime::kSetProperty, 4);
   1779           Node* set_property = NewNode(op, receiver, key, value, language);
   1780           // SetProperty should not lazy deopt on an object literal.
   1781           PrepareFrameState(set_property, BailoutId::None());
   1782           BuildSetHomeObject(value, receiver, property);
   1783         }
   1784         break;
   1785       }
   1786       case ObjectLiteral::Property::PROTOTYPE: {
   1787         environment()->Push(environment()->Top());  // Duplicate receiver.
   1788         VisitForValue(property->value());
   1789         Node* value = environment()->Pop();
   1790         Node* receiver = environment()->Pop();
   1791         DCHECK(property->emit_store());
   1792         const Operator* op =
   1793             javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
   1794         Node* set_prototype = NewNode(op, receiver, value);
   1795         // SetPrototype should not lazy deopt on an object literal.
   1796         PrepareFrameState(set_prototype,
   1797                           expr->GetIdForPropertySet(property_index));
   1798         break;
   1799       }
   1800       case ObjectLiteral::Property::GETTER:
   1801         if (property->emit_store()) {
   1802           accessor_table.lookup(key)->second->getter = property;
   1803         }
   1804         break;
   1805       case ObjectLiteral::Property::SETTER:
   1806         if (property->emit_store()) {
   1807           accessor_table.lookup(key)->second->setter = property;
   1808         }
   1809         break;
   1810     }
   1811   }
   1812 
   1813   // Create nodes to define accessors, using only a single call to the runtime
   1814   // for each pair of corresponding getters and setters.
   1815   literal = environment()->Top();  // Reload from operand stack.
   1816   for (AccessorTable::Iterator it = accessor_table.begin();
   1817        it != accessor_table.end(); ++it) {
   1818     VisitForValue(it->first);
   1819     VisitObjectLiteralAccessor(literal, it->second->getter);
   1820     VisitObjectLiteralAccessor(literal, it->second->setter);
   1821     Node* setter = environment()->Pop();
   1822     Node* getter = environment()->Pop();
   1823     Node* name = environment()->Pop();
   1824     Node* attr = jsgraph()->Constant(NONE);
   1825     const Operator* op =
   1826         javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
   1827     Node* call = NewNode(op, literal, name, getter, setter, attr);
   1828     // This should not lazy deopt on a new literal.
   1829     PrepareFrameState(call, BailoutId::None());
   1830   }
   1831 
   1832   // Object literals have two parts. The "static" part on the left contains no
   1833   // computed property names, and so we can compute its map ahead of time; see
   1834   // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
   1835   // with the first computed property name and continues with all properties to
   1836   // its right. All the code from above initializes the static component of the
   1837   // object literal, and arranges for the map of the result to reflect the
   1838   // static order in which the keys appear. For the dynamic properties, we
   1839   // compile them into a series of "SetOwnProperty" runtime calls. This will
   1840   // preserve insertion order.
   1841   for (; property_index < expr->properties()->length(); property_index++) {
   1842     ObjectLiteral::Property* property = expr->properties()->at(property_index);
   1843 
   1844     if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
   1845       environment()->Push(environment()->Top());  // Duplicate receiver.
   1846       VisitForValue(property->value());
   1847       Node* value = environment()->Pop();
   1848       Node* receiver = environment()->Pop();
   1849       const Operator* op =
   1850           javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
   1851       Node* call = NewNode(op, receiver, value);
   1852       PrepareFrameState(call, expr->GetIdForPropertySet(property_index));
   1853       continue;
   1854     }
   1855 
   1856     environment()->Push(environment()->Top());  // Duplicate receiver.
   1857     VisitForValue(property->key());
   1858     Node* name = BuildToName(environment()->Pop(),
   1859                              expr->GetIdForPropertyName(property_index));
   1860     environment()->Push(name);
   1861     VisitForValue(property->value());
   1862     Node* value = environment()->Pop();
   1863     Node* key = environment()->Pop();
   1864     Node* receiver = environment()->Pop();
   1865     BuildSetHomeObject(value, receiver, property);
   1866     switch (property->kind()) {
   1867       case ObjectLiteral::Property::CONSTANT:
   1868       case ObjectLiteral::Property::COMPUTED:
   1869       case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
   1870         Node* attr = jsgraph()->Constant(NONE);
   1871         const Operator* op =
   1872             javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
   1873         Node* call = NewNode(op, receiver, key, value, attr);
   1874         PrepareFrameState(call, BailoutId::None());
   1875         break;
   1876       }
   1877       case ObjectLiteral::Property::PROTOTYPE:
   1878         UNREACHABLE();  // Handled specially above.
   1879         break;
   1880       case ObjectLiteral::Property::GETTER: {
   1881         Node* attr = jsgraph()->Constant(NONE);
   1882         const Operator* op = javascript()->CallRuntime(
   1883             Runtime::kDefineGetterPropertyUnchecked, 4);
   1884         Node* call = NewNode(op, receiver, key, value, attr);
   1885         PrepareFrameState(call, BailoutId::None());
   1886         break;
   1887       }
   1888       case ObjectLiteral::Property::SETTER: {
   1889         Node* attr = jsgraph()->Constant(NONE);
   1890         const Operator* op = javascript()->CallRuntime(
   1891             Runtime::kDefineSetterPropertyUnchecked, 4);
   1892         Node* call = NewNode(op, receiver, key, value, attr);
   1893         PrepareFrameState(call, BailoutId::None());
   1894         break;
   1895       }
   1896     }
   1897   }
   1898 
   1899   // Transform literals that contain functions to fast properties.
   1900   literal = environment()->Top();  // Reload from operand stack.
   1901   if (expr->has_function()) {
   1902     const Operator* op =
   1903         javascript()->CallRuntime(Runtime::kToFastProperties, 1);
   1904     NewNode(op, literal);
   1905   }
   1906 
   1907   ast_context()->ProduceValue(environment()->Pop());
   1908 }
   1909 
   1910 
   1911 void AstGraphBuilder::VisitObjectLiteralAccessor(
   1912     Node* home_object, ObjectLiteralProperty* property) {
   1913   if (property == nullptr) {
   1914     VisitForValueOrNull(nullptr);
   1915   } else {
   1916     VisitForValue(property->value());
   1917     BuildSetHomeObject(environment()->Top(), home_object, property);
   1918   }
   1919 }
   1920 
   1921 
   1922 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
   1923   Node* closure = GetFunctionClosure();
   1924 
   1925   // Create node to deep-copy the literal boilerplate.
   1926   const Operator* op = javascript()->CreateLiteralArray(
   1927       expr->constant_elements(), expr->ComputeFlags(true),
   1928       expr->literal_index());
   1929   Node* literal = NewNode(op, closure);
   1930   PrepareFrameState(literal, expr->CreateLiteralId(),
   1931                     OutputFrameStateCombine::Push());
   1932 
   1933   // The array is expected on the operand stack during computation of the
   1934   // element values.
   1935   environment()->Push(literal);
   1936 
   1937   // Create nodes to evaluate all the non-constant subexpressions and to store
   1938   // them into the newly cloned array.
   1939   int array_index = 0;
   1940   for (; array_index < expr->values()->length(); array_index++) {
   1941     Expression* subexpr = expr->values()->at(array_index);
   1942     if (subexpr->IsSpread()) break;
   1943     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
   1944 
   1945     VisitForValue(subexpr);
   1946     {
   1947       FrameStateBeforeAndAfter states(this, subexpr->id());
   1948       VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot());
   1949       Node* value = environment()->Pop();
   1950       Node* index = jsgraph()->Constant(array_index);
   1951       Node* literal = environment()->Top();
   1952       Node* store = BuildKeyedStore(literal, index, value, pair);
   1953       states.AddToNode(store, expr->GetIdForElement(array_index),
   1954                        OutputFrameStateCombine::Ignore());
   1955     }
   1956   }
   1957 
   1958   // In case the array literal contains spread expressions it has two parts. The
   1959   // first part is  the "static" array which has a literal index is handled
   1960   // above. The second part is the part after the first spread expression
   1961   // (inclusive) and these elements gets appended to the array. Note that the
   1962   // number elements an iterable produces is unknown ahead of time.
   1963   for (; array_index < expr->values()->length(); array_index++) {
   1964     Expression* subexpr = expr->values()->at(array_index);
   1965     Node* result;
   1966 
   1967     if (subexpr->IsSpread()) {
   1968       VisitForValue(subexpr->AsSpread()->expression());
   1969       FrameStateBeforeAndAfter states(this,
   1970                                       subexpr->AsSpread()->expression()->id());
   1971       Node* iterable = environment()->Pop();
   1972       Node* array = environment()->Pop();
   1973       Node* function = BuildLoadNativeContextField(
   1974           Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX);
   1975       result = NewNode(javascript()->CallFunction(3, language_mode()), function,
   1976                        array, iterable);
   1977       states.AddToNode(result, expr->GetIdForElement(array_index));
   1978     } else {
   1979       VisitForValue(subexpr);
   1980       Node* value = environment()->Pop();
   1981       Node* array = environment()->Pop();
   1982       const Operator* op =
   1983           javascript()->CallRuntime(Runtime::kAppendElement, 2);
   1984       result = NewNode(op, array, value);
   1985       PrepareFrameState(result, expr->GetIdForElement(array_index));
   1986     }
   1987 
   1988     environment()->Push(result);
   1989   }
   1990 
   1991   ast_context()->ProduceValue(environment()->Pop());
   1992 }
   1993 
   1994 
   1995 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
   1996                                            const VectorSlotPair& feedback,
   1997                                            BailoutId bailout_id_before,
   1998                                            BailoutId bailout_id_after) {
   1999   DCHECK(expr->IsValidReferenceExpressionOrThis());
   2000 
   2001   // Left-hand side can only be a property, a global or a variable slot.
   2002   Property* property = expr->AsProperty();
   2003   LhsKind assign_type = Property::GetAssignType(property);
   2004 
   2005   // Evaluate LHS expression and store the value.
   2006   switch (assign_type) {
   2007     case VARIABLE: {
   2008       Variable* var = expr->AsVariableProxy()->var();
   2009       environment()->Push(value);
   2010       FrameStateBeforeAndAfter states(this, bailout_id_before);
   2011       value = environment()->Pop();
   2012       BuildVariableAssignment(var, value, Token::ASSIGN, feedback,
   2013                               bailout_id_after, states);
   2014       break;
   2015     }
   2016     case NAMED_PROPERTY: {
   2017       environment()->Push(value);
   2018       VisitForValue(property->obj());
   2019       FrameStateBeforeAndAfter states(this, property->obj()->id());
   2020       Node* object = environment()->Pop();
   2021       value = environment()->Pop();
   2022       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2023       Node* store = BuildNamedStore(object, name, value, feedback);
   2024       states.AddToNode(store, bailout_id_after,
   2025                        OutputFrameStateCombine::Ignore());
   2026       break;
   2027     }
   2028     case KEYED_PROPERTY: {
   2029       environment()->Push(value);
   2030       VisitForValue(property->obj());
   2031       VisitForValue(property->key());
   2032       FrameStateBeforeAndAfter states(this, property->key()->id());
   2033       Node* key = environment()->Pop();
   2034       Node* object = environment()->Pop();
   2035       value = environment()->Pop();
   2036       Node* store = BuildKeyedStore(object, key, value, feedback);
   2037       states.AddToNode(store, bailout_id_after,
   2038                        OutputFrameStateCombine::Ignore());
   2039       break;
   2040     }
   2041     case NAMED_SUPER_PROPERTY: {
   2042       environment()->Push(value);
   2043       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2044       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2045       FrameStateBeforeAndAfter states(this, property->obj()->id());
   2046       Node* home_object = environment()->Pop();
   2047       Node* receiver = environment()->Pop();
   2048       value = environment()->Pop();
   2049       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2050       Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
   2051       states.AddToNode(store, bailout_id_after,
   2052                        OutputFrameStateCombine::Ignore());
   2053       break;
   2054     }
   2055     case KEYED_SUPER_PROPERTY: {
   2056       environment()->Push(value);
   2057       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2058       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2059       VisitForValue(property->key());
   2060       FrameStateBeforeAndAfter states(this, property->key()->id());
   2061       Node* key = environment()->Pop();
   2062       Node* home_object = environment()->Pop();
   2063       Node* receiver = environment()->Pop();
   2064       value = environment()->Pop();
   2065       Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
   2066       states.AddToNode(store, bailout_id_after,
   2067                        OutputFrameStateCombine::Ignore());
   2068       break;
   2069     }
   2070   }
   2071 }
   2072 
   2073 
   2074 void AstGraphBuilder::VisitAssignment(Assignment* expr) {
   2075   DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
   2076 
   2077   // Left-hand side can only be a property, a global or a variable slot.
   2078   Property* property = expr->target()->AsProperty();
   2079   LhsKind assign_type = Property::GetAssignType(property);
   2080   bool needs_frame_state_before = true;
   2081 
   2082   // Evaluate LHS expression.
   2083   switch (assign_type) {
   2084     case VARIABLE: {
   2085       Variable* variable = expr->target()->AsVariableProxy()->var();
   2086       if (variable->location() == VariableLocation::PARAMETER ||
   2087           variable->location() == VariableLocation::LOCAL ||
   2088           variable->location() == VariableLocation::CONTEXT) {
   2089         needs_frame_state_before = false;
   2090       }
   2091       break;
   2092     }
   2093     case NAMED_PROPERTY:
   2094       VisitForValue(property->obj());
   2095       break;
   2096     case KEYED_PROPERTY:
   2097       VisitForValue(property->obj());
   2098       VisitForValue(property->key());
   2099       break;
   2100     case NAMED_SUPER_PROPERTY:
   2101       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2102       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2103       break;
   2104     case KEYED_SUPER_PROPERTY:
   2105       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2106       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2107       VisitForValue(property->key());
   2108       break;
   2109   }
   2110 
   2111   BailoutId before_store_id = BailoutId::None();
   2112   // Evaluate the value and potentially handle compound assignments by loading
   2113   // the left-hand side value and performing a binary operation.
   2114   if (expr->is_compound()) {
   2115     Node* old_value = nullptr;
   2116     switch (assign_type) {
   2117       case VARIABLE: {
   2118         VariableProxy* proxy = expr->target()->AsVariableProxy();
   2119         VectorSlotPair pair =
   2120             CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   2121         FrameStateBeforeAndAfter states(this, BeforeId(proxy));
   2122         old_value =
   2123             BuildVariableLoad(proxy->var(), expr->target()->id(), states, pair,
   2124                               OutputFrameStateCombine::Push());
   2125         break;
   2126       }
   2127       case NAMED_PROPERTY: {
   2128         Node* object = environment()->Top();
   2129         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2130         VectorSlotPair pair =
   2131             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2132         FrameStateBeforeAndAfter states(this, property->obj()->id());
   2133         old_value = BuildNamedLoad(object, name, pair);
   2134         states.AddToNode(old_value, property->LoadId(),
   2135                          OutputFrameStateCombine::Push());
   2136         break;
   2137       }
   2138       case KEYED_PROPERTY: {
   2139         Node* key = environment()->Top();
   2140         Node* object = environment()->Peek(1);
   2141         VectorSlotPair pair =
   2142             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2143         FrameStateBeforeAndAfter states(this, property->key()->id());
   2144         old_value = BuildKeyedLoad(object, key, pair);
   2145         states.AddToNode(old_value, property->LoadId(),
   2146                          OutputFrameStateCombine::Push());
   2147         break;
   2148       }
   2149       case NAMED_SUPER_PROPERTY: {
   2150         Node* home_object = environment()->Top();
   2151         Node* receiver = environment()->Peek(1);
   2152         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2153         VectorSlotPair pair =
   2154             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2155         FrameStateBeforeAndAfter states(this, property->obj()->id());
   2156         old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
   2157         states.AddToNode(old_value, property->LoadId(),
   2158                          OutputFrameStateCombine::Push());
   2159         break;
   2160       }
   2161       case KEYED_SUPER_PROPERTY: {
   2162         Node* key = environment()->Top();
   2163         Node* home_object = environment()->Peek(1);
   2164         Node* receiver = environment()->Peek(2);
   2165         VectorSlotPair pair =
   2166             CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2167         FrameStateBeforeAndAfter states(this, property->key()->id());
   2168         old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
   2169         states.AddToNode(old_value, property->LoadId(),
   2170                          OutputFrameStateCombine::Push());
   2171         break;
   2172       }
   2173     }
   2174     environment()->Push(old_value);
   2175     VisitForValue(expr->value());
   2176     Node* value;
   2177     {
   2178       FrameStateBeforeAndAfter states(this, expr->value()->id());
   2179       Node* right = environment()->Pop();
   2180       Node* left = environment()->Pop();
   2181       value =
   2182           BuildBinaryOp(left, right, expr->binary_op(),
   2183                         expr->binary_operation()->BinaryOperationFeedbackId());
   2184       states.AddToNode(value, expr->binary_operation()->id(),
   2185                        OutputFrameStateCombine::Push());
   2186     }
   2187     environment()->Push(value);
   2188     if (needs_frame_state_before) {
   2189       before_store_id = expr->binary_operation()->id();
   2190     }
   2191   } else {
   2192     VisitForValue(expr->value());
   2193     if (needs_frame_state_before) {
   2194       before_store_id = expr->value()->id();
   2195     }
   2196   }
   2197 
   2198   FrameStateBeforeAndAfter store_states(this, before_store_id);
   2199   // Store the value.
   2200   Node* value = environment()->Pop();
   2201   VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot());
   2202   switch (assign_type) {
   2203     case VARIABLE: {
   2204       Variable* variable = expr->target()->AsVariableProxy()->var();
   2205       BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(),
   2206                               store_states, ast_context()->GetStateCombine());
   2207       break;
   2208     }
   2209     case NAMED_PROPERTY: {
   2210       Node* object = environment()->Pop();
   2211       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2212       Node* store = BuildNamedStore(object, name, value, feedback);
   2213       store_states.AddToNode(store, expr->id(),
   2214                              ast_context()->GetStateCombine());
   2215       break;
   2216     }
   2217     case KEYED_PROPERTY: {
   2218       Node* key = environment()->Pop();
   2219       Node* object = environment()->Pop();
   2220       Node* store = BuildKeyedStore(object, key, value, feedback);
   2221       store_states.AddToNode(store, expr->id(),
   2222                              ast_context()->GetStateCombine());
   2223       break;
   2224     }
   2225     case NAMED_SUPER_PROPERTY: {
   2226       Node* home_object = environment()->Pop();
   2227       Node* receiver = environment()->Pop();
   2228       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2229       Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
   2230       store_states.AddToNode(store, expr->id(),
   2231                              ast_context()->GetStateCombine());
   2232       break;
   2233     }
   2234     case KEYED_SUPER_PROPERTY: {
   2235       Node* key = environment()->Pop();
   2236       Node* home_object = environment()->Pop();
   2237       Node* receiver = environment()->Pop();
   2238       Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
   2239       store_states.AddToNode(store, expr->id(),
   2240                              ast_context()->GetStateCombine());
   2241       break;
   2242     }
   2243   }
   2244 
   2245   ast_context()->ProduceValue(value);
   2246 }
   2247 
   2248 
   2249 void AstGraphBuilder::VisitYield(Yield* expr) {
   2250   // TODO(turbofan): Implement yield here.
   2251   SetStackOverflow();
   2252   ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   2253 }
   2254 
   2255 
   2256 void AstGraphBuilder::VisitThrow(Throw* expr) {
   2257   VisitForValue(expr->exception());
   2258   Node* exception = environment()->Pop();
   2259   Node* value = BuildThrowError(exception, expr->id());
   2260   ast_context()->ProduceValue(value);
   2261 }
   2262 
   2263 
   2264 void AstGraphBuilder::VisitProperty(Property* expr) {
   2265   Node* value = nullptr;
   2266   LhsKind property_kind = Property::GetAssignType(expr);
   2267   VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
   2268   switch (property_kind) {
   2269     case VARIABLE:
   2270       UNREACHABLE();
   2271       break;
   2272     case NAMED_PROPERTY: {
   2273       VisitForValue(expr->obj());
   2274       FrameStateBeforeAndAfter states(this, expr->obj()->id());
   2275       Node* object = environment()->Pop();
   2276       Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
   2277       value = BuildNamedLoad(object, name, pair);
   2278       states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2279       break;
   2280     }
   2281     case KEYED_PROPERTY: {
   2282       VisitForValue(expr->obj());
   2283       VisitForValue(expr->key());
   2284       FrameStateBeforeAndAfter states(this, expr->key()->id());
   2285       Node* key = environment()->Pop();
   2286       Node* object = environment()->Pop();
   2287       value = BuildKeyedLoad(object, key, pair);
   2288       states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2289       break;
   2290     }
   2291     case NAMED_SUPER_PROPERTY: {
   2292       VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
   2293       VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
   2294       FrameStateBeforeAndAfter states(this, expr->obj()->id());
   2295       Node* home_object = environment()->Pop();
   2296       Node* receiver = environment()->Pop();
   2297       Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
   2298       value = BuildNamedSuperLoad(receiver, home_object, name, pair);
   2299       states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2300       break;
   2301     }
   2302     case KEYED_SUPER_PROPERTY: {
   2303       VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
   2304       VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
   2305       VisitForValue(expr->key());
   2306       FrameStateBeforeAndAfter states(this, expr->key()->id());
   2307       Node* key = environment()->Pop();
   2308       Node* home_object = environment()->Pop();
   2309       Node* receiver = environment()->Pop();
   2310       value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
   2311       states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2312       break;
   2313     }
   2314   }
   2315   ast_context()->ProduceValue(value);
   2316 }
   2317 
   2318 
   2319 void AstGraphBuilder::VisitCall(Call* expr) {
   2320   Expression* callee = expr->expression();
   2321   Call::CallType call_type = expr->GetCallType(isolate());
   2322 
   2323   // Prepare the callee and the receiver to the function call. This depends on
   2324   // the semantics of the underlying call type.
   2325   ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
   2326   Node* receiver_value = nullptr;
   2327   Node* callee_value = nullptr;
   2328   bool possibly_eval = false;
   2329   switch (call_type) {
   2330     case Call::GLOBAL_CALL: {
   2331       VariableProxy* proxy = callee->AsVariableProxy();
   2332       VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   2333       FrameStateBeforeAndAfter states(this, BeforeId(proxy));
   2334       callee_value =
   2335           BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
   2336                             pair, OutputFrameStateCombine::Push());
   2337       receiver_hint = ConvertReceiverMode::kNullOrUndefined;
   2338       receiver_value = jsgraph()->UndefinedConstant();
   2339       break;
   2340     }
   2341     case Call::LOOKUP_SLOT_CALL: {
   2342       Variable* variable = callee->AsVariableProxy()->var();
   2343       DCHECK(variable->location() == VariableLocation::LOOKUP);
   2344       Node* name = jsgraph()->Constant(variable->name());
   2345       const Operator* op =
   2346           javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
   2347       Node* pair = NewNode(op, current_context(), name);
   2348       callee_value = NewNode(common()->Projection(0), pair);
   2349       receiver_value = NewNode(common()->Projection(1), pair);
   2350       PrepareFrameState(pair, expr->LookupId(),
   2351                         OutputFrameStateCombine::Push(2));
   2352       break;
   2353     }
   2354     case Call::NAMED_PROPERTY_CALL: {
   2355       Property* property = callee->AsProperty();
   2356       VectorSlotPair feedback =
   2357           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2358       VisitForValue(property->obj());
   2359       FrameStateBeforeAndAfter states(this, property->obj()->id());
   2360       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2361       Node* object = environment()->Top();
   2362       callee_value = BuildNamedLoad(object, name, feedback);
   2363       states.AddToNode(callee_value, property->LoadId(),
   2364                        OutputFrameStateCombine::Push());
   2365       // Note that a property call requires the receiver to be wrapped into
   2366       // an object for sloppy callees. However the receiver is guaranteed
   2367       // not to be null or undefined at this point.
   2368       receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
   2369       receiver_value = environment()->Pop();
   2370       break;
   2371     }
   2372     case Call::KEYED_PROPERTY_CALL: {
   2373       Property* property = callee->AsProperty();
   2374       VectorSlotPair feedback =
   2375           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2376       VisitForValue(property->obj());
   2377       VisitForValue(property->key());
   2378       FrameStateBeforeAndAfter states(this, property->key()->id());
   2379       Node* key = environment()->Pop();
   2380       Node* object = environment()->Top();
   2381       callee_value = BuildKeyedLoad(object, key, feedback);
   2382       states.AddToNode(callee_value, property->LoadId(),
   2383                        OutputFrameStateCombine::Push());
   2384       // Note that a property call requires the receiver to be wrapped into
   2385       // an object for sloppy callees. However the receiver is guaranteed
   2386       // not to be null or undefined at this point.
   2387       receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
   2388       receiver_value = environment()->Pop();
   2389       break;
   2390     }
   2391     case Call::NAMED_SUPER_PROPERTY_CALL: {
   2392       Property* property = callee->AsProperty();
   2393       SuperPropertyReference* super_ref =
   2394           property->obj()->AsSuperPropertyReference();
   2395       VisitForValue(super_ref->home_object());
   2396       VisitForValue(super_ref->this_var());
   2397       Node* home = environment()->Peek(1);
   2398       Node* object = environment()->Top();
   2399       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2400       FrameStateBeforeAndAfter states(this, property->obj()->id());
   2401       callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair());
   2402       states.AddToNode(callee_value, property->LoadId(),
   2403                        OutputFrameStateCombine::Push());
   2404       // Note that a property call requires the receiver to be wrapped into
   2405       // an object for sloppy callees. Since the receiver is not the target of
   2406       // the load, it could very well be null or undefined at this point.
   2407       receiver_value = environment()->Pop();
   2408       environment()->Drop(1);
   2409       break;
   2410     }
   2411     case Call::KEYED_SUPER_PROPERTY_CALL: {
   2412       Property* property = callee->AsProperty();
   2413       SuperPropertyReference* super_ref =
   2414           property->obj()->AsSuperPropertyReference();
   2415       VisitForValue(super_ref->home_object());
   2416       VisitForValue(super_ref->this_var());
   2417       environment()->Push(environment()->Top());    // Duplicate this_var.
   2418       environment()->Push(environment()->Peek(2));  // Duplicate home_obj.
   2419       VisitForValue(property->key());
   2420       Node* key = environment()->Pop();
   2421       Node* home = environment()->Pop();
   2422       Node* object = environment()->Pop();
   2423       FrameStateBeforeAndAfter states(this, property->key()->id());
   2424       callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
   2425       states.AddToNode(callee_value, property->LoadId(),
   2426                        OutputFrameStateCombine::Push());
   2427       // Note that a property call requires the receiver to be wrapped into
   2428       // an object for sloppy callees. Since the receiver is not the target of
   2429       // the load, it could very well be null or undefined at this point.
   2430       receiver_value = environment()->Pop();
   2431       environment()->Drop(1);
   2432       break;
   2433     }
   2434     case Call::SUPER_CALL:
   2435       return VisitCallSuper(expr);
   2436     case Call::POSSIBLY_EVAL_CALL:
   2437       possibly_eval = true;
   2438       if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
   2439         Variable* variable = callee->AsVariableProxy()->var();
   2440         Node* name = jsgraph()->Constant(variable->name());
   2441         const Operator* op =
   2442             javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
   2443         Node* pair = NewNode(op, current_context(), name);
   2444         callee_value = NewNode(common()->Projection(0), pair);
   2445         receiver_value = NewNode(common()->Projection(1), pair);
   2446         PrepareFrameState(pair, expr->LookupId(),
   2447                           OutputFrameStateCombine::Push(2));
   2448         break;
   2449       }
   2450     // Fall through.
   2451     case Call::OTHER_CALL:
   2452       VisitForValue(callee);
   2453       callee_value = environment()->Pop();
   2454       receiver_hint = ConvertReceiverMode::kNullOrUndefined;
   2455       receiver_value = jsgraph()->UndefinedConstant();
   2456       break;
   2457   }
   2458 
   2459   // The callee and the receiver both have to be pushed onto the operand stack
   2460   // before arguments are being evaluated.
   2461   environment()->Push(callee_value);
   2462   environment()->Push(receiver_value);
   2463 
   2464   // Evaluate all arguments to the function call,
   2465   ZoneList<Expression*>* args = expr->arguments();
   2466   VisitForValues(args);
   2467 
   2468   // Resolve callee for a potential direct eval call. This block will mutate the
   2469   // callee value pushed onto the environment.
   2470   if (possibly_eval && args->length() > 0) {
   2471     int arg_count = args->length();
   2472 
   2473     // Extract callee and source string from the environment.
   2474     Node* callee = environment()->Peek(arg_count + 1);
   2475     Node* source = environment()->Peek(arg_count - 1);
   2476 
   2477     // Create node to ask for help resolving potential eval call. This will
   2478     // provide a fully resolved callee to patch into the environment.
   2479     Node* function = GetFunctionClosure();
   2480     Node* language = jsgraph()->Constant(language_mode());
   2481     Node* position = jsgraph()->Constant(current_scope()->start_position());
   2482     const Operator* op =
   2483         javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
   2484     Node* new_callee =
   2485         NewNode(op, callee, source, function, language, position);
   2486     PrepareFrameState(new_callee, expr->EvalId(),
   2487                       OutputFrameStateCombine::PokeAt(arg_count + 1));
   2488 
   2489     // Patch callee on the environment.
   2490     environment()->Poke(arg_count + 1, new_callee);
   2491   }
   2492 
   2493   // Create node to perform the function call.
   2494   VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
   2495   const Operator* call = javascript()->CallFunction(
   2496       args->length() + 2, language_mode(), feedback, receiver_hint);
   2497   FrameStateBeforeAndAfter states(this, expr->CallId());
   2498   Node* value = ProcessArguments(call, args->length() + 2);
   2499   environment()->Push(value->InputAt(0));  // The callee passed to the call.
   2500   states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   2501   environment()->Drop(1);
   2502   ast_context()->ProduceValue(value);
   2503 }
   2504 
   2505 
   2506 void AstGraphBuilder::VisitCallSuper(Call* expr) {
   2507   SuperCallReference* super = expr->expression()->AsSuperCallReference();
   2508   DCHECK_NOT_NULL(super);
   2509 
   2510   // Prepare the callee to the super call.
   2511   VisitForValue(super->this_function_var());
   2512   Node* this_function = environment()->Pop();
   2513   const Operator* op =
   2514       javascript()->CallRuntime(Runtime::kInlineGetSuperConstructor, 1);
   2515   Node* super_function = NewNode(op, this_function);
   2516   environment()->Push(super_function);
   2517 
   2518   // Evaluate all arguments to the super call.
   2519   ZoneList<Expression*>* args = expr->arguments();
   2520   VisitForValues(args);
   2521 
   2522   // The new target is loaded from the {new.target} variable.
   2523   VisitForValue(super->new_target_var());
   2524 
   2525   // Create node to perform the super call.
   2526   const Operator* call =
   2527       javascript()->CallConstruct(args->length() + 2, VectorSlotPair());
   2528   FrameStateBeforeAndAfter states(this, super->new_target_var()->id());
   2529   Node* value = ProcessArguments(call, args->length() + 2);
   2530   states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   2531   ast_context()->ProduceValue(value);
   2532 }
   2533 
   2534 
   2535 void AstGraphBuilder::VisitCallNew(CallNew* expr) {
   2536   VisitForValue(expr->expression());
   2537 
   2538   // Evaluate all arguments to the construct call.
   2539   ZoneList<Expression*>* args = expr->arguments();
   2540   VisitForValues(args);
   2541 
   2542   // The baseline compiler doesn't push the new.target, so we need to record
   2543   // the frame state before the push.
   2544   FrameStateBeforeAndAfter states(
   2545       this, args->is_empty() ? expr->expression()->id() : args->last()->id());
   2546 
   2547   // The new target is the same as the callee.
   2548   environment()->Push(environment()->Peek(args->length()));
   2549 
   2550   // Create node to perform the construct call.
   2551   VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot());
   2552   const Operator* call =
   2553       javascript()->CallConstruct(args->length() + 2, feedback);
   2554   Node* value = ProcessArguments(call, args->length() + 2);
   2555   states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   2556   ast_context()->ProduceValue(value);
   2557 }
   2558 
   2559 
   2560 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
   2561   // The callee and the receiver both have to be pushed onto the operand stack
   2562   // before arguments are being evaluated.
   2563   Node* callee_value = BuildLoadNativeContextField(expr->context_index());
   2564   Node* receiver_value = jsgraph()->UndefinedConstant();
   2565 
   2566   environment()->Push(callee_value);
   2567   environment()->Push(receiver_value);
   2568 
   2569   // Evaluate all arguments to the JS runtime call.
   2570   ZoneList<Expression*>* args = expr->arguments();
   2571   VisitForValues(args);
   2572 
   2573   // Create node to perform the JS runtime call.
   2574   const Operator* call =
   2575       javascript()->CallFunction(args->length() + 2, language_mode());
   2576   FrameStateBeforeAndAfter states(this, expr->CallId());
   2577   Node* value = ProcessArguments(call, args->length() + 2);
   2578   states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2579   ast_context()->ProduceValue(value);
   2580 }
   2581 
   2582 
   2583 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
   2584   // Handle calls to runtime functions implemented in JavaScript separately as
   2585   // the call follows JavaScript ABI and the callee is statically unknown.
   2586   if (expr->is_jsruntime()) {
   2587     return VisitCallJSRuntime(expr);
   2588   }
   2589 
   2590   const Runtime::Function* function = expr->function();
   2591 
   2592   // TODO(mstarzinger): This bailout is a gigantic hack, the owner is ashamed.
   2593   if (function->function_id == Runtime::kInlineGeneratorNext ||
   2594       function->function_id == Runtime::kInlineGeneratorThrow) {
   2595     ast_context()->ProduceValue(jsgraph()->TheHoleConstant());
   2596     return SetStackOverflow();
   2597   }
   2598 
   2599   // Evaluate all arguments to the runtime call.
   2600   ZoneList<Expression*>* args = expr->arguments();
   2601   VisitForValues(args);
   2602 
   2603   // Create node to perform the runtime call.
   2604   Runtime::FunctionId functionId = function->function_id;
   2605   const Operator* call = javascript()->CallRuntime(functionId, args->length());
   2606   FrameStateBeforeAndAfter states(this, expr->CallId());
   2607   Node* value = ProcessArguments(call, args->length());
   2608   states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2609   ast_context()->ProduceValue(value);
   2610 }
   2611 
   2612 
   2613 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
   2614   switch (expr->op()) {
   2615     case Token::DELETE:
   2616       return VisitDelete(expr);
   2617     case Token::VOID:
   2618       return VisitVoid(expr);
   2619     case Token::TYPEOF:
   2620       return VisitTypeof(expr);
   2621     case Token::NOT:
   2622       return VisitNot(expr);
   2623     default:
   2624       UNREACHABLE();
   2625   }
   2626 }
   2627 
   2628 
   2629 void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
   2630   DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
   2631 
   2632   // Left-hand side can only be a property, a global or a variable slot.
   2633   Property* property = expr->expression()->AsProperty();
   2634   LhsKind assign_type = Property::GetAssignType(property);
   2635 
   2636   // Reserve space for result of postfix operation.
   2637   bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect();
   2638   if (is_postfix && assign_type != VARIABLE) {
   2639     environment()->Push(jsgraph()->ZeroConstant());
   2640   }
   2641 
   2642   // Evaluate LHS expression and get old value.
   2643   Node* old_value = nullptr;
   2644   int stack_depth = -1;
   2645   switch (assign_type) {
   2646     case VARIABLE: {
   2647       VariableProxy* proxy = expr->expression()->AsVariableProxy();
   2648       VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   2649       FrameStateBeforeAndAfter states(this, BeforeId(proxy));
   2650       old_value =
   2651           BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
   2652                             pair, OutputFrameStateCombine::Push());
   2653       stack_depth = 0;
   2654       break;
   2655     }
   2656     case NAMED_PROPERTY: {
   2657       VisitForValue(property->obj());
   2658       FrameStateBeforeAndAfter states(this, property->obj()->id());
   2659       Node* object = environment()->Top();
   2660       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2661       VectorSlotPair pair =
   2662           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2663       old_value = BuildNamedLoad(object, name, pair);
   2664       states.AddToNode(old_value, property->LoadId(),
   2665                        OutputFrameStateCombine::Push());
   2666       stack_depth = 1;
   2667       break;
   2668     }
   2669     case KEYED_PROPERTY: {
   2670       VisitForValue(property->obj());
   2671       VisitForValue(property->key());
   2672       FrameStateBeforeAndAfter states(this, property->key()->id());
   2673       Node* key = environment()->Top();
   2674       Node* object = environment()->Peek(1);
   2675       VectorSlotPair pair =
   2676           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2677       old_value = BuildKeyedLoad(object, key, pair);
   2678       states.AddToNode(old_value, property->LoadId(),
   2679                        OutputFrameStateCombine::Push());
   2680       stack_depth = 2;
   2681       break;
   2682     }
   2683     case NAMED_SUPER_PROPERTY: {
   2684       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2685       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2686       FrameStateBeforeAndAfter states(this, property->obj()->id());
   2687       Node* home_object = environment()->Top();
   2688       Node* receiver = environment()->Peek(1);
   2689       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2690       VectorSlotPair pair =
   2691           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2692       old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
   2693       states.AddToNode(old_value, property->LoadId(),
   2694                        OutputFrameStateCombine::Push());
   2695       stack_depth = 2;
   2696       break;
   2697     }
   2698     case KEYED_SUPER_PROPERTY: {
   2699       VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
   2700       VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
   2701       VisitForValue(property->key());
   2702       FrameStateBeforeAndAfter states(this, property->obj()->id());
   2703       Node* key = environment()->Top();
   2704       Node* home_object = environment()->Peek(1);
   2705       Node* receiver = environment()->Peek(2);
   2706       VectorSlotPair pair =
   2707           CreateVectorSlotPair(property->PropertyFeedbackSlot());
   2708       old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
   2709       states.AddToNode(old_value, property->LoadId(),
   2710                        OutputFrameStateCombine::Push());
   2711       stack_depth = 3;
   2712       break;
   2713     }
   2714   }
   2715 
   2716   // Convert old value into a number.
   2717   if (!is_strong(language_mode())) {
   2718     old_value = NewNode(javascript()->ToNumber(), old_value);
   2719     PrepareFrameState(old_value, expr->ToNumberId(),
   2720                       OutputFrameStateCombine::Push());
   2721   }
   2722 
   2723   // Create a proper eager frame state for the stores.
   2724   environment()->Push(old_value);
   2725   FrameStateBeforeAndAfter store_states(this, expr->ToNumberId());
   2726   old_value = environment()->Pop();
   2727 
   2728   // Save result for postfix expressions at correct stack depth.
   2729   if (is_postfix) {
   2730     if (assign_type != VARIABLE) {
   2731       environment()->Poke(stack_depth, old_value);
   2732     } else {
   2733       environment()->Push(old_value);
   2734     }
   2735   }
   2736 
   2737   // Create node to perform +1/-1 operation.
   2738   Node* value;
   2739   {
   2740     // TODO(bmeurer): Cleanup this feedback/bailout mess!
   2741     FrameStateBeforeAndAfter states(this, BailoutId::None());
   2742     value = BuildBinaryOp(old_value, jsgraph()->OneConstant(),
   2743                           expr->binary_op(), TypeFeedbackId::None());
   2744     // This should never deoptimize outside strong mode because otherwise we
   2745     // have converted to number before.
   2746     states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId()
   2747                                                        : BailoutId::None(),
   2748                      OutputFrameStateCombine::Ignore());
   2749   }
   2750 
   2751   // Store the value.
   2752   VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot());
   2753   switch (assign_type) {
   2754     case VARIABLE: {
   2755       Variable* variable = expr->expression()->AsVariableProxy()->var();
   2756       environment()->Push(value);
   2757       BuildVariableAssignment(variable, value, expr->op(), feedback,
   2758                               expr->AssignmentId(), store_states);
   2759       environment()->Pop();
   2760       break;
   2761     }
   2762     case NAMED_PROPERTY: {
   2763       Node* object = environment()->Pop();
   2764       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2765       Node* store = BuildNamedStore(object, name, value, feedback);
   2766       environment()->Push(value);
   2767       store_states.AddToNode(store, expr->AssignmentId(),
   2768                              OutputFrameStateCombine::Ignore());
   2769       environment()->Pop();
   2770       break;
   2771     }
   2772     case KEYED_PROPERTY: {
   2773       Node* key = environment()->Pop();
   2774       Node* object = environment()->Pop();
   2775       Node* store = BuildKeyedStore(object, key, value, feedback);
   2776       environment()->Push(value);
   2777       store_states.AddToNode(store, expr->AssignmentId(),
   2778                              OutputFrameStateCombine::Ignore());
   2779       environment()->Pop();
   2780       break;
   2781     }
   2782     case NAMED_SUPER_PROPERTY: {
   2783       Node* home_object = environment()->Pop();
   2784       Node* receiver = environment()->Pop();
   2785       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
   2786       Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
   2787       environment()->Push(value);
   2788       store_states.AddToNode(store, expr->AssignmentId(),
   2789                              OutputFrameStateCombine::Ignore());
   2790       environment()->Pop();
   2791       break;
   2792     }
   2793     case KEYED_SUPER_PROPERTY: {
   2794       Node* key = environment()->Pop();
   2795       Node* home_object = environment()->Pop();
   2796       Node* receiver = environment()->Pop();
   2797       Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
   2798       environment()->Push(value);
   2799       store_states.AddToNode(store, expr->AssignmentId(),
   2800                              OutputFrameStateCombine::Ignore());
   2801       environment()->Pop();
   2802       break;
   2803     }
   2804   }
   2805 
   2806   // Restore old value for postfix expressions.
   2807   if (is_postfix) value = environment()->Pop();
   2808 
   2809   ast_context()->ProduceValue(value);
   2810 }
   2811 
   2812 
   2813 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
   2814   switch (expr->op()) {
   2815     case Token::COMMA:
   2816       return VisitComma(expr);
   2817     case Token::OR:
   2818     case Token::AND:
   2819       return VisitLogicalExpression(expr);
   2820     default: {
   2821       VisitForValue(expr->left());
   2822       VisitForValue(expr->right());
   2823       FrameStateBeforeAndAfter states(this, expr->right()->id());
   2824       Node* right = environment()->Pop();
   2825       Node* left = environment()->Pop();
   2826       Node* value = BuildBinaryOp(left, right, expr->op(),
   2827                                   expr->BinaryOperationFeedbackId());
   2828       states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2829       ast_context()->ProduceValue(value);
   2830     }
   2831   }
   2832 }
   2833 
   2834 
   2835 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
   2836   const Operator* op;
   2837   switch (expr->op()) {
   2838     case Token::EQ:
   2839       op = javascript()->Equal();
   2840       break;
   2841     case Token::NE:
   2842       op = javascript()->NotEqual();
   2843       break;
   2844     case Token::EQ_STRICT:
   2845       op = javascript()->StrictEqual();
   2846       break;
   2847     case Token::NE_STRICT:
   2848       op = javascript()->StrictNotEqual();
   2849       break;
   2850     case Token::LT:
   2851       op = javascript()->LessThan(language_mode());
   2852       break;
   2853     case Token::GT:
   2854       op = javascript()->GreaterThan(language_mode());
   2855       break;
   2856     case Token::LTE:
   2857       op = javascript()->LessThanOrEqual(language_mode());
   2858       break;
   2859     case Token::GTE:
   2860       op = javascript()->GreaterThanOrEqual(language_mode());
   2861       break;
   2862     case Token::INSTANCEOF:
   2863       op = javascript()->InstanceOf();
   2864       break;
   2865     case Token::IN:
   2866       op = javascript()->HasProperty();
   2867       break;
   2868     default:
   2869       op = nullptr;
   2870       UNREACHABLE();
   2871   }
   2872   VisitForValue(expr->left());
   2873   VisitForValue(expr->right());
   2874   FrameStateBeforeAndAfter states(this, expr->right()->id());
   2875   Node* right = environment()->Pop();
   2876   Node* left = environment()->Pop();
   2877   Node* value = NewNode(op, left, right);
   2878   states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   2879   ast_context()->ProduceValue(value);
   2880 }
   2881 
   2882 
   2883 void AstGraphBuilder::VisitSpread(Spread* expr) {
   2884   // Handled entirely by the parser itself.
   2885   UNREACHABLE();
   2886 }
   2887 
   2888 
   2889 void AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) {
   2890   // Handled entirely by the parser itself.
   2891   UNREACHABLE();
   2892 }
   2893 
   2894 
   2895 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
   2896   Node* value = GetFunctionClosure();
   2897   ast_context()->ProduceValue(value);
   2898 }
   2899 
   2900 
   2901 void AstGraphBuilder::VisitSuperPropertyReference(
   2902     SuperPropertyReference* expr) {
   2903   Node* value = BuildThrowUnsupportedSuperError(expr->id());
   2904   ast_context()->ProduceValue(value);
   2905 }
   2906 
   2907 
   2908 void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) {
   2909   // Handled by VisitCall
   2910   UNREACHABLE();
   2911 }
   2912 
   2913 
   2914 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) {
   2915   // Handled entirely in VisitSwitch.
   2916   UNREACHABLE();
   2917 }
   2918 
   2919 
   2920 void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
   2921   DCHECK(globals()->empty());
   2922   AstVisitor::VisitDeclarations(declarations);
   2923   if (globals()->empty()) return;
   2924   int array_index = 0;
   2925   Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
   2926       static_cast<int>(globals()->size()), TENURED);
   2927   for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
   2928   int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
   2929                       DeclareGlobalsNativeFlag::encode(info()->is_native()) |
   2930                       DeclareGlobalsLanguageMode::encode(language_mode());
   2931   Node* flags = jsgraph()->Constant(encoded_flags);
   2932   Node* pairs = jsgraph()->Constant(data);
   2933   const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 2);
   2934   Node* call = NewNode(op, pairs, flags);
   2935   PrepareFrameState(call, BailoutId::Declarations());
   2936   globals()->clear();
   2937 }
   2938 
   2939 
   2940 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
   2941   if (stmt == nullptr) return;
   2942   Visit(stmt);
   2943 }
   2944 
   2945 
   2946 void AstGraphBuilder::VisitInScope(Statement* stmt, Scope* s, Node* context) {
   2947   ContextScope scope(this, s, context);
   2948   DCHECK(s->declarations()->is_empty());
   2949   Visit(stmt);
   2950 }
   2951 
   2952 
   2953 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt,
   2954                                          LoopBuilder* loop) {
   2955   ControlScopeForIteration scope(this, stmt, loop);
   2956   if (FLAG_turbo_loop_stackcheck || !info()->shared_info()->asm_function()) {
   2957     Node* node = NewNode(javascript()->StackCheck());
   2958     PrepareFrameState(node, stmt->StackCheckId());
   2959   }
   2960   Visit(stmt->body());
   2961 }
   2962 
   2963 
   2964 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) {
   2965   Node* value;
   2966   if (expr->expression()->IsVariableProxy()) {
   2967     // Delete of an unqualified identifier is only allowed in classic mode but
   2968     // deleting "this" is allowed in all language modes.
   2969     Variable* variable = expr->expression()->AsVariableProxy()->var();
   2970     // Delete of an unqualified identifier is disallowed in strict mode but
   2971     // "delete this" is allowed.
   2972     DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate()));
   2973     value = BuildVariableDelete(variable, expr->id(),
   2974                                 ast_context()->GetStateCombine());
   2975   } else if (expr->expression()->IsProperty()) {
   2976     Property* property = expr->expression()->AsProperty();
   2977     VisitForValue(property->obj());
   2978     VisitForValue(property->key());
   2979     Node* key = environment()->Pop();
   2980     Node* object = environment()->Pop();
   2981     value = NewNode(javascript()->DeleteProperty(language_mode()), object, key);
   2982     PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   2983   } else {
   2984     VisitForEffect(expr->expression());
   2985     value = jsgraph()->TrueConstant();
   2986   }
   2987   ast_context()->ProduceValue(value);
   2988 }
   2989 
   2990 
   2991 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) {
   2992   VisitForEffect(expr->expression());
   2993   Node* value = jsgraph()->UndefinedConstant();
   2994   ast_context()->ProduceValue(value);
   2995 }
   2996 
   2997 
   2998 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
   2999   Node* operand;
   3000   if (expr->expression()->IsVariableProxy()) {
   3001     // Typeof does not throw a reference error on global variables, hence we
   3002     // perform a non-contextual load in case the operand is a variable proxy.
   3003     VariableProxy* proxy = expr->expression()->AsVariableProxy();
   3004     VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
   3005     FrameStateBeforeAndAfter states(this, BeforeId(proxy));
   3006     operand =
   3007         BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair,
   3008                           OutputFrameStateCombine::Push(), INSIDE_TYPEOF);
   3009   } else {
   3010     VisitForValue(expr->expression());
   3011     operand = environment()->Pop();
   3012   }
   3013   Node* value = NewNode(javascript()->TypeOf(), operand);
   3014   ast_context()->ProduceValue(value);
   3015 }
   3016 
   3017 
   3018 void AstGraphBuilder::VisitNot(UnaryOperation* expr) {
   3019   VisitForValue(expr->expression());
   3020   Node* operand = environment()->Pop();
   3021   Node* input = BuildToBoolean(operand, expr->expression()->test_id());
   3022   Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input,
   3023                         jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   3024   ast_context()->ProduceValue(value);
   3025 }
   3026 
   3027 
   3028 void AstGraphBuilder::VisitComma(BinaryOperation* expr) {
   3029   VisitForEffect(expr->left());
   3030   Visit(expr->right());
   3031   ast_context()->ReplaceValue();
   3032 }
   3033 
   3034 
   3035 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
   3036   bool is_logical_and = expr->op() == Token::AND;
   3037   IfBuilder compare_if(this);
   3038   VisitForValue(expr->left());
   3039   Node* condition = environment()->Top();
   3040   compare_if.If(BuildToBoolean(condition, expr->left()->test_id()));
   3041   compare_if.Then();
   3042   if (is_logical_and) {
   3043     environment()->Pop();
   3044     Visit(expr->right());
   3045   } else if (ast_context()->IsEffect()) {
   3046     environment()->Pop();
   3047   } else if (ast_context()->IsTest()) {
   3048     environment()->Poke(0, jsgraph()->TrueConstant());
   3049   }
   3050   compare_if.Else();
   3051   if (!is_logical_and) {
   3052     environment()->Pop();
   3053     Visit(expr->right());
   3054   } else if (ast_context()->IsEffect()) {
   3055     environment()->Pop();
   3056   } else if (ast_context()->IsTest()) {
   3057     environment()->Poke(0, jsgraph()->FalseConstant());
   3058   }
   3059   compare_if.End();
   3060   ast_context()->ReplaceValue();
   3061 }
   3062 
   3063 
   3064 LanguageMode AstGraphBuilder::language_mode() const {
   3065   return info()->language_mode();
   3066 }
   3067 
   3068 
   3069 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
   3070     FeedbackVectorSlot slot) const {
   3071   return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
   3072 }
   3073 
   3074 
   3075 void AstGraphBuilder::VisitRewritableAssignmentExpression(
   3076     RewritableAssignmentExpression* node) {
   3077   Visit(node->expression());
   3078 }
   3079 
   3080 
   3081 namespace {
   3082 
   3083 // Limit of context chain length to which inline check is possible.
   3084 const int kMaxCheckDepth = 30;
   3085 
   3086 // Sentinel for {TryLoadDynamicVariable} disabling inline checks.
   3087 const uint32_t kFullCheckRequired = -1;
   3088 
   3089 }  // namespace
   3090 
   3091 
   3092 uint32_t AstGraphBuilder::ComputeBitsetForDynamicGlobal(Variable* variable) {
   3093   DCHECK_EQ(DYNAMIC_GLOBAL, variable->mode());
   3094   bool found_eval_scope = false;
   3095   uint32_t check_depths = 0;
   3096   for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
   3097     if (s->num_heap_slots() <= 0) continue;
   3098     // TODO(mstarzinger): If we have reached an eval scope, we check all
   3099     // extensions from this point. Replicated from full-codegen, figure out
   3100     // whether this is still needed. If not, drop {found_eval_scope} below.
   3101     if (s->is_eval_scope()) found_eval_scope = true;
   3102     if (!s->calls_sloppy_eval() && !found_eval_scope) continue;
   3103     int depth = current_scope()->ContextChainLength(s);
   3104     if (depth > kMaxCheckDepth) return kFullCheckRequired;
   3105     check_depths |= 1 << depth;
   3106   }
   3107   return check_depths;
   3108 }
   3109 
   3110 
   3111 uint32_t AstGraphBuilder::ComputeBitsetForDynamicContext(Variable* variable) {
   3112   DCHECK_EQ(DYNAMIC_LOCAL, variable->mode());
   3113   uint32_t check_depths = 0;
   3114   for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
   3115     if (s->num_heap_slots() <= 0) continue;
   3116     if (!s->calls_sloppy_eval() && s != variable->scope()) continue;
   3117     int depth = current_scope()->ContextChainLength(s);
   3118     if (depth > kMaxCheckDepth) return kFullCheckRequired;
   3119     check_depths |= 1 << depth;
   3120     if (s == variable->scope()) break;
   3121   }
   3122   return check_depths;
   3123 }
   3124 
   3125 
   3126 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
   3127   DCHECK(environment()->stack_height() >= arity);
   3128   Node** all = info()->zone()->NewArray<Node*>(arity);
   3129   for (int i = arity - 1; i >= 0; --i) {
   3130     all[i] = environment()->Pop();
   3131   }
   3132   Node* value = NewNode(op, arity, all);
   3133   return value;
   3134 }
   3135 
   3136 
   3137 Node* AstGraphBuilder::BuildLocalActivationContext(Node* context) {
   3138   Scope* scope = info()->scope();
   3139 
   3140   // Allocate a new local context.
   3141   Node* local_context = scope->is_script_scope()
   3142                             ? BuildLocalScriptContext(scope)
   3143                             : BuildLocalFunctionContext(scope);
   3144 
   3145   if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
   3146     Node* receiver = environment()->RawParameterLookup(0);
   3147     // Context variable (at bottom of the context chain).
   3148     Variable* variable = scope->receiver();
   3149     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   3150     const Operator* op = javascript()->StoreContext(0, variable->index());
   3151     NewNode(op, local_context, receiver);
   3152   }
   3153 
   3154   // Copy parameters into context if necessary.
   3155   int num_parameters = scope->num_parameters();
   3156   for (int i = 0; i < num_parameters; i++) {
   3157     Variable* variable = scope->parameter(i);
   3158     if (!variable->IsContextSlot()) continue;
   3159     Node* parameter = environment()->RawParameterLookup(i + 1);
   3160     // Context variable (at bottom of the context chain).
   3161     DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
   3162     const Operator* op = javascript()->StoreContext(0, variable->index());
   3163     NewNode(op, local_context, parameter);
   3164   }
   3165 
   3166   return local_context;
   3167 }
   3168 
   3169 
   3170 Node* AstGraphBuilder::BuildLocalFunctionContext(Scope* scope) {
   3171   DCHECK(scope->is_function_scope());
   3172 
   3173   // Allocate a new local context.
   3174   int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   3175   const Operator* op = javascript()->CreateFunctionContext(slot_count);
   3176   Node* local_context = NewNode(op, GetFunctionClosure());
   3177 
   3178   return local_context;
   3179 }
   3180 
   3181 
   3182 Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) {
   3183   DCHECK(scope->is_script_scope());
   3184 
   3185   // Allocate a new local context.
   3186   Handle<ScopeInfo> scope_info = scope->GetScopeInfo(isolate());
   3187   const Operator* op = javascript()->CreateScriptContext(scope_info);
   3188   Node* local_context = NewNode(op, GetFunctionClosure());
   3189   PrepareFrameState(local_context, BailoutId::ScriptContext(),
   3190                     OutputFrameStateCombine::Push());
   3191 
   3192   return local_context;
   3193 }
   3194 
   3195 
   3196 Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) {
   3197   DCHECK(scope->is_block_scope());
   3198 
   3199   // Allocate a new local context.
   3200   Handle<ScopeInfo> scope_info = scope->GetScopeInfo(isolate());
   3201   const Operator* op = javascript()->CreateBlockContext(scope_info);
   3202   Node* local_context = NewNode(op, GetFunctionClosureForContext());
   3203 
   3204   return local_context;
   3205 }
   3206 
   3207 
   3208 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
   3209   if (arguments == nullptr) return nullptr;
   3210 
   3211   // Allocate and initialize a new arguments object.
   3212   CreateArgumentsParameters::Type type =
   3213       is_strict(language_mode()) || !info()->has_simple_parameters()
   3214           ? CreateArgumentsParameters::kUnmappedArguments
   3215           : CreateArgumentsParameters::kMappedArguments;
   3216   const Operator* op = javascript()->CreateArguments(type, 0);
   3217   Node* object = NewNode(op, GetFunctionClosure());
   3218   PrepareFrameState(object, BailoutId::None());
   3219 
   3220   // Assign the object to the {arguments} variable. This should never lazy
   3221   // deopt, so it is fine to send invalid bailout id.
   3222   DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
   3223   FrameStateBeforeAndAfter states(this, BailoutId::None());
   3224   BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(),
   3225                           BailoutId::None(), states);
   3226   return object;
   3227 }
   3228 
   3229 
   3230 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) {
   3231   if (rest == nullptr) return nullptr;
   3232 
   3233   // Allocate and initialize a new arguments object.
   3234   CreateArgumentsParameters::Type type = CreateArgumentsParameters::kRestArray;
   3235   const Operator* op = javascript()->CreateArguments(type, index);
   3236   Node* object = NewNode(op, GetFunctionClosure());
   3237   PrepareFrameState(object, BailoutId::None());
   3238 
   3239   // Assign the object to the {rest} variable. This should never lazy
   3240   // deopt, so it is fine to send invalid bailout id.
   3241   DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
   3242   FrameStateBeforeAndAfter states(this, BailoutId::None());
   3243   BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(),
   3244                           BailoutId::None(), states);
   3245   return object;
   3246 }
   3247 
   3248 
   3249 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) {
   3250   if (this_function_var == nullptr) return nullptr;
   3251 
   3252   // Retrieve the closure we were called with.
   3253   Node* this_function = GetFunctionClosure();
   3254 
   3255   // Assign the object to the {.this_function} variable. This should never lazy
   3256   // deopt, so it is fine to send invalid bailout id.
   3257   FrameStateBeforeAndAfter states(this, BailoutId::None());
   3258   BuildVariableAssignment(this_function_var, this_function, Token::INIT,
   3259                           VectorSlotPair(), BailoutId::None(), states);
   3260   return this_function;
   3261 }
   3262 
   3263 
   3264 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) {
   3265   if (new_target_var == nullptr) return nullptr;
   3266 
   3267   // Retrieve the new target we were called with.
   3268   Node* object = GetNewTarget();
   3269 
   3270   // Assign the object to the {new.target} variable. This should never lazy
   3271   // deopt, so it is fine to send invalid bailout id.
   3272   FrameStateBeforeAndAfter states(this, BailoutId::None());
   3273   BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(),
   3274                           BailoutId::None(), states);
   3275   return object;
   3276 }
   3277 
   3278 
   3279 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole,
   3280                                             Node* not_hole) {
   3281   Node* the_hole = jsgraph()->TheHoleConstant();
   3282   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
   3283   return NewNode(
   3284       common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
   3285       check, for_hole, not_hole);
   3286 }
   3287 
   3288 
   3289 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable,
   3290                                                Node* not_hole,
   3291                                                BailoutId bailout_id) {
   3292   IfBuilder hole_check(this);
   3293   Node* the_hole = jsgraph()->TheHoleConstant();
   3294   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
   3295   hole_check.If(check);
   3296   hole_check.Then();
   3297   Node* error = BuildThrowReferenceError(variable, bailout_id);
   3298   environment()->Push(error);
   3299   hole_check.Else();
   3300   environment()->Push(not_hole);
   3301   hole_check.End();
   3302   return environment()->Pop();
   3303 }
   3304 
   3305 
   3306 Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable,
   3307                                                Node* for_hole,
   3308                                                BailoutId bailout_id) {
   3309   IfBuilder hole_check(this);
   3310   Node* the_hole = jsgraph()->TheHoleConstant();
   3311   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
   3312   hole_check.If(check);
   3313   hole_check.Then();
   3314   environment()->Push(for_hole);
   3315   hole_check.Else();
   3316   Node* error = BuildThrowReferenceError(variable, bailout_id);
   3317   environment()->Push(error);
   3318   hole_check.End();
   3319   return environment()->Pop();
   3320 }
   3321 
   3322 
   3323 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
   3324                                                    BailoutId bailout_id) {
   3325   IfBuilder prototype_check(this);
   3326   Node* prototype_string =
   3327       jsgraph()->Constant(isolate()->factory()->prototype_string());
   3328   Node* check = NewNode(javascript()->StrictEqual(), name, prototype_string);
   3329   prototype_check.If(check);
   3330   prototype_check.Then();
   3331   Node* error = BuildThrowStaticPrototypeError(bailout_id);
   3332   environment()->Push(error);
   3333   prototype_check.Else();
   3334   environment()->Push(name);
   3335   prototype_check.End();
   3336   return environment()->Pop();
   3337 }
   3338 
   3339 
   3340 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
   3341                                          BailoutId bailout_id,
   3342                                          FrameStateBeforeAndAfter& states,
   3343                                          const VectorSlotPair& feedback,
   3344                                          OutputFrameStateCombine combine,
   3345                                          TypeofMode typeof_mode) {
   3346   Node* the_hole = jsgraph()->TheHoleConstant();
   3347   VariableMode mode = variable->mode();
   3348   switch (variable->location()) {
   3349     case VariableLocation::GLOBAL:
   3350     case VariableLocation::UNALLOCATED: {
   3351       // Global var, const, or let variable.
   3352       Handle<Name> name = variable->name();
   3353       if (Node* node = TryLoadGlobalConstant(name)) return node;
   3354       Node* value = BuildGlobalLoad(name, feedback, typeof_mode);
   3355       states.AddToNode(value, bailout_id, combine);
   3356       return value;
   3357     }
   3358     case VariableLocation::PARAMETER:
   3359     case VariableLocation::LOCAL: {
   3360       // Local var, const, or let variable.
   3361       Node* value = environment()->Lookup(variable);
   3362       if (mode == CONST_LEGACY) {
   3363         // Perform check for uninitialized legacy const variables.
   3364         if (value->op() == the_hole->op()) {
   3365           value = jsgraph()->UndefinedConstant();
   3366         } else if (value->opcode() == IrOpcode::kPhi) {
   3367           Node* undefined = jsgraph()->UndefinedConstant();
   3368           value = BuildHoleCheckSilent(value, undefined, value);
   3369         }
   3370       } else if (mode == LET || mode == CONST) {
   3371         // Perform check for uninitialized let/const variables.
   3372         if (value->op() == the_hole->op()) {
   3373           value = BuildThrowReferenceError(variable, bailout_id);
   3374         } else if (value->opcode() == IrOpcode::kPhi) {
   3375           value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
   3376         }
   3377       }
   3378       return value;
   3379     }
   3380     case VariableLocation::CONTEXT: {
   3381       // Context variable (potentially up the context chain).
   3382       int depth = current_scope()->ContextChainLength(variable->scope());
   3383       bool immutable = variable->maybe_assigned() == kNotAssigned;
   3384       const Operator* op =
   3385           javascript()->LoadContext(depth, variable->index(), immutable);
   3386       Node* value = NewNode(op, current_context());
   3387       // TODO(titzer): initialization checks are redundant for already
   3388       // initialized immutable context loads, but only specialization knows.
   3389       // Maybe specializer should be a parameter to the graph builder?
   3390       if (mode == CONST_LEGACY) {
   3391         // Perform check for uninitialized legacy const variables.
   3392         Node* undefined = jsgraph()->UndefinedConstant();
   3393         value = BuildHoleCheckSilent(value, undefined, value);
   3394       } else if (mode == LET || mode == CONST) {
   3395         // Perform check for uninitialized let/const variables.
   3396         value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
   3397       }
   3398       return value;
   3399     }
   3400     case VariableLocation::LOOKUP: {
   3401       // Dynamic lookup of context variable (anywhere in the chain).
   3402       Handle<String> name = variable->name();
   3403       if (Node* node =
   3404               TryLoadDynamicVariable(variable, name, bailout_id, states,
   3405                                      feedback, combine, typeof_mode)) {
   3406         return node;
   3407       }
   3408       const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
   3409       Node* value = NewNode(op, BuildLoadFeedbackVector(), current_context());
   3410       states.AddToNode(value, bailout_id, combine);
   3411       return value;
   3412     }
   3413   }
   3414   UNREACHABLE();
   3415   return nullptr;
   3416 }
   3417 
   3418 
   3419 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
   3420                                            BailoutId bailout_id,
   3421                                            OutputFrameStateCombine combine) {
   3422   switch (variable->location()) {
   3423     case VariableLocation::GLOBAL:
   3424     case VariableLocation::UNALLOCATED: {
   3425       // Global var, const, or let variable.
   3426       Node* global = BuildLoadGlobalObject();
   3427       Node* name = jsgraph()->Constant(variable->name());
   3428       const Operator* op = javascript()->DeleteProperty(language_mode());
   3429       Node* result = NewNode(op, global, name);
   3430       PrepareFrameState(result, bailout_id, combine);
   3431       return result;
   3432     }
   3433     case VariableLocation::PARAMETER:
   3434     case VariableLocation::LOCAL:
   3435     case VariableLocation::CONTEXT: {
   3436       // Local var, const, or let variable or context variable.
   3437       return jsgraph()->BooleanConstant(variable->HasThisName(isolate()));
   3438     }
   3439     case VariableLocation::LOOKUP: {
   3440       // Dynamic lookup of context variable (anywhere in the chain).
   3441       Node* name = jsgraph()->Constant(variable->name());
   3442       const Operator* op =
   3443           javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
   3444       Node* result = NewNode(op, current_context(), name);
   3445       PrepareFrameState(result, bailout_id, combine);
   3446       return result;
   3447     }
   3448   }
   3449   UNREACHABLE();
   3450   return nullptr;
   3451 }
   3452 
   3453 
   3454 Node* AstGraphBuilder::BuildVariableAssignment(
   3455     Variable* variable, Node* value, Token::Value op,
   3456     const VectorSlotPair& feedback, BailoutId bailout_id,
   3457     FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) {
   3458   Node* the_hole = jsgraph()->TheHoleConstant();
   3459   VariableMode mode = variable->mode();
   3460   switch (variable->location()) {
   3461     case VariableLocation::GLOBAL:
   3462     case VariableLocation::UNALLOCATED: {
   3463       // Global var, const, or let variable.
   3464       Handle<Name> name = variable->name();
   3465       Node* store = BuildGlobalStore(name, value, feedback);
   3466       states.AddToNode(store, bailout_id, combine);
   3467       return store;
   3468     }
   3469     case VariableLocation::PARAMETER:
   3470     case VariableLocation::LOCAL:
   3471       // Local var, const, or let variable.
   3472       if (mode == CONST_LEGACY && op == Token::INIT) {
   3473         // Perform an initialization check for legacy const variables.
   3474         Node* current = environment()->Lookup(variable);
   3475         if (current->op() != the_hole->op()) {
   3476           value = BuildHoleCheckSilent(current, value, current);
   3477         }
   3478       } else if (mode == CONST_LEGACY && op != Token::INIT) {
   3479         // Non-initializing assignment to legacy const is
   3480         // - exception in strict mode.
   3481         // - ignored in sloppy mode.
   3482         if (is_strict(language_mode())) {
   3483           return BuildThrowConstAssignError(bailout_id);
   3484         }
   3485         return value;
   3486       } else if (mode == LET && op == Token::INIT) {
   3487         // No initialization check needed because scoping guarantees it. Note
   3488         // that we still perform a lookup to keep the variable live, because
   3489         // baseline code might contain debug code that inspects the variable.
   3490         Node* current = environment()->Lookup(variable);
   3491         CHECK_NOT_NULL(current);
   3492       } else if (mode == LET && op != Token::INIT) {
   3493         // Perform an initialization check for let declared variables.
   3494         Node* current = environment()->Lookup(variable);
   3495         if (current->op() == the_hole->op()) {
   3496           return BuildThrowReferenceError(variable, bailout_id);
   3497         } else if (current->opcode() == IrOpcode::kPhi) {
   3498           BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3499         }
   3500       } else if (mode == CONST && op == Token::INIT) {
   3501         // Perform an initialization check for const {this} variables.
   3502         // Note that the {this} variable is the only const variable being able
   3503         // to trigger bind operations outside the TDZ, via {super} calls.
   3504         Node* current = environment()->Lookup(variable);
   3505         if (current->op() != the_hole->op() && variable->is_this()) {
   3506           value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
   3507         }
   3508       } else if (mode == CONST && op != Token::INIT) {
   3509         // Assignment to const is exception in all modes.
   3510         Node* current = environment()->Lookup(variable);
   3511         if (current->op() == the_hole->op()) {
   3512           return BuildThrowReferenceError(variable, bailout_id);
   3513         } else if (current->opcode() == IrOpcode::kPhi) {
   3514           BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3515         }
   3516         return BuildThrowConstAssignError(bailout_id);
   3517       }
   3518       environment()->Bind(variable, value);
   3519       return value;
   3520     case VariableLocation::CONTEXT: {
   3521       // Context variable (potentially up the context chain).
   3522       int depth = current_scope()->ContextChainLength(variable->scope());
   3523       if (mode == CONST_LEGACY && op == Token::INIT) {
   3524         // Perform an initialization check for legacy const variables.
   3525         const Operator* op =
   3526             javascript()->LoadContext(depth, variable->index(), false);
   3527         Node* current = NewNode(op, current_context());
   3528         value = BuildHoleCheckSilent(current, value, current);
   3529       } else if (mode == CONST_LEGACY && op != Token::INIT) {
   3530         // Non-initializing assignment to legacy const is
   3531         // - exception in strict mode.
   3532         // - ignored in sloppy mode.
   3533         if (is_strict(language_mode())) {
   3534           return BuildThrowConstAssignError(bailout_id);
   3535         }
   3536         return value;
   3537       } else if (mode == LET && op != Token::INIT) {
   3538         // Perform an initialization check for let declared variables.
   3539         const Operator* op =
   3540             javascript()->LoadContext(depth, variable->index(), false);
   3541         Node* current = NewNode(op, current_context());
   3542         value = BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3543       } else if (mode == CONST && op == Token::INIT) {
   3544         // Perform an initialization check for const {this} variables.
   3545         // Note that the {this} variable is the only const variable being able
   3546         // to trigger bind operations outside the TDZ, via {super} calls.
   3547         if (variable->is_this()) {
   3548           const Operator* op =
   3549               javascript()->LoadContext(depth, variable->index(), false);
   3550           Node* current = NewNode(op, current_context());
   3551           value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
   3552         }
   3553       } else if (mode == CONST && op != Token::INIT) {
   3554         // Assignment to const is exception in all modes.
   3555         const Operator* op =
   3556             javascript()->LoadContext(depth, variable->index(), false);
   3557         Node* current = NewNode(op, current_context());
   3558         BuildHoleCheckThenThrow(current, variable, value, bailout_id);
   3559         return BuildThrowConstAssignError(bailout_id);
   3560       }
   3561       const Operator* op = javascript()->StoreContext(depth, variable->index());
   3562       return NewNode(op, current_context(), value);
   3563     }
   3564     case VariableLocation::LOOKUP: {
   3565       // Dynamic lookup of context variable (anywhere in the chain).
   3566       Node* name = jsgraph()->Constant(variable->name());
   3567       Node* language = jsgraph()->Constant(language_mode());
   3568       // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
   3569       // initializations of const declarations.
   3570       const Operator* op =
   3571           javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
   3572       Node* store = NewNode(op, value, current_context(), name, language);
   3573       PrepareFrameState(store, bailout_id, combine);
   3574       return store;
   3575     }
   3576   }
   3577   UNREACHABLE();
   3578   return nullptr;
   3579 }
   3580 
   3581 
   3582 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
   3583                                       const VectorSlotPair& feedback) {
   3584   const Operator* op = javascript()->LoadProperty(language_mode(), feedback);
   3585   Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
   3586   return node;
   3587 }
   3588 
   3589 
   3590 Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
   3591                                       const VectorSlotPair& feedback) {
   3592   const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback);
   3593   Node* node = NewNode(op, object, BuildLoadFeedbackVector());
   3594   return node;
   3595 }
   3596 
   3597 
   3598 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
   3599                                        const VectorSlotPair& feedback) {
   3600   const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
   3601   Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector());
   3602   return node;
   3603 }
   3604 
   3605 
   3606 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
   3607                                        Node* value,
   3608                                        const VectorSlotPair& feedback) {
   3609   const Operator* op =
   3610       javascript()->StoreNamed(language_mode(), name, feedback);
   3611   Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
   3612   return node;
   3613 }
   3614 
   3615 
   3616 Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object,
   3617                                            Handle<Name> name,
   3618                                            const VectorSlotPair& feedback) {
   3619   Node* name_node = jsgraph()->Constant(name);
   3620   Node* language = jsgraph()->Constant(language_mode());
   3621   const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 4);
   3622   Node* node = NewNode(op, receiver, home_object, name_node, language);
   3623   return node;
   3624 }
   3625 
   3626 
   3627 Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
   3628                                            Node* key,
   3629                                            const VectorSlotPair& feedback) {
   3630   Node* language = jsgraph()->Constant(language_mode());
   3631   const Operator* op =
   3632       javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
   3633   Node* node = NewNode(op, receiver, home_object, key, language);
   3634   return node;
   3635 }
   3636 
   3637 
   3638 Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object,
   3639                                             Node* key, Node* value) {
   3640   Runtime::FunctionId function_id = is_strict(language_mode())
   3641                                         ? Runtime::kStoreKeyedToSuper_Strict
   3642                                         : Runtime::kStoreKeyedToSuper_Sloppy;
   3643   const Operator* op = javascript()->CallRuntime(function_id, 4);
   3644   Node* node = NewNode(op, receiver, home_object, key, value);
   3645   return node;
   3646 }
   3647 
   3648 
   3649 Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
   3650                                             Handle<Name> name, Node* value) {
   3651   Node* name_node = jsgraph()->Constant(name);
   3652   Runtime::FunctionId function_id = is_strict(language_mode())
   3653                                         ? Runtime::kStoreToSuper_Strict
   3654                                         : Runtime::kStoreToSuper_Sloppy;
   3655   const Operator* op = javascript()->CallRuntime(function_id, 4);
   3656   Node* node = NewNode(op, receiver, home_object, name_node, value);
   3657   return node;
   3658 }
   3659 
   3660 
   3661 Node* AstGraphBuilder::BuildGlobalLoad(Handle<Name> name,
   3662                                        const VectorSlotPair& feedback,
   3663                                        TypeofMode typeof_mode) {
   3664   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
   3665   Node* node = NewNode(op, BuildLoadFeedbackVector());
   3666   return node;
   3667 }
   3668 
   3669 
   3670 Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value,
   3671                                         const VectorSlotPair& feedback) {
   3672   const Operator* op =
   3673       javascript()->StoreGlobal(language_mode(), name, feedback);
   3674   Node* node = NewNode(op, value, BuildLoadFeedbackVector());
   3675   return node;
   3676 }
   3677 
   3678 
   3679 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
   3680   return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
   3681                  jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
   3682 }
   3683 
   3684 
   3685 Node* AstGraphBuilder::BuildLoadImmutableObjectField(Node* object, int offset) {
   3686   return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()),
   3687                           object,
   3688                           jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
   3689                           graph()->start(), graph()->start());
   3690 }
   3691 
   3692 
   3693 Node* AstGraphBuilder::BuildLoadGlobalObject() {
   3694   return BuildLoadNativeContextField(Context::EXTENSION_INDEX);
   3695 }
   3696 
   3697 
   3698 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) {
   3699   const Operator* op =
   3700       javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
   3701   Node* native_context = NewNode(op, current_context());
   3702   return NewNode(javascript()->LoadContext(0, index, true), native_context);
   3703 }
   3704 
   3705 
   3706 Node* AstGraphBuilder::BuildLoadFeedbackVector() {
   3707   if (!feedback_vector_.is_set()) {
   3708     Node* closure = GetFunctionClosure();
   3709     Node* shared = BuildLoadImmutableObjectField(
   3710         closure, JSFunction::kSharedFunctionInfoOffset);
   3711     Node* vector = BuildLoadImmutableObjectField(
   3712         shared, SharedFunctionInfo::kFeedbackVectorOffset);
   3713     feedback_vector_.set(vector);
   3714   }
   3715   return feedback_vector_.get();
   3716 }
   3717 
   3718 
   3719 Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) {
   3720   if (Node* node = TryFastToBoolean(input)) return node;
   3721   ToBooleanHints hints;
   3722   if (!type_hint_analysis_ ||
   3723       !type_hint_analysis_->GetToBooleanHints(feedback_id, &hints)) {
   3724     hints = ToBooleanHint::kAny;
   3725   }
   3726   return NewNode(javascript()->ToBoolean(hints), input);
   3727 }
   3728 
   3729 
   3730 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) {
   3731   if (Node* node = TryFastToName(input)) return node;
   3732   Node* name = NewNode(javascript()->ToName(), input);
   3733   PrepareFrameState(name, bailout_id);
   3734   return name;
   3735 }
   3736 
   3737 
   3738 Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) {
   3739   Node* object = NewNode(javascript()->ToObject(), input);
   3740   PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push());
   3741   return object;
   3742 }
   3743 
   3744 
   3745 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
   3746                                           ObjectLiteralProperty* property,
   3747                                           int slot_number) {
   3748   Expression* expr = property->value();
   3749   if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
   3750   Handle<Name> name = isolate()->factory()->home_object_symbol();
   3751   FrameStateBeforeAndAfter states(this, BailoutId::None());
   3752   VectorSlotPair feedback =
   3753       CreateVectorSlotPair(property->GetSlot(slot_number));
   3754   Node* store = BuildNamedStore(value, name, home_object, feedback);
   3755   states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore());
   3756   return store;
   3757 }
   3758 
   3759 
   3760 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) {
   3761   const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1);
   3762   Node* call = NewNode(op, exception);
   3763   PrepareFrameState(call, bailout_id);
   3764   Node* control = NewNode(common()->Throw(), call);
   3765   UpdateControlDependencyToLeaveFunction(control);
   3766   return call;
   3767 }
   3768 
   3769 
   3770 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
   3771                                                 BailoutId bailout_id) {
   3772   Node* variable_name = jsgraph()->Constant(variable->name());
   3773   const Operator* op =
   3774       javascript()->CallRuntime(Runtime::kThrowReferenceError, 1);
   3775   Node* call = NewNode(op, variable_name);
   3776   PrepareFrameState(call, bailout_id);
   3777   Node* control = NewNode(common()->Throw(), call);
   3778   UpdateControlDependencyToLeaveFunction(control);
   3779   return call;
   3780 }
   3781 
   3782 
   3783 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
   3784   const Operator* op =
   3785       javascript()->CallRuntime(Runtime::kThrowConstAssignError, 0);
   3786   Node* call = NewNode(op);
   3787   PrepareFrameState(call, bailout_id);
   3788   Node* control = NewNode(common()->Throw(), call);
   3789   UpdateControlDependencyToLeaveFunction(control);
   3790   return call;
   3791 }
   3792 
   3793 
   3794 Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) {
   3795   const Operator* op =
   3796       javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError, 0);
   3797   Node* call = NewNode(op);
   3798   PrepareFrameState(call, bailout_id);
   3799   Node* control = NewNode(common()->Throw(), call);
   3800   UpdateControlDependencyToLeaveFunction(control);
   3801   return call;
   3802 }
   3803 
   3804 
   3805 Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) {
   3806   const Operator* op =
   3807       javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
   3808   Node* call = NewNode(op);
   3809   PrepareFrameState(call, bailout_id);
   3810   Node* control = NewNode(common()->Throw(), call);
   3811   UpdateControlDependencyToLeaveFunction(control);
   3812   return call;
   3813 }
   3814 
   3815 
   3816 Node* AstGraphBuilder::BuildReturn(Node* return_value) {
   3817   Node* control = NewNode(common()->Return(), return_value);
   3818   UpdateControlDependencyToLeaveFunction(control);
   3819   return control;
   3820 }
   3821 
   3822 
   3823 Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
   3824   NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value);
   3825   Node* control = NewNode(common()->Throw(), exception_value);
   3826   UpdateControlDependencyToLeaveFunction(control);
   3827   return control;
   3828 }
   3829 
   3830 
   3831 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op,
   3832                                      TypeFeedbackId feedback_id) {
   3833   const Operator* js_op;
   3834   BinaryOperationHints hints;
   3835   if (!type_hint_analysis_ ||
   3836       !type_hint_analysis_->GetBinaryOperationHints(feedback_id, &hints)) {
   3837     hints = BinaryOperationHints::Any();
   3838   }
   3839   switch (op) {
   3840     case Token::BIT_OR:
   3841       js_op = javascript()->BitwiseOr(language_mode(), hints);
   3842       break;
   3843     case Token::BIT_AND:
   3844       js_op = javascript()->BitwiseAnd(language_mode(), hints);
   3845       break;
   3846     case Token::BIT_XOR:
   3847       js_op = javascript()->BitwiseXor(language_mode(), hints);
   3848       break;
   3849     case Token::SHL:
   3850       js_op = javascript()->ShiftLeft(language_mode(), hints);
   3851       break;
   3852     case Token::SAR:
   3853       js_op = javascript()->ShiftRight(language_mode(), hints);
   3854       break;
   3855     case Token::SHR:
   3856       js_op = javascript()->ShiftRightLogical(language_mode(), hints);
   3857       break;
   3858     case Token::ADD:
   3859       js_op = javascript()->Add(language_mode(), hints);
   3860       break;
   3861     case Token::SUB:
   3862       js_op = javascript()->Subtract(language_mode(), hints);
   3863       break;
   3864     case Token::MUL:
   3865       js_op = javascript()->Multiply(language_mode(), hints);
   3866       break;
   3867     case Token::DIV:
   3868       js_op = javascript()->Divide(language_mode(), hints);
   3869       break;
   3870     case Token::MOD:
   3871       js_op = javascript()->Modulus(language_mode(), hints);
   3872       break;
   3873     default:
   3874       UNREACHABLE();
   3875       js_op = nullptr;
   3876   }
   3877   return NewNode(js_op, left, right);
   3878 }
   3879 
   3880 
   3881 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) {
   3882   // Optimize global constants like "undefined", "Infinity", and "NaN".
   3883   Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name);
   3884   if (!constant_value.is_null()) return jsgraph()->Constant(constant_value);
   3885   return nullptr;
   3886 }
   3887 
   3888 
   3889 Node* AstGraphBuilder::TryLoadDynamicVariable(
   3890     Variable* variable, Handle<String> name, BailoutId bailout_id,
   3891     FrameStateBeforeAndAfter& states, const VectorSlotPair& feedback,
   3892     OutputFrameStateCombine combine, TypeofMode typeof_mode) {
   3893   VariableMode mode = variable->mode();
   3894 
   3895   if (mode == DYNAMIC_GLOBAL) {
   3896     uint32_t bitset = ComputeBitsetForDynamicGlobal(variable);
   3897     if (bitset == kFullCheckRequired) return nullptr;
   3898 
   3899     // We are using two blocks to model fast and slow cases.
   3900     BlockBuilder fast_block(this);
   3901     BlockBuilder slow_block(this);
   3902     environment()->Push(jsgraph()->TheHoleConstant());
   3903     slow_block.BeginBlock();
   3904     environment()->Pop();
   3905     fast_block.BeginBlock();
   3906 
   3907     // Perform checks whether the fast mode applies, by looking for any
   3908     // extension object which might shadow the optimistic declaration.
   3909     for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
   3910       if ((bitset & 1) == 0) continue;
   3911       Node* load = NewNode(
   3912           javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
   3913           current_context());
   3914       Node* check = NewNode(javascript()->StrictEqual(), load,
   3915                             jsgraph()->TheHoleConstant());
   3916       fast_block.BreakUnless(check, BranchHint::kTrue);
   3917     }
   3918 
   3919     // Fast case, because variable is not shadowed. Perform global slot load.
   3920     Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
   3921     states.AddToNode(fast, bailout_id, combine);
   3922     environment()->Push(fast);
   3923     slow_block.Break();
   3924     environment()->Pop();
   3925     fast_block.EndBlock();
   3926 
   3927     // Slow case, because variable potentially shadowed. Perform dynamic lookup.
   3928     const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
   3929     Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
   3930     states.AddToNode(slow, bailout_id, combine);
   3931     environment()->Push(slow);
   3932     slow_block.EndBlock();
   3933 
   3934     return environment()->Pop();
   3935   }
   3936 
   3937   if (mode == DYNAMIC_LOCAL) {
   3938     uint32_t bitset = ComputeBitsetForDynamicContext(variable);
   3939     if (bitset == kFullCheckRequired) return nullptr;
   3940 
   3941     // We are using two blocks to model fast and slow cases.
   3942     BlockBuilder fast_block(this);
   3943     BlockBuilder slow_block(this);
   3944     environment()->Push(jsgraph()->TheHoleConstant());
   3945     slow_block.BeginBlock();
   3946     environment()->Pop();
   3947     fast_block.BeginBlock();
   3948 
   3949     // Perform checks whether the fast mode applies, by looking for any
   3950     // extension object which might shadow the optimistic declaration.
   3951     for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
   3952       if ((bitset & 1) == 0) continue;
   3953       Node* load = NewNode(
   3954           javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
   3955           current_context());
   3956       Node* check = NewNode(javascript()->StrictEqual(), load,
   3957                             jsgraph()->TheHoleConstant());
   3958       fast_block.BreakUnless(check, BranchHint::kTrue);
   3959     }
   3960 
   3961     // Fast case, because variable is not shadowed. Perform context slot load.
   3962     Variable* local = variable->local_if_not_shadowed();
   3963     DCHECK(local->location() == VariableLocation::CONTEXT);  // Must be context.
   3964     Node* fast = BuildVariableLoad(local, bailout_id, states, feedback, combine,
   3965                                    typeof_mode);
   3966     environment()->Push(fast);
   3967     slow_block.Break();
   3968     environment()->Pop();
   3969     fast_block.EndBlock();
   3970 
   3971     // Slow case, because variable potentially shadowed. Perform dynamic lookup.
   3972     const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
   3973     Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
   3974     states.AddToNode(slow, bailout_id, combine);
   3975     environment()->Push(slow);
   3976     slow_block.EndBlock();
   3977 
   3978     return environment()->Pop();
   3979   }
   3980 
   3981   return nullptr;
   3982 }
   3983 
   3984 
   3985 Node* AstGraphBuilder::TryFastToBoolean(Node* input) {
   3986   switch (input->opcode()) {
   3987     case IrOpcode::kNumberConstant: {
   3988       NumberMatcher m(input);
   3989       return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN());
   3990     }
   3991     case IrOpcode::kHeapConstant: {
   3992       Handle<HeapObject> object = HeapObjectMatcher(input).Value();
   3993       return jsgraph_->BooleanConstant(object->BooleanValue());
   3994     }
   3995     case IrOpcode::kJSEqual:
   3996     case IrOpcode::kJSNotEqual:
   3997     case IrOpcode::kJSStrictEqual:
   3998     case IrOpcode::kJSStrictNotEqual:
   3999     case IrOpcode::kJSLessThan:
   4000     case IrOpcode::kJSLessThanOrEqual:
   4001     case IrOpcode::kJSGreaterThan:
   4002     case IrOpcode::kJSGreaterThanOrEqual:
   4003     case IrOpcode::kJSToBoolean:
   4004     case IrOpcode::kJSDeleteProperty:
   4005     case IrOpcode::kJSHasProperty:
   4006     case IrOpcode::kJSInstanceOf:
   4007       return input;
   4008     default:
   4009       break;
   4010   }
   4011   return nullptr;
   4012 }
   4013 
   4014 
   4015 Node* AstGraphBuilder::TryFastToName(Node* input) {
   4016   switch (input->opcode()) {
   4017     case IrOpcode::kHeapConstant: {
   4018       Handle<HeapObject> object = HeapObjectMatcher(input).Value();
   4019       if (object->IsName()) return input;
   4020       break;
   4021     }
   4022     case IrOpcode::kJSToString:
   4023     case IrOpcode::kJSToName:
   4024     case IrOpcode::kJSTypeOf:
   4025       return input;
   4026     default:
   4027       break;
   4028   }
   4029   return nullptr;
   4030 }
   4031 
   4032 
   4033 bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
   4034   if (info()->osr_ast_id() == stmt->OsrEntryId()) {
   4035     info()->set_osr_expr_stack_height(std::max(
   4036         environment()->stack_height(), info()->osr_expr_stack_height()));
   4037     return true;
   4038   }
   4039   return false;
   4040 }
   4041 
   4042 
   4043 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
   4044                                         OutputFrameStateCombine combine) {
   4045   if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
   4046     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
   4047 
   4048     DCHECK_EQ(IrOpcode::kDead,
   4049               NodeProperties::GetFrameStateInput(node, 0)->opcode());
   4050     NodeProperties::ReplaceFrameStateInput(
   4051         node, 0, environment()->Checkpoint(ast_id, combine));
   4052   }
   4053 }
   4054 
   4055 
   4056 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
   4057     IterationStatement* stmt) {
   4058   if (loop_assignment_analysis_ == nullptr) return nullptr;
   4059   return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
   4060 }
   4061 
   4062 
   4063 Node** AstGraphBuilder::EnsureInputBufferSize(int size) {
   4064   if (size > input_buffer_size_) {
   4065     size = size + kInputBufferSizeIncrement + input_buffer_size_;
   4066     input_buffer_ = local_zone()->NewArray<Node*>(size);
   4067     input_buffer_size_ = size;
   4068   }
   4069   return input_buffer_;
   4070 }
   4071 
   4072 
   4073 Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
   4074                                 Node** value_inputs, bool incomplete) {
   4075   DCHECK_EQ(op->ValueInputCount(), value_input_count);
   4076 
   4077   bool has_context = OperatorProperties::HasContextInput(op);
   4078   int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
   4079   bool has_control = op->ControlInputCount() == 1;
   4080   bool has_effect = op->EffectInputCount() == 1;
   4081 
   4082   DCHECK(op->ControlInputCount() < 2);
   4083   DCHECK(op->EffectInputCount() < 2);
   4084 
   4085   Node* result = nullptr;
   4086   if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
   4087     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   4088   } else {
   4089     bool inside_try_scope = try_nesting_level_ > 0;
   4090     int input_count_with_deps = value_input_count;
   4091     if (has_context) ++input_count_with_deps;
   4092     input_count_with_deps += frame_state_count;
   4093     if (has_control) ++input_count_with_deps;
   4094     if (has_effect) ++input_count_with_deps;
   4095     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
   4096     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
   4097     Node** current_input = buffer + value_input_count;
   4098     if (has_context) {
   4099       *current_input++ = current_context();
   4100     }
   4101     for (int i = 0; i < frame_state_count; i++) {
   4102       // The frame state will be inserted later. Here we misuse
   4103       // the {Dead} node as a sentinel to be later overwritten
   4104       // with the real frame state.
   4105       *current_input++ = jsgraph()->Dead();
   4106     }
   4107     if (has_effect) {
   4108       *current_input++ = environment_->GetEffectDependency();
   4109     }
   4110     if (has_control) {
   4111       *current_input++ = environment_->GetControlDependency();
   4112     }
   4113     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
   4114     if (!environment()->IsMarkedAsUnreachable()) {
   4115       // Update the current control dependency for control-producing nodes.
   4116       if (NodeProperties::IsControl(result)) {
   4117         environment_->UpdateControlDependency(result);
   4118       }
   4119       // Update the current effect dependency for effect-producing nodes.
   4120       if (result->op()->EffectOutputCount() > 0) {
   4121         environment_->UpdateEffectDependency(result);
   4122       }
   4123       // Add implicit exception continuation for throwing nodes.
   4124       if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
   4125         // Conservative prediction whether caught locally.
   4126         IfExceptionHint hint = try_catch_nesting_level_ > 0
   4127                                    ? IfExceptionHint::kLocallyCaught
   4128                                    : IfExceptionHint::kLocallyUncaught;
   4129         // Copy the environment for the success continuation.
   4130         Environment* success_env = environment()->CopyForConditional();
   4131         const Operator* op = common()->IfException(hint);
   4132         Node* effect = environment()->GetEffectDependency();
   4133         Node* on_exception = graph()->NewNode(op, effect, result);
   4134         environment_->UpdateControlDependency(on_exception);
   4135         environment_->UpdateEffectDependency(on_exception);
   4136         execution_control()->ThrowValue(on_exception);
   4137         set_environment(success_env);
   4138       }
   4139       // Add implicit success continuation for throwing nodes.
   4140       if (!result->op()->HasProperty(Operator::kNoThrow)) {
   4141         const Operator* op = common()->IfSuccess();
   4142         Node* on_success = graph()->NewNode(op, result);
   4143         environment_->UpdateControlDependency(on_success);
   4144       }
   4145     }
   4146   }
   4147 
   4148   return result;
   4149 }
   4150 
   4151 
   4152 void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
   4153   if (environment()->IsMarkedAsUnreachable()) return;
   4154   environment()->MarkAsUnreachable();
   4155   exit_controls_.push_back(exit);
   4156 }
   4157 
   4158 
   4159 void AstGraphBuilder::Environment::Merge(Environment* other) {
   4160   DCHECK(values_.size() == other->values_.size());
   4161   DCHECK(contexts_.size() == other->contexts_.size());
   4162 
   4163   // Nothing to do if the other environment is dead.
   4164   if (other->IsMarkedAsUnreachable()) return;
   4165 
   4166   // Resurrect a dead environment by copying the contents of the other one and
   4167   // placing a singleton merge as the new control dependency.
   4168   if (this->IsMarkedAsUnreachable()) {
   4169     Node* other_control = other->control_dependency_;
   4170     Node* inputs[] = {other_control};
   4171     control_dependency_ =
   4172         graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
   4173     effect_dependency_ = other->effect_dependency_;
   4174     values_ = other->values_;
   4175     contexts_ = other->contexts_;
   4176     if (IsLivenessAnalysisEnabled()) {
   4177       liveness_block_ =
   4178           builder_->liveness_analyzer()->NewBlock(other->liveness_block());
   4179     }
   4180     return;
   4181   }
   4182 
   4183   // Record the merge for the local variable liveness calculation.
   4184   // For loops, we are connecting a back edge into the existing block;
   4185   // for merges, we create a new merged block.
   4186   if (IsLivenessAnalysisEnabled()) {
   4187     if (GetControlDependency()->opcode() != IrOpcode::kLoop) {
   4188       liveness_block_ =
   4189           builder_->liveness_analyzer()->NewBlock(liveness_block());
   4190     }
   4191     liveness_block()->AddPredecessor(other->liveness_block());
   4192   }
   4193 
   4194   // Create a merge of the control dependencies of both environments and update
   4195   // the current environment's control dependency accordingly.
   4196   Node* control = builder_->MergeControl(this->GetControlDependency(),
   4197                                          other->GetControlDependency());
   4198   UpdateControlDependency(control);
   4199 
   4200   // Create a merge of the effect dependencies of both environments and update
   4201   // the current environment's effect dependency accordingly.
   4202   Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
   4203                                        other->GetEffectDependency(), control);
   4204   UpdateEffectDependency(effect);
   4205 
   4206   // Introduce Phi nodes for values that have differing input at merge points,
   4207   // potentially extending an existing Phi node if possible.
   4208   for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
   4209     values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
   4210   }
   4211   for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) {
   4212     contexts_[i] =
   4213         builder_->MergeValue(contexts_[i], other->contexts_[i], control);
   4214   }
   4215 }
   4216 
   4217 
   4218 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
   4219                                                   bool is_osr) {
   4220   int size = static_cast<int>(values()->size());
   4221 
   4222   Node* control = builder_->NewLoop();
   4223   if (assigned == nullptr) {
   4224     // Assume that everything is updated in the loop.
   4225     for (int i = 0; i < size; ++i) {
   4226       values()->at(i) = builder_->NewPhi(1, values()->at(i), control);
   4227     }
   4228   } else {
   4229     // Only build phis for those locals assigned in this loop.
   4230     for (int i = 0; i < size; ++i) {
   4231       if (i < assigned->length() && !assigned->Contains(i)) continue;
   4232       Node* phi = builder_->NewPhi(1, values()->at(i), control);
   4233       values()->at(i) = phi;
   4234     }
   4235   }
   4236   Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
   4237   UpdateEffectDependency(effect);
   4238 
   4239   // Connect the loop to end via Terminate if it's not marked as unreachable.
   4240   if (!IsMarkedAsUnreachable()) {
   4241     // Connect the Loop node to end via a Terminate node.
   4242     Node* terminate = builder_->graph()->NewNode(
   4243         builder_->common()->Terminate(), effect, control);
   4244     builder_->exit_controls_.push_back(terminate);
   4245   }
   4246 
   4247   if (builder_->info()->is_osr()) {
   4248     // Introduce phis for all context values in the case of an OSR graph.
   4249     for (size_t i = 0; i < contexts()->size(); ++i) {
   4250       Node* context = contexts()->at(i);
   4251       contexts()->at(i) = builder_->NewPhi(1, context, control);
   4252     }
   4253   }
   4254 
   4255   if (is_osr) {
   4256     // Merge OSR values as inputs to the phis of the loop.
   4257     Graph* graph = builder_->graph();
   4258     Node* osr_loop_entry = builder_->graph()->NewNode(
   4259         builder_->common()->OsrLoopEntry(), graph->start(), graph->start());
   4260 
   4261     builder_->MergeControl(control, osr_loop_entry);
   4262     builder_->MergeEffect(effect, osr_loop_entry, control);
   4263 
   4264     for (int i = 0; i < size; ++i) {
   4265       Node* value = values()->at(i);
   4266       Node* osr_value =
   4267           graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
   4268       values()->at(i) = builder_->MergeValue(value, osr_value, control);
   4269     }
   4270 
   4271     // Rename all the contexts in the environment.
   4272     // The innermost context is the OSR value, and the outer contexts are
   4273     // reconstructed by dynamically walking up the context chain.
   4274     Node* osr_context = nullptr;
   4275     const Operator* op =
   4276         builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
   4277     const Operator* op_inner =
   4278         builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex);
   4279     int last = static_cast<int>(contexts()->size() - 1);
   4280     for (int i = last; i >= 0; i--) {
   4281       Node* context = contexts()->at(i);
   4282       osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry)
   4283                                 : graph->NewNode(op, osr_context, osr_context,
   4284                                                  osr_loop_entry);
   4285       contexts()->at(i) = builder_->MergeValue(context, osr_context, control);
   4286     }
   4287   }
   4288 }
   4289 
   4290 
   4291 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) {
   4292   const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
   4293   Node** buffer = EnsureInputBufferSize(count + 1);
   4294   MemsetPointer(buffer, input, count);
   4295   buffer[count] = control;
   4296   return graph()->NewNode(phi_op, count + 1, buffer, true);
   4297 }
   4298 
   4299 
   4300 // TODO(mstarzinger): Revisit this once we have proper effect states.
   4301 Node* AstGraphBuilder::NewEffectPhi(int count, Node* input, Node* control) {
   4302   const Operator* phi_op = common()->EffectPhi(count);
   4303   Node** buffer = EnsureInputBufferSize(count + 1);
   4304   MemsetPointer(buffer, input, count);
   4305   buffer[count] = control;
   4306   return graph()->NewNode(phi_op, count + 1, buffer, true);
   4307 }
   4308 
   4309 
   4310 Node* AstGraphBuilder::MergeControl(Node* control, Node* other) {
   4311   int inputs = control->op()->ControlInputCount() + 1;
   4312   if (control->opcode() == IrOpcode::kLoop) {
   4313     // Control node for loop exists, add input.
   4314     const Operator* op = common()->Loop(inputs);
   4315     control->AppendInput(graph_zone(), other);
   4316     NodeProperties::ChangeOp(control, op);
   4317   } else if (control->opcode() == IrOpcode::kMerge) {
   4318     // Control node for merge exists, add input.
   4319     const Operator* op = common()->Merge(inputs);
   4320     control->AppendInput(graph_zone(), other);
   4321     NodeProperties::ChangeOp(control, op);
   4322   } else {
   4323     // Control node is a singleton, introduce a merge.
   4324     const Operator* op = common()->Merge(inputs);
   4325     Node* inputs[] = {control, other};
   4326     control = graph()->NewNode(op, arraysize(inputs), inputs, true);
   4327   }
   4328   return control;
   4329 }
   4330 
   4331 
   4332 Node* AstGraphBuilder::MergeEffect(Node* value, Node* other, Node* control) {
   4333   int inputs = control->op()->ControlInputCount();
   4334   if (value->opcode() == IrOpcode::kEffectPhi &&
   4335       NodeProperties::GetControlInput(value) == control) {
   4336     // Phi already exists, add input.
   4337     value->InsertInput(graph_zone(), inputs - 1, other);
   4338     NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
   4339   } else if (value != other) {
   4340     // Phi does not exist yet, introduce one.
   4341     value = NewEffectPhi(inputs, value, control);
   4342     value->ReplaceInput(inputs - 1, other);
   4343   }
   4344   return value;
   4345 }
   4346 
   4347 
   4348 Node* AstGraphBuilder::MergeValue(Node* value, Node* other, Node* control) {
   4349   int inputs = control->op()->ControlInputCount();
   4350   if (value->opcode() == IrOpcode::kPhi &&
   4351       NodeProperties::GetControlInput(value) == control) {
   4352     // Phi already exists, add input.
   4353     value->InsertInput(graph_zone(), inputs - 1, other);
   4354     NodeProperties::ChangeOp(
   4355         value, common()->Phi(MachineRepresentation::kTagged, inputs));
   4356   } else if (value != other) {
   4357     // Phi does not exist yet, introduce one.
   4358     value = NewPhi(inputs, value, control);
   4359     value->ReplaceInput(inputs - 1, other);
   4360   }
   4361   return value;
   4362 }
   4363 
   4364 }  // namespace compiler
   4365 }  // namespace internal
   4366 }  // namespace v8
   4367