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