deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / compiler / ast-graph-builder.cc
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/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/js-type-feedback.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/full-codegen.h"
19 #include "src/parser.h"
20 #include "src/scopes.h"
21
22 namespace v8 {
23 namespace internal {
24 namespace compiler {
25
26
27 // Each expression in the AST is evaluated in a specific context. This context
28 // decides how the evaluation result is passed up the visitor.
29 class AstGraphBuilder::AstContext BASE_EMBEDDED {
30  public:
31   bool IsEffect() const { return kind_ == Expression::kEffect; }
32   bool IsValue() const { return kind_ == Expression::kValue; }
33   bool IsTest() const { return kind_ == Expression::kTest; }
34
35   // Determines how to combine the frame state with the value
36   // that is about to be plugged into this AstContext.
37   OutputFrameStateCombine GetStateCombine() {
38     return IsEffect() ? OutputFrameStateCombine::Ignore()
39                       : OutputFrameStateCombine::Push();
40   }
41
42   // Plug a node into this expression context.  Call this function in tail
43   // position in the Visit functions for expressions.
44   virtual void ProduceValue(Node* value) = 0;
45
46   // Unplugs a node from this expression context.  Call this to retrieve the
47   // result of another Visit function that already plugged the context.
48   virtual Node* ConsumeValue() = 0;
49
50   // Shortcut for "context->ProduceValue(context->ConsumeValue())".
51   void ReplaceValue() { ProduceValue(ConsumeValue()); }
52
53  protected:
54   AstContext(AstGraphBuilder* owner, Expression::Context kind);
55   virtual ~AstContext();
56
57   AstGraphBuilder* owner() const { return owner_; }
58   Environment* environment() const { return owner_->environment(); }
59
60 // We want to be able to assert, in a context-specific way, that the stack
61 // height makes sense when the context is filled.
62 #ifdef DEBUG
63   int original_height_;
64 #endif
65
66  private:
67   Expression::Context kind_;
68   AstGraphBuilder* owner_;
69   AstContext* outer_;
70 };
71
72
73 // Context to evaluate expression for its side effects only.
74 class AstGraphBuilder::AstEffectContext FINAL : public AstContext {
75  public:
76   explicit AstEffectContext(AstGraphBuilder* owner)
77       : AstContext(owner, Expression::kEffect) {}
78   ~AstEffectContext() FINAL;
79   void ProduceValue(Node* value) FINAL;
80   Node* ConsumeValue() FINAL;
81 };
82
83
84 // Context to evaluate expression for its value (and side effects).
85 class AstGraphBuilder::AstValueContext FINAL : public AstContext {
86  public:
87   explicit AstValueContext(AstGraphBuilder* owner)
88       : AstContext(owner, Expression::kValue) {}
89   ~AstValueContext() FINAL;
90   void ProduceValue(Node* value) FINAL;
91   Node* ConsumeValue() FINAL;
92 };
93
94
95 // Context to evaluate expression for a condition value (and side effects).
96 class AstGraphBuilder::AstTestContext FINAL : public AstContext {
97  public:
98   explicit AstTestContext(AstGraphBuilder* owner)
99       : AstContext(owner, Expression::kTest) {}
100   ~AstTestContext() FINAL;
101   void ProduceValue(Node* value) FINAL;
102   Node* ConsumeValue() FINAL;
103 };
104
105
106 // Scoped class tracking context objects created by the visitor. Represents
107 // mutations of the context chain within the function body and allows to
108 // change the current {scope} and {context} during visitation.
109 class AstGraphBuilder::ContextScope BASE_EMBEDDED {
110  public:
111   ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context)
112       : builder_(builder),
113         outer_(builder->execution_context()),
114         scope_(scope),
115         depth_(builder_->environment()->ContextStackDepth()) {
116     builder_->environment()->PushContext(context);  // Push.
117     builder_->set_execution_context(this);
118   }
119
120   ~ContextScope() {
121     builder_->set_execution_context(outer_);  // Pop.
122     builder_->environment()->PopContext();
123     CHECK_EQ(depth_, builder_->environment()->ContextStackDepth());
124   }
125
126   // Current scope during visitation.
127   Scope* scope() const { return scope_; }
128
129  private:
130   AstGraphBuilder* builder_;
131   ContextScope* outer_;
132   Scope* scope_;
133   int depth_;
134 };
135
136
137 // Scoped class tracking control statements entered by the visitor. There are
138 // different types of statements participating in this stack to properly track
139 // local as well as non-local control flow:
140 //  - IterationStatement : Allows proper 'break' and 'continue' behavior.
141 //  - BreakableStatement : Allows 'break' from block and switch statements.
142 //  - TryCatchStatement  : Intercepts 'throw' and implicit exceptional edges.
143 //  - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'.
144 class AstGraphBuilder::ControlScope BASE_EMBEDDED {
145  public:
146   explicit ControlScope(AstGraphBuilder* builder)
147       : builder_(builder),
148         outer_(builder->execution_control()),
149         stack_height_(builder->environment()->stack_height()) {
150     builder_->set_execution_control(this);  // Push.
151   }
152
153   virtual ~ControlScope() {
154     builder_->set_execution_control(outer_);  // Pop.
155   }
156
157   // Either 'break' or 'continue' to the target statement.
158   void BreakTo(BreakableStatement* target);
159   void ContinueTo(BreakableStatement* target);
160
161   // Either 'return' or 'throw' the given value.
162   void ReturnValue(Node* return_value);
163   void ThrowValue(Node* exception_value);
164
165   class DeferredCommands;
166
167  protected:
168   enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW };
169
170   // Performs one of the above commands on this stack of control scopes. This
171   // walks through the stack giving each scope a chance to execute or defer the
172   // given command by overriding the {Execute} method appropriately. Note that
173   // this also drops extra operands from the environment for each skipped scope.
174   void PerformCommand(Command cmd, Statement* target, Node* value);
175
176   // Interface to execute a given command in this scope. Returning {true} here
177   // indicates successful execution whereas {false} requests to skip scope.
178   virtual bool Execute(Command cmd, Statement* target, Node* value) {
179     // For function-level control.
180     switch (cmd) {
181       case CMD_THROW:
182         builder()->BuildThrow(value);
183         return true;
184       case CMD_RETURN:
185         builder()->BuildReturn(value);
186         return true;
187       case CMD_BREAK:
188       case CMD_CONTINUE:
189         break;
190     }
191     return false;
192   }
193
194   Environment* environment() { return builder_->environment(); }
195   AstGraphBuilder* builder() const { return builder_; }
196   int stack_height() const { return stack_height_; }
197
198  private:
199   AstGraphBuilder* builder_;
200   ControlScope* outer_;
201   int stack_height_;
202 };
203
204
205 // Helper class for a try-finally control scope. It can record intercepted
206 // control-flow commands that cause entry into a finally-block, and re-apply
207 // them after again leaving that block. Special tokens are used to identify
208 // paths going through the finally-block to dispatch after leaving the block.
209 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
210  public:
211   explicit DeferredCommands(AstGraphBuilder* owner)
212       : owner_(owner), deferred_(owner->zone()) {}
213
214   // One recorded control-flow command.
215   struct Entry {
216     Command command;       // The command type being applied on this path.
217     Statement* statement;  // The target statement for the command or {NULL}.
218     Node* token;           // A token identifying this particular path.
219   };
220
221   // Records a control-flow command while entering the finally-block. This also
222   // generates a new dispatch token that identifies one particular path.
223   Node* RecordCommand(Command cmd, Statement* stmt, Node* value) {
224     Node* token = NewPathTokenForDeferredCommand();
225     deferred_.push_back({cmd, stmt, token});
226     return token;
227   }
228
229   // Returns the dispatch token to be used to identify the implicit fall-through
230   // path at the end of a try-block into the corresponding finally-block.
231   Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); }
232
233   // Applies all recorded control-flow commands after the finally-block again.
234   // This generates a dynamic dispatch on the token from the entry point.
235   void ApplyDeferredCommands(Node* token, Node* value) {
236     SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size()));
237     dispatch.BeginSwitch();
238     for (size_t i = 0; i < deferred_.size(); ++i) {
239       Node* condition = NewPathDispatchCondition(token, deferred_[i].token);
240       dispatch.BeginLabel(static_cast<int>(i), condition);
241       dispatch.EndLabel();
242     }
243     for (size_t i = 0; i < deferred_.size(); ++i) {
244       dispatch.BeginCase(static_cast<int>(i));
245       owner_->execution_control()->PerformCommand(
246           deferred_[i].command, deferred_[i].statement, value);
247       dispatch.EndCase();
248     }
249     dispatch.EndSwitch();
250   }
251
252  protected:
253   Node* NewPathTokenForDeferredCommand() {
254     return owner_->jsgraph()->Constant(static_cast<int>(deferred_.size()));
255   }
256   Node* NewPathTokenForImplicitFallThrough() {
257     return owner_->jsgraph()->Constant(-1);
258   }
259   Node* NewPathDispatchCondition(Node* t1, Node* t2) {
260     // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi
261     // nodes all have kRepTagged|kTypeAny, which causes representation mismatch.
262     return owner_->NewNode(owner_->javascript()->StrictEqual(), t1, t2);
263   }
264
265  private:
266   AstGraphBuilder* owner_;
267   ZoneVector<Entry> deferred_;
268 };
269
270
271 // Control scope implementation for a BreakableStatement.
272 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope {
273  public:
274   ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target,
275                            ControlBuilder* control)
276       : ControlScope(owner), target_(target), control_(control) {}
277
278  protected:
279   virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE {
280     if (target != target_) return false;  // We are not the command target.
281     switch (cmd) {
282       case CMD_BREAK:
283         control_->Break();
284         return true;
285       case CMD_CONTINUE:
286       case CMD_THROW:
287       case CMD_RETURN:
288         break;
289     }
290     return false;
291   }
292
293  private:
294   BreakableStatement* target_;
295   ControlBuilder* control_;
296 };
297
298
299 // Control scope implementation for an IterationStatement.
300 class AstGraphBuilder::ControlScopeForIteration : public ControlScope {
301  public:
302   ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target,
303                            LoopBuilder* control)
304       : ControlScope(owner), target_(target), control_(control) {}
305
306  protected:
307   virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE {
308     if (target != target_) return false;  // We are not the command target.
309     switch (cmd) {
310       case CMD_BREAK:
311         control_->Break();
312         return true;
313       case CMD_CONTINUE:
314         control_->Continue();
315         return true;
316       case CMD_THROW:
317       case CMD_RETURN:
318         break;
319     }
320     return false;
321   }
322
323  private:
324   BreakableStatement* target_;
325   LoopBuilder* control_;
326 };
327
328
329 // Control scope implementation for a TryCatchStatement.
330 class AstGraphBuilder::ControlScopeForCatch : public ControlScope {
331  public:
332   ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control)
333       : ControlScope(owner), control_(control) {
334     builder()->try_nesting_level_++;  // Increment nesting.
335   }
336   ~ControlScopeForCatch() {
337     builder()->try_nesting_level_--;  // Decrement nesting.
338   }
339
340  protected:
341   virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE {
342     switch (cmd) {
343       case CMD_THROW:
344         control_->Throw(value);
345         return true;
346       case CMD_BREAK:
347       case CMD_CONTINUE:
348       case CMD_RETURN:
349         break;
350     }
351     return false;
352   }
353
354  private:
355   TryCatchBuilder* control_;
356 };
357
358
359 // Control scope implementation for a TryFinallyStatement.
360 class AstGraphBuilder::ControlScopeForFinally : public ControlScope {
361  public:
362   ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands,
363                          TryFinallyBuilder* control)
364       : ControlScope(owner), commands_(commands), control_(control) {
365     builder()->try_nesting_level_++;  // Increment nesting.
366   }
367   ~ControlScopeForFinally() {
368     builder()->try_nesting_level_--;  // Decrement nesting.
369   }
370
371  protected:
372   virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE {
373     Node* token = commands_->RecordCommand(cmd, target, value);
374     control_->LeaveTry(token, value);
375     return true;
376   }
377
378  private:
379   DeferredCommands* commands_;
380   TryFinallyBuilder* control_;
381 };
382
383
384 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
385                                  JSGraph* jsgraph, LoopAssignmentAnalysis* loop,
386                                  JSTypeFeedbackTable* js_type_feedback)
387     : local_zone_(local_zone),
388       info_(info),
389       jsgraph_(jsgraph),
390       environment_(nullptr),
391       ast_context_(nullptr),
392       globals_(0, local_zone),
393       execution_control_(nullptr),
394       execution_context_(nullptr),
395       try_nesting_level_(0),
396       input_buffer_size_(0),
397       input_buffer_(nullptr),
398       exit_control_(nullptr),
399       loop_assignment_analysis_(loop),
400       state_values_cache_(jsgraph),
401       liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()),
402                          local_zone),
403       js_type_feedback_(js_type_feedback) {
404   InitializeAstVisitor(info->isolate(), local_zone);
405 }
406
407
408 Node* AstGraphBuilder::GetFunctionClosure() {
409   if (!function_closure_.is_set()) {
410     const Operator* op =
411         common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex);
412     Node* node = NewNode(op, graph()->start());
413     function_closure_.set(node);
414   }
415   return function_closure_.get();
416 }
417
418
419 void AstGraphBuilder::CreateFunctionContext(bool constant_context) {
420   function_context_.set(constant_context
421                             ? jsgraph()->HeapConstant(info()->context())
422                             : NewOuterContextParam());
423 }
424
425
426 Node* AstGraphBuilder::NewOuterContextParam() {
427   // Parameter (arity + 1) is special for the outer context of the function
428   const Operator* op = common()->Parameter(info()->num_parameters() + 1);
429   return NewNode(op, graph()->start());
430 }
431
432
433 Node* AstGraphBuilder::NewCurrentContextOsrValue() {
434   // TODO(titzer): use a real OSR value here; a parameter works by accident.
435   // Parameter (arity + 1) is special for the outer context of the function
436   const Operator* op = common()->Parameter(info()->num_parameters() + 1);
437   return NewNode(op, graph()->start());
438 }
439
440
441 bool AstGraphBuilder::CreateGraph(bool constant_context, bool stack_check) {
442   Scope* scope = info()->scope();
443   DCHECK(graph() != NULL);
444
445   // Set up the basic structure of the graph.
446   int parameter_count = info()->num_parameters();
447   graph()->SetStart(graph()->NewNode(common()->Start(parameter_count)));
448
449   // Initialize the top-level environment.
450   Environment env(this, scope, graph()->start());
451   set_environment(&env);
452
453   // Initialize control scope.
454   ControlScope control(this);
455
456   if (info()->is_osr()) {
457     // Use OSR normal entry as the start of the top-level environment.
458     // It will be replaced with {Dead} after typing and optimizations.
459     NewNode(common()->OsrNormalEntry());
460   }
461
462   // Initialize the incoming context.
463   CreateFunctionContext(constant_context);
464   ContextScope incoming(this, scope, function_context_.get());
465
466   // Build receiver check for sloppy mode if necessary.
467   // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
468   Node* original_receiver = env.Lookup(scope->receiver());
469   Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
470   env.Bind(scope->receiver(), patched_receiver);
471
472   // Build function context only if there are context allocated variables.
473   int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
474   if (heap_slots > 0) {
475     // Push a new inner context scope for the function.
476     Node* closure = GetFunctionClosure();
477     Node* inner_context =
478         BuildLocalFunctionContext(function_context_.get(), closure);
479     ContextScope top_context(this, scope, inner_context);
480     CreateGraphBody(stack_check);
481   } else {
482     // Simply use the outer function context in building the graph.
483     CreateGraphBody(stack_check);
484   }
485
486   // Finish the basic structure of the graph.
487   graph()->SetEnd(graph()->NewNode(common()->End(), exit_control()));
488
489   // Compute local variable liveness information and use it to relax
490   // frame states.
491   ClearNonLiveSlotsInFrameStates();
492
493   // Failures indicated by stack overflow.
494   return !HasStackOverflow();
495 }
496
497
498 void AstGraphBuilder::CreateGraphBody(bool stack_check) {
499   Scope* scope = info()->scope();
500
501   // Build the arguments object if it is used.
502   BuildArgumentsObject(scope->arguments());
503
504   // Build rest arguments array if it is used.
505   int rest_index;
506   Variable* rest_parameter = scope->rest_parameter(&rest_index);
507   BuildRestArgumentsArray(rest_parameter, rest_index);
508
509   // Emit tracing call if requested to do so.
510   if (FLAG_trace) {
511     NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0));
512   }
513
514   // Visit implicit declaration of the function name.
515   if (scope->is_function_scope() && scope->function() != NULL) {
516     VisitVariableDeclaration(scope->function());
517   }
518
519   // Visit declarations within the function scope.
520   VisitDeclarations(scope->declarations());
521
522   // Build a stack-check before the body.
523   if (stack_check) {
524     Node* node = NewNode(javascript()->StackCheck());
525     PrepareFrameState(node, BailoutId::FunctionEntry());
526   }
527
528   // Visit statements in the function body.
529   VisitStatements(info()->function()->body());
530
531   // Emit tracing call if requested to do so.
532   if (FLAG_trace) {
533     // TODO(mstarzinger): Only traces implicit return.
534     Node* return_value = jsgraph()->UndefinedConstant();
535     NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
536   }
537
538   // Return 'undefined' in case we can fall off the end.
539   BuildReturn(jsgraph()->UndefinedConstant());
540 }
541
542
543 void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
544   if (!FLAG_analyze_environment_liveness) return;
545
546   NonLiveFrameStateSlotReplacer replacer(
547       &state_values_cache_, jsgraph()->UndefinedConstant(),
548       liveness_analyzer()->local_count(), local_zone());
549   Variable* arguments = info()->scope()->arguments();
550   if (arguments != nullptr && arguments->IsStackAllocated()) {
551     replacer.MarkPermanentlyLive(arguments->index());
552   }
553   liveness_analyzer()->Run(&replacer);
554   if (FLAG_trace_environment_liveness) {
555     OFStream os(stdout);
556     liveness_analyzer()->Print(os);
557   }
558 }
559
560
561 // Left-hand side can only be a property, a global or a variable slot.
562 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
563
564
565 // Determine the left-hand side kind of an assignment.
566 static LhsKind DetermineLhsKind(Expression* expr) {
567   Property* property = expr->AsProperty();
568   DCHECK(expr->IsValidReferenceExpression());
569   LhsKind lhs_kind =
570       (property == NULL) ? VARIABLE : (property->key()->IsPropertyName())
571                                           ? NAMED_PROPERTY
572                                           : KEYED_PROPERTY;
573   return lhs_kind;
574 }
575
576
577 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
578                                           Scope* scope,
579                                           Node* control_dependency)
580     : builder_(builder),
581       parameters_count_(scope->num_parameters() + 1),
582       locals_count_(scope->num_stack_slots()),
583       liveness_block_(builder_->liveness_analyzer()->NewBlock()),
584       values_(builder_->local_zone()),
585       contexts_(builder_->local_zone()),
586       control_dependency_(control_dependency),
587       effect_dependency_(control_dependency),
588       parameters_node_(nullptr),
589       locals_node_(nullptr),
590       stack_node_(nullptr) {
591   DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
592
593   // Bind the receiver variable.
594   Node* receiver = builder->graph()->NewNode(common()->Parameter(0),
595                                              builder->graph()->start());
596   values()->push_back(receiver);
597
598   // Bind all parameter variables. The parameter indices are shifted by 1
599   // (receiver is parameter index -1 but environment index 0).
600   for (int i = 0; i < scope->num_parameters(); ++i) {
601     Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1),
602                                                 builder->graph()->start());
603     values()->push_back(parameter);
604   }
605
606   // Bind all local variables to undefined.
607   Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
608   values()->insert(values()->end(), locals_count(), undefined_constant);
609 }
610
611
612 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy)
613     : builder_(copy->builder_),
614       parameters_count_(copy->parameters_count_),
615       locals_count_(copy->locals_count_),
616       values_(copy->zone()),
617       contexts_(copy->zone()),
618       control_dependency_(copy->control_dependency_),
619       effect_dependency_(copy->effect_dependency_),
620       parameters_node_(copy->parameters_node_),
621       locals_node_(copy->locals_node_),
622       stack_node_(copy->stack_node_) {
623   const size_t kStackEstimate = 7;  // optimum from experimentation!
624   values_.reserve(copy->values_.size() + kStackEstimate);
625   values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end());
626   contexts_.reserve(copy->contexts_.size());
627   contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
628                    copy->contexts_.end());
629
630   if (FLAG_analyze_environment_liveness) {
631     // Split the liveness blocks.
632     copy->liveness_block_ =
633         builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
634     liveness_block_ =
635         builder_->liveness_analyzer()->NewBlock(copy->liveness_block());
636   }
637 }
638
639
640 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) {
641   DCHECK(variable->IsStackAllocated());
642   if (variable->IsParameter()) {
643     // The parameter indices are shifted by 1 (receiver is parameter
644     // index -1 but environment index 0).
645     values()->at(variable->index() + 1) = node;
646   } else {
647     DCHECK(variable->IsStackLocal());
648     values()->at(variable->index() + parameters_count_) = node;
649     if (FLAG_analyze_environment_liveness) {
650       liveness_block()->Bind(variable->index());
651     }
652   }
653 }
654
655
656 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
657   DCHECK(variable->IsStackAllocated());
658   if (variable->IsParameter()) {
659     // The parameter indices are shifted by 1 (receiver is parameter
660     // index -1 but environment index 0).
661     return values()->at(variable->index() + 1);
662   } else {
663     DCHECK(variable->IsStackLocal());
664     if (FLAG_analyze_environment_liveness) {
665       liveness_block()->Lookup(variable->index());
666     }
667     return values()->at(variable->index() + parameters_count_);
668   }
669 }
670
671
672 void AstGraphBuilder::Environment::MarkAllLocalsLive() {
673   if (FLAG_analyze_environment_liveness) {
674     for (int i = 0; i < locals_count_; i++) {
675       liveness_block()->Lookup(i);
676     }
677   }
678 }
679
680
681 AstGraphBuilder::Environment*
682 AstGraphBuilder::Environment::CopyAndShareLiveness() {
683   Environment* env = new (zone()) Environment(this);
684   if (FLAG_analyze_environment_liveness) {
685     env->liveness_block_ = liveness_block();
686   }
687   return env;
688 }
689
690
691 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
692                                                      int offset, int count) {
693   bool should_update = false;
694   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
695   if (*state_values == NULL || (*state_values)->InputCount() != count) {
696     should_update = true;
697   } else {
698     DCHECK(static_cast<size_t>(offset + count) <= values()->size());
699     for (int i = 0; i < count; i++) {
700       if ((*state_values)->InputAt(i) != env_values[i]) {
701         should_update = true;
702         break;
703       }
704     }
705   }
706   if (should_update) {
707     const Operator* op = common()->StateValues(count);
708     (*state_values) = graph()->NewNode(op, count, env_values);
709   }
710 }
711
712
713 void AstGraphBuilder::Environment::UpdateStateValuesWithCache(
714     Node** state_values, int offset, int count) {
715   Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
716   *state_values = builder_->state_values_cache_.GetNodeForValues(
717       env_values, static_cast<size_t>(count));
718 }
719
720
721 Node* AstGraphBuilder::Environment::Checkpoint(
722     BailoutId ast_id, OutputFrameStateCombine combine) {
723   if (!FLAG_turbo_deoptimization) return nullptr;
724
725   UpdateStateValues(&parameters_node_, 0, parameters_count());
726   UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count());
727   UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
728                     stack_height());
729
730   const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine);
731
732   Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
733                                   stack_node_, builder()->current_context(),
734                                   builder()->jsgraph()->UndefinedConstant());
735   if (FLAG_analyze_environment_liveness) {
736     liveness_block()->Checkpoint(result);
737   }
738   return result;
739 }
740
741
742 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own,
743                                         Expression::Context kind)
744     : kind_(kind), owner_(own), outer_(own->ast_context()) {
745   owner()->set_ast_context(this);  // Push.
746 #ifdef DEBUG
747   original_height_ = environment()->stack_height();
748 #endif
749 }
750
751
752 AstGraphBuilder::AstContext::~AstContext() {
753   owner()->set_ast_context(outer_);  // Pop.
754 }
755
756
757 AstGraphBuilder::AstEffectContext::~AstEffectContext() {
758   DCHECK(environment()->stack_height() == original_height_);
759 }
760
761
762 AstGraphBuilder::AstValueContext::~AstValueContext() {
763   DCHECK(environment()->stack_height() == original_height_ + 1);
764 }
765
766
767 AstGraphBuilder::AstTestContext::~AstTestContext() {
768   DCHECK(environment()->stack_height() == original_height_ + 1);
769 }
770
771
772 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) {
773   // The value is ignored.
774 }
775
776
777 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) {
778   environment()->Push(value);
779 }
780
781
782 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) {
783   environment()->Push(owner()->BuildToBoolean(value));
784 }
785
786
787 Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return NULL; }
788
789
790 Node* AstGraphBuilder::AstValueContext::ConsumeValue() {
791   return environment()->Pop();
792 }
793
794
795 Node* AstGraphBuilder::AstTestContext::ConsumeValue() {
796   return environment()->Pop();
797 }
798
799
800 Scope* AstGraphBuilder::current_scope() const {
801   return execution_context_->scope();
802 }
803
804
805 Node* AstGraphBuilder::current_context() const {
806   return environment()->Context();
807 }
808
809
810 void AstGraphBuilder::ControlScope::PerformCommand(Command command,
811                                                    Statement* target,
812                                                    Node* value) {
813   Environment* env = environment()->CopyAsUnreachable();
814   ControlScope* current = this;
815   while (current != NULL) {
816     environment()->Trim(current->stack_height());
817     if (current->Execute(command, target, value)) break;
818     current = current->outer_;
819   }
820   builder()->set_environment(env);
821   DCHECK(current != NULL);  // Always handled (unless stack is malformed).
822 }
823
824
825 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) {
826   PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant());
827 }
828
829
830 void AstGraphBuilder::ControlScope::ContinueTo(BreakableStatement* stmt) {
831   PerformCommand(CMD_CONTINUE, stmt, builder()->jsgraph()->TheHoleConstant());
832 }
833
834
835 void AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) {
836   PerformCommand(CMD_RETURN, nullptr, return_value);
837 }
838
839
840 void AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) {
841   PerformCommand(CMD_THROW, nullptr, exception_value);
842 }
843
844
845 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) {
846   if (expr == NULL) {
847     return environment()->Push(jsgraph()->NullConstant());
848   }
849   VisitForValue(expr);
850 }
851
852
853 void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) {
854   if (expr == NULL) {
855     return environment()->Push(jsgraph()->TheHoleConstant());
856   }
857   VisitForValue(expr);
858 }
859
860
861 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
862   for (int i = 0; i < exprs->length(); ++i) {
863     VisitForValue(exprs->at(i));
864   }
865 }
866
867
868 void AstGraphBuilder::VisitForValue(Expression* expr) {
869   AstValueContext for_value(this);
870   if (!CheckStackOverflow()) {
871     expr->Accept(this);
872   } else {
873     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
874   }
875 }
876
877
878 void AstGraphBuilder::VisitForEffect(Expression* expr) {
879   AstEffectContext for_effect(this);
880   if (!CheckStackOverflow()) {
881     expr->Accept(this);
882   } else {
883     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
884   }
885 }
886
887
888 void AstGraphBuilder::VisitForTest(Expression* expr) {
889   AstTestContext for_condition(this);
890   if (!CheckStackOverflow()) {
891     expr->Accept(this);
892   } else {
893     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
894   }
895 }
896
897
898 void AstGraphBuilder::Visit(Expression* expr) {
899   // Reuses enclosing AstContext.
900   if (!CheckStackOverflow()) {
901     expr->Accept(this);
902   } else {
903     ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
904   }
905 }
906
907
908 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
909   Variable* variable = decl->proxy()->var();
910   VariableMode mode = decl->mode();
911   bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
912   switch (variable->location()) {
913     case Variable::UNALLOCATED: {
914       Handle<Oddball> value = variable->binding_needs_init()
915                                   ? isolate()->factory()->the_hole_value()
916                                   : isolate()->factory()->undefined_value();
917       globals()->push_back(variable->name());
918       globals()->push_back(value);
919       break;
920     }
921     case Variable::PARAMETER:
922     case Variable::LOCAL:
923       if (hole_init) {
924         Node* value = jsgraph()->TheHoleConstant();
925         environment()->Bind(variable, value);
926       }
927       break;
928     case Variable::CONTEXT:
929       if (hole_init) {
930         Node* value = jsgraph()->TheHoleConstant();
931         const Operator* op = javascript()->StoreContext(0, variable->index());
932         NewNode(op, current_context(), value);
933       }
934       break;
935     case Variable::LOOKUP:
936       UNIMPLEMENTED();
937   }
938 }
939
940
941 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
942   Variable* variable = decl->proxy()->var();
943   switch (variable->location()) {
944     case Variable::UNALLOCATED: {
945       Handle<SharedFunctionInfo> function =
946           Compiler::BuildFunctionInfo(decl->fun(), info()->script(), info());
947       // Check for stack-overflow exception.
948       if (function.is_null()) return SetStackOverflow();
949       globals()->push_back(variable->name());
950       globals()->push_back(function);
951       break;
952     }
953     case Variable::PARAMETER:
954     case Variable::LOCAL: {
955       VisitForValue(decl->fun());
956       Node* value = environment()->Pop();
957       environment()->Bind(variable, value);
958       break;
959     }
960     case Variable::CONTEXT: {
961       VisitForValue(decl->fun());
962       Node* value = environment()->Pop();
963       const Operator* op = javascript()->StoreContext(0, variable->index());
964       NewNode(op, current_context(), value);
965       break;
966     }
967     case Variable::LOOKUP:
968       UNIMPLEMENTED();
969   }
970 }
971
972
973 void AstGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) {
974   UNREACHABLE();
975 }
976
977
978 void AstGraphBuilder::VisitImportDeclaration(ImportDeclaration* decl) {
979   UNREACHABLE();
980 }
981
982
983 void AstGraphBuilder::VisitExportDeclaration(ExportDeclaration* decl) {
984   UNREACHABLE();
985 }
986
987
988 void AstGraphBuilder::VisitModuleLiteral(ModuleLiteral* modl) { UNREACHABLE(); }
989
990
991 void AstGraphBuilder::VisitModulePath(ModulePath* modl) { UNREACHABLE(); }
992
993
994 void AstGraphBuilder::VisitModuleUrl(ModuleUrl* modl) { UNREACHABLE(); }
995
996
997 void AstGraphBuilder::VisitBlock(Block* stmt) {
998   BlockBuilder block(this);
999   ControlScopeForBreakable scope(this, stmt, &block);
1000   if (stmt->labels() != NULL) block.BeginBlock();
1001   if (stmt->scope() == NULL) {
1002     // Visit statements in the same scope, no declarations.
1003     VisitStatements(stmt->statements());
1004   } else {
1005     // Visit declarations and statements in a block scope.
1006     Node* context = BuildLocalBlockContext(stmt->scope());
1007     ContextScope scope(this, stmt->scope(), context);
1008     VisitDeclarations(stmt->scope()->declarations());
1009     VisitStatements(stmt->statements());
1010   }
1011   if (stmt->labels() != NULL) block.EndBlock();
1012 }
1013
1014
1015 void AstGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) {
1016   UNREACHABLE();
1017 }
1018
1019
1020 void AstGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
1021   VisitForEffect(stmt->expression());
1022 }
1023
1024
1025 void AstGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
1026   // Do nothing.
1027 }
1028
1029
1030 void AstGraphBuilder::VisitIfStatement(IfStatement* stmt) {
1031   IfBuilder compare_if(this);
1032   VisitForTest(stmt->condition());
1033   Node* condition = environment()->Pop();
1034   compare_if.If(condition);
1035   compare_if.Then();
1036   Visit(stmt->then_statement());
1037   compare_if.Else();
1038   Visit(stmt->else_statement());
1039   compare_if.End();
1040 }
1041
1042
1043 void AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
1044   execution_control()->ContinueTo(stmt->target());
1045 }
1046
1047
1048 void AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
1049   execution_control()->BreakTo(stmt->target());
1050 }
1051
1052
1053 void AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
1054   VisitForValue(stmt->expression());
1055   Node* result = environment()->Pop();
1056   execution_control()->ReturnValue(result);
1057 }
1058
1059
1060 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
1061   VisitForValue(stmt->expression());
1062   Node* value = environment()->Pop();
1063   const Operator* op = javascript()->CreateWithContext();
1064   Node* context = NewNode(op, value, GetFunctionClosure());
1065   PrepareFrameState(context, stmt->EntryId());
1066   ContextScope scope(this, stmt->scope(), context);
1067   Visit(stmt->statement());
1068 }
1069
1070
1071 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
1072   ZoneList<CaseClause*>* clauses = stmt->cases();
1073   SwitchBuilder compare_switch(this, clauses->length());
1074   ControlScopeForBreakable scope(this, stmt, &compare_switch);
1075   compare_switch.BeginSwitch();
1076   int default_index = -1;
1077
1078   // Keep the switch value on the stack until a case matches.
1079   VisitForValue(stmt->tag());
1080   Node* tag = environment()->Top();
1081
1082   // Iterate over all cases and create nodes for label comparison.
1083   for (int i = 0; i < clauses->length(); i++) {
1084     CaseClause* clause = clauses->at(i);
1085
1086     // The default is not a test, remember index.
1087     if (clause->is_default()) {
1088       default_index = i;
1089       continue;
1090     }
1091
1092     // Create nodes to perform label comparison as if via '==='. The switch
1093     // value is still on the operand stack while the label is evaluated.
1094     VisitForValue(clause->label());
1095     Node* label = environment()->Pop();
1096     const Operator* op = javascript()->StrictEqual();
1097     Node* condition = NewNode(op, tag, label);
1098     compare_switch.BeginLabel(i, condition);
1099
1100     // Discard the switch value at label match.
1101     environment()->Pop();
1102     compare_switch.EndLabel();
1103   }
1104
1105   // Discard the switch value and mark the default case.
1106   environment()->Pop();
1107   if (default_index >= 0) {
1108     compare_switch.DefaultAt(default_index);
1109   }
1110
1111   // Iterate over all cases and create nodes for case bodies.
1112   for (int i = 0; i < clauses->length(); i++) {
1113     CaseClause* clause = clauses->at(i);
1114     compare_switch.BeginCase(i);
1115     VisitStatements(clause->statements());
1116     compare_switch.EndCase();
1117   }
1118
1119   compare_switch.EndSwitch();
1120 }
1121
1122
1123 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
1124   LoopBuilder while_loop(this);
1125   while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
1126   VisitIterationBody(stmt, &while_loop);
1127   while_loop.EndBody();
1128   VisitForTest(stmt->cond());
1129   Node* condition = environment()->Pop();
1130   while_loop.BreakUnless(condition);
1131   while_loop.EndLoop();
1132 }
1133
1134
1135 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
1136   LoopBuilder while_loop(this);
1137   while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
1138   VisitForTest(stmt->cond());
1139   Node* condition = environment()->Pop();
1140   while_loop.BreakUnless(condition);
1141   VisitIterationBody(stmt, &while_loop);
1142   while_loop.EndBody();
1143   while_loop.EndLoop();
1144 }
1145
1146
1147 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
1148   LoopBuilder for_loop(this);
1149   VisitIfNotNull(stmt->init());
1150   for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
1151   if (stmt->cond() != NULL) {
1152     VisitForTest(stmt->cond());
1153     Node* condition = environment()->Pop();
1154     for_loop.BreakUnless(condition);
1155   } else {
1156     for_loop.BreakUnless(jsgraph()->TrueConstant());
1157   }
1158   VisitIterationBody(stmt, &for_loop);
1159   for_loop.EndBody();
1160   VisitIfNotNull(stmt->next());
1161   for_loop.EndLoop();
1162 }
1163
1164
1165 // TODO(dcarney): this is a big function.  Try to clean up some.
1166 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
1167   VisitForValue(stmt->subject());
1168   Node* obj = environment()->Pop();
1169   // Check for undefined or null before entering loop.
1170   IfBuilder is_undefined(this);
1171   Node* is_undefined_cond =
1172       NewNode(javascript()->StrictEqual(), obj, jsgraph()->UndefinedConstant());
1173   is_undefined.If(is_undefined_cond);
1174   is_undefined.Then();
1175   is_undefined.Else();
1176   {
1177     IfBuilder is_null(this);
1178     Node* is_null_cond =
1179         NewNode(javascript()->StrictEqual(), obj, jsgraph()->NullConstant());
1180     is_null.If(is_null_cond);
1181     is_null.Then();
1182     is_null.Else();
1183     // Convert object to jsobject.
1184     // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
1185     obj = NewNode(javascript()->ToObject(), obj);
1186     PrepareFrameState(obj, stmt->ToObjectId(), OutputFrameStateCombine::Push());
1187     environment()->Push(obj);
1188     // TODO(dcarney): should do a fast enum cache check here to skip runtime.
1189     Node* cache_type = NewNode(
1190         javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), obj);
1191     PrepareFrameState(cache_type, stmt->EnumId(),
1192                       OutputFrameStateCombine::Push());
1193     // TODO(dcarney): these next runtime calls should be removed in favour of
1194     //                a few simplified instructions.
1195     Node* cache_pair = NewNode(
1196         javascript()->CallRuntime(Runtime::kForInInit, 2), obj, cache_type);
1197     // cache_type may have been replaced.
1198     Node* cache_array = NewNode(common()->Projection(0), cache_pair);
1199     cache_type = NewNode(common()->Projection(1), cache_pair);
1200     Node* cache_length =
1201         NewNode(javascript()->CallRuntime(Runtime::kForInCacheArrayLength, 2),
1202                 cache_type, cache_array);
1203     {
1204       // TODO(dcarney): this check is actually supposed to be for the
1205       //                empty enum case only.
1206       IfBuilder have_no_properties(this);
1207       Node* empty_array_cond = NewNode(javascript()->StrictEqual(),
1208                                        cache_length, jsgraph()->ZeroConstant());
1209       have_no_properties.If(empty_array_cond);
1210       have_no_properties.Then();
1211       // Pop obj and skip loop.
1212       environment()->Pop();
1213       have_no_properties.Else();
1214       {
1215         // Construct the rest of the environment.
1216         environment()->Push(cache_type);
1217         environment()->Push(cache_array);
1218         environment()->Push(cache_length);
1219         environment()->Push(jsgraph()->ZeroConstant());
1220
1221         // Build the actual loop body.
1222         VisitForInBody(stmt);
1223       }
1224       have_no_properties.End();
1225     }
1226     is_null.End();
1227   }
1228   is_undefined.End();
1229 }
1230
1231
1232 // TODO(dcarney): this is a big function.  Try to clean up some.
1233 void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
1234   LoopBuilder for_loop(this);
1235   for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
1236
1237   // These stack values are renamed in the case of OSR, so reload them
1238   // from the environment.
1239   Node* index = environment()->Peek(0);
1240   Node* cache_length = environment()->Peek(1);
1241   Node* cache_array = environment()->Peek(2);
1242   Node* cache_type = environment()->Peek(3);
1243   Node* obj = environment()->Peek(4);
1244
1245   // Check loop termination condition.
1246   Node* exit_cond = NewNode(javascript()->LessThan(), index, cache_length);
1247   // TODO(jarin): provide real bailout id.
1248   PrepareFrameState(exit_cond, BailoutId::None());
1249   for_loop.BreakUnless(exit_cond);
1250   Node* pair = NewNode(javascript()->CallRuntime(Runtime::kForInNext, 4), obj,
1251                        cache_array, cache_type, index);
1252   Node* value = NewNode(common()->Projection(0), pair);
1253   Node* should_filter = NewNode(common()->Projection(1), pair);
1254   environment()->Push(value);
1255   {
1256     // Test if FILTER_KEY needs to be called.
1257     IfBuilder test_should_filter(this);
1258     Node* should_filter_cond = NewNode(
1259         javascript()->StrictEqual(), should_filter, jsgraph()->TrueConstant());
1260     test_should_filter.If(should_filter_cond);
1261     test_should_filter.Then();
1262     value = environment()->Pop();
1263     Node* builtins = BuildLoadBuiltinsObject();
1264     Node* function = BuildLoadObjectField(
1265         builtins,
1266         JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
1267     // result is either the string key or Smi(0) indicating the property
1268     // is gone.
1269     Node* res = NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
1270                         function, obj, value);
1271     // TODO(jarin): provide real bailout id.
1272     PrepareFrameState(res, BailoutId::None());
1273     Node* property_missing =
1274         NewNode(javascript()->StrictEqual(), res, jsgraph()->ZeroConstant());
1275     {
1276       IfBuilder is_property_missing(this);
1277       is_property_missing.If(property_missing);
1278       is_property_missing.Then();
1279       // Inc counter and continue.
1280       Node* index_inc =
1281           NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
1282       // TODO(jarin): provide real bailout id.
1283       PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
1284                                       OutputFrameStateCombine::Ignore(),
1285                                       jsgraph()->EmptyFrameState());
1286       environment()->Poke(0, index_inc);
1287       for_loop.Continue();
1288       is_property_missing.Else();
1289       is_property_missing.End();
1290     }
1291     // Replace 'value' in environment.
1292     environment()->Push(res);
1293     test_should_filter.Else();
1294     test_should_filter.End();
1295   }
1296   value = environment()->Pop();
1297   // Bind value and do loop body.
1298   VisitForInAssignment(stmt->each(), value, stmt->AssignmentId());
1299   VisitIterationBody(stmt, &for_loop);
1300   index = environment()->Peek(0);
1301   for_loop.EndBody();
1302
1303   // Inc counter and continue.
1304   Node* index_inc =
1305       NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
1306   // TODO(jarin): provide real bailout id.
1307   PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(),
1308                                   OutputFrameStateCombine::Ignore(),
1309                                   jsgraph()->EmptyFrameState());
1310   environment()->Poke(0, index_inc);
1311   for_loop.EndLoop();
1312   environment()->Drop(5);
1313   // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1314 }
1315
1316
1317 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
1318   LoopBuilder for_loop(this);
1319   VisitForEffect(stmt->assign_iterator());
1320   for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
1321   VisitForEffect(stmt->next_result());
1322   VisitForTest(stmt->result_done());
1323   Node* condition = environment()->Pop();
1324   for_loop.BreakWhen(condition);
1325   VisitForEffect(stmt->assign_each());
1326   VisitIterationBody(stmt, &for_loop);
1327   for_loop.EndBody();
1328   for_loop.EndLoop();
1329 }
1330
1331
1332 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
1333   TryCatchBuilder try_control(this);
1334
1335   // Evaluate the try-block inside a control scope. This simulates a handler
1336   // that is intercepting 'throw' control commands.
1337   try_control.BeginTry();
1338   {
1339     ControlScopeForCatch scope(this, &try_control);
1340     STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1341     environment()->Push(current_context());
1342     Visit(stmt->try_block());
1343     environment()->Pop();
1344   }
1345   try_control.EndTry();
1346
1347   // Create a catch scope that binds the exception.
1348   Node* exception = try_control.GetExceptionNode();
1349   Unique<String> name = MakeUnique(stmt->variable()->name());
1350   const Operator* op = javascript()->CreateCatchContext(name);
1351   Node* context = NewNode(op, exception, GetFunctionClosure());
1352   PrepareFrameState(context, BailoutId::None());
1353   {
1354     ContextScope scope(this, stmt->scope(), context);
1355     DCHECK(stmt->scope()->declarations()->is_empty());
1356     // Evaluate the catch-block.
1357     Visit(stmt->catch_block());
1358   }
1359   try_control.EndCatch();
1360
1361   // TODO(mstarzinger): Remove bailout once everything works.
1362   if (!FLAG_turbo_exceptions) SetStackOverflow();
1363 }
1364
1365
1366 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1367   TryFinallyBuilder try_control(this);
1368
1369   ExternalReference message_object =
1370       ExternalReference::address_of_pending_message_obj(isolate());
1371
1372   // We keep a record of all paths that enter the finally-block to be able to
1373   // dispatch to the correct continuation point after the statements in the
1374   // finally-block have been evaluated.
1375   //
1376   // The try-finally construct can enter the finally-block in three ways:
1377   // 1. By exiting the try-block normally, falling through at the end.
1378   // 2. By exiting the try-block with a function-local control flow transfer
1379   //    (i.e. through break/continue/return statements).
1380   // 3. By exiting the try-block with a thrown exception.
1381   Node* fallthrough_result = jsgraph()->TheHoleConstant();
1382   ControlScope::DeferredCommands* commands =
1383       new (zone()) ControlScope::DeferredCommands(this);
1384
1385   // Evaluate the try-block inside a control scope. This simulates a handler
1386   // that is intercepting all control commands.
1387   try_control.BeginTry();
1388   {
1389     ControlScopeForFinally scope(this, commands, &try_control);
1390     STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1391     environment()->Push(current_context());
1392     Visit(stmt->try_block());
1393     environment()->Pop();
1394   }
1395   try_control.EndTry(commands->GetFallThroughToken(), fallthrough_result);
1396
1397   // The result value semantics depend on how the block was entered:
1398   //  - ReturnStatement: It represents the return value being returned.
1399   //  - ThrowStatement: It represents the exception being thrown.
1400   //  - BreakStatement/ContinueStatement: Filled with the hole.
1401   //  - Falling through into finally-block: Filled with the hole.
1402   Node* result = try_control.GetResultValueNode();
1403   Node* token = try_control.GetDispatchTokenNode();
1404
1405   // The result value, dispatch token and message is expected on the operand
1406   // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
1407   Node* message = BuildLoadExternal(message_object, kMachAnyTagged);
1408   environment()->Push(token);  // TODO(mstarzinger): Cook token!
1409   environment()->Push(result);
1410   environment()->Push(message);
1411
1412   // Evaluate the finally-block.
1413   Visit(stmt->finally_block());
1414   try_control.EndFinally();
1415
1416   // The result value, dispatch token and message is restored from the operand
1417   // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock).
1418   message = environment()->Pop();
1419   result = environment()->Pop();
1420   token = environment()->Pop();  // TODO(mstarzinger): Uncook token!
1421   BuildStoreExternal(message_object, kMachAnyTagged, message);
1422
1423   // Dynamic dispatch after the finally-block.
1424   commands->ApplyDeferredCommands(token, result);
1425
1426   // TODO(mstarzinger): Remove bailout once everything works.
1427   if (!FLAG_turbo_exceptions) SetStackOverflow();
1428 }
1429
1430
1431 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
1432   Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0));
1433   PrepareFrameState(node, stmt->DebugBreakId());
1434   environment()->MarkAllLocalsLive();
1435 }
1436
1437
1438 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
1439   Node* context = current_context();
1440
1441   // Build a new shared function info if we cannot find one in the baseline
1442   // code. We also have a stack overflow if the recursive compilation did.
1443   expr->InitializeSharedInfo(handle(info()->shared_info()->code()));
1444   Handle<SharedFunctionInfo> shared_info = expr->shared_info();
1445   if (shared_info.is_null()) {
1446     shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info());
1447     CHECK(!shared_info.is_null());  // TODO(mstarzinger): Set stack overflow?
1448   }
1449
1450   // Create node to instantiate a new closure.
1451   Node* info = jsgraph()->Constant(shared_info);
1452   Node* pretenure = jsgraph()->BooleanConstant(expr->pretenure());
1453   const Operator* op = javascript()->CallRuntime(Runtime::kNewClosure, 3);
1454   Node* value = NewNode(op, context, info, pretenure);
1455   ast_context()->ProduceValue(value);
1456 }
1457
1458
1459 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
1460   if (expr->scope() == NULL) {
1461     // Visit class literal in the same scope, no declarations.
1462     VisitClassLiteralContents(expr);
1463   } else {
1464     // Visit declarations and class literal in a block scope.
1465     Node* context = BuildLocalBlockContext(expr->scope());
1466     ContextScope scope(this, expr->scope(), context);
1467     VisitDeclarations(expr->scope()->declarations());
1468     VisitClassLiteralContents(expr);
1469   }
1470 }
1471
1472
1473 void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
1474   Node* class_name = expr->raw_name() ? jsgraph()->Constant(expr->name())
1475                                       : jsgraph()->UndefinedConstant();
1476
1477   // The class name is expected on the operand stack.
1478   environment()->Push(class_name);
1479   VisitForValueOrTheHole(expr->extends());
1480   VisitForValue(expr->constructor());
1481
1482   // Create node to instantiate a new class.
1483   Node* constructor = environment()->Pop();
1484   Node* extends = environment()->Pop();
1485   Node* name = environment()->Pop();
1486   Node* script = jsgraph()->Constant(info()->script());
1487   Node* start = jsgraph()->Constant(expr->start_position());
1488   Node* end = jsgraph()->Constant(expr->end_position());
1489   const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass, 6);
1490   Node* literal = NewNode(opc, name, extends, constructor, script, start, end);
1491
1492   // The prototype is ensured to exist by Runtime_DefineClass. No access check
1493   // is needed here since the constructor is created by the class literal.
1494   Node* proto =
1495       BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset);
1496
1497   // The class literal and the prototype are both expected on the operand stack
1498   // during evaluation of the method values.
1499   environment()->Push(literal);
1500   environment()->Push(proto);
1501
1502   // Create nodes to store method values into the literal.
1503   for (int i = 0; i < expr->properties()->length(); i++) {
1504     ObjectLiteral::Property* property = expr->properties()->at(i);
1505     environment()->Push(property->is_static() ? literal : proto);
1506
1507     VisitForValue(property->key());
1508     Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i));
1509     environment()->Push(name);
1510
1511     // The static prototype property is read only. We handle the non computed
1512     // property name case in the parser. Since this is the only case where we
1513     // need to check for an own read only property we special case this so we do
1514     // not need to do this for every property.
1515     if (property->is_static() && property->is_computed_name()) {
1516       Node* check = BuildThrowIfStaticPrototype(environment()->Pop(),
1517                                                 expr->GetIdForProperty(i));
1518       environment()->Push(check);
1519     }
1520
1521     VisitForValue(property->value());
1522     Node* value = environment()->Pop();
1523     Node* key = environment()->Pop();
1524     Node* receiver = environment()->Pop();
1525     BuildSetHomeObject(value, receiver, property->value());
1526
1527     switch (property->kind()) {
1528       case ObjectLiteral::Property::CONSTANT:
1529       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1530       case ObjectLiteral::Property::PROTOTYPE:
1531         UNREACHABLE();
1532       case ObjectLiteral::Property::COMPUTED: {
1533         const Operator* op =
1534             javascript()->CallRuntime(Runtime::kDefineClassMethod, 3);
1535         NewNode(op, receiver, key, value);
1536         break;
1537       }
1538       case ObjectLiteral::Property::GETTER: {
1539         Node* attr = jsgraph()->Constant(DONT_ENUM);
1540         const Operator* op = javascript()->CallRuntime(
1541             Runtime::kDefineGetterPropertyUnchecked, 4);
1542         NewNode(op, receiver, key, value, attr);
1543         break;
1544       }
1545       case ObjectLiteral::Property::SETTER: {
1546         Node* attr = jsgraph()->Constant(DONT_ENUM);
1547         const Operator* op = javascript()->CallRuntime(
1548             Runtime::kDefineSetterPropertyUnchecked, 4);
1549         NewNode(op, receiver, key, value, attr);
1550         break;
1551       }
1552     }
1553   }
1554
1555   // Transform both the class literal and the prototype to fast properties.
1556   const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1);
1557   NewNode(op, environment()->Pop());  // prototype
1558   NewNode(op, environment()->Pop());  // literal
1559
1560   // Assign to class variable.
1561   if (expr->scope() != NULL) {
1562     DCHECK_NOT_NULL(expr->class_variable_proxy());
1563     Variable* var = expr->class_variable_proxy()->var();
1564     BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None());
1565   }
1566
1567   PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
1568   ast_context()->ProduceValue(literal);
1569 }
1570
1571
1572 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
1573   UNREACHABLE();
1574 }
1575
1576
1577 void AstGraphBuilder::VisitConditional(Conditional* expr) {
1578   IfBuilder compare_if(this);
1579   VisitForTest(expr->condition());
1580   Node* condition = environment()->Pop();
1581   compare_if.If(condition);
1582   compare_if.Then();
1583   Visit(expr->then_expression());
1584   compare_if.Else();
1585   Visit(expr->else_expression());
1586   compare_if.End();
1587   ast_context()->ReplaceValue();
1588 }
1589
1590
1591 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
1592   VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
1593   Node* value = BuildVariableLoad(expr->var(), expr->id(), pair);
1594   ast_context()->ProduceValue(value);
1595 }
1596
1597
1598 void AstGraphBuilder::VisitLiteral(Literal* expr) {
1599   Node* value = jsgraph()->Constant(expr->value());
1600   ast_context()->ProduceValue(value);
1601 }
1602
1603
1604 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
1605   Node* closure = GetFunctionClosure();
1606
1607   // Create node to materialize a regular expression literal.
1608   Node* literals_array =
1609       BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
1610   Node* literal_index = jsgraph()->Constant(expr->literal_index());
1611   Node* pattern = jsgraph()->Constant(expr->pattern());
1612   Node* flags = jsgraph()->Constant(expr->flags());
1613   const Operator* op =
1614       javascript()->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1615   Node* literal = NewNode(op, literals_array, literal_index, pattern, flags);
1616   PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
1617   ast_context()->ProduceValue(literal);
1618 }
1619
1620
1621 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
1622   Node* closure = GetFunctionClosure();
1623
1624   // Create node to deep-copy the literal boilerplate.
1625   expr->BuildConstantProperties(isolate());
1626   Node* literals_array =
1627       BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
1628   Node* literal_index = jsgraph()->Constant(expr->literal_index());
1629   Node* constants = jsgraph()->Constant(expr->constant_properties());
1630   Node* flags = jsgraph()->Constant(expr->ComputeFlags(true));
1631   const Operator* op =
1632       javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4);
1633   Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
1634   PrepareFrameState(literal, expr->CreateLiteralId(),
1635                     OutputFrameStateCombine::Push());
1636
1637   // The object is expected on the operand stack during computation of the
1638   // property values and is the value of the entire expression.
1639   environment()->Push(literal);
1640
1641   // Mark all computed expressions that are bound to a key that is shadowed by
1642   // a later occurrence of the same key. For the marked expressions, no store
1643   // code is emitted.
1644   expr->CalculateEmitStore(zone());
1645
1646   // Create nodes to store computed values into the literal.
1647   int property_index = 0;
1648   AccessorTable accessor_table(zone());
1649   for (; property_index < expr->properties()->length(); property_index++) {
1650     ObjectLiteral::Property* property = expr->properties()->at(property_index);
1651     if (property->is_computed_name()) break;
1652     if (property->IsCompileTimeValue()) continue;
1653
1654     Literal* key = property->key()->AsLiteral();
1655     switch (property->kind()) {
1656       case ObjectLiteral::Property::CONSTANT:
1657         UNREACHABLE();
1658       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1659         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1660       // Fall through.
1661       case ObjectLiteral::Property::COMPUTED: {
1662         // It is safe to use [[Put]] here because the boilerplate already
1663         // contains computed properties with an uninitialized value.
1664         if (key->value()->IsInternalizedString()) {
1665           if (property->emit_store()) {
1666             VisitForValue(property->value());
1667             Node* value = environment()->Pop();
1668             Handle<Name> name = key->AsPropertyName();
1669             Node* store =
1670                 BuildNamedStore(literal, name, value, TypeFeedbackId::None());
1671             PrepareFrameState(store, key->id());
1672             BuildSetHomeObject(value, literal, property->value());
1673           } else {
1674             VisitForEffect(property->value());
1675           }
1676           break;
1677         }
1678         environment()->Push(literal);  // Duplicate receiver.
1679         VisitForValue(property->key());
1680         VisitForValue(property->value());
1681         Node* value = environment()->Pop();
1682         Node* key = environment()->Pop();
1683         Node* receiver = environment()->Pop();
1684         if (property->emit_store()) {
1685           Node* language = jsgraph()->Constant(SLOPPY);
1686           const Operator* op =
1687               javascript()->CallRuntime(Runtime::kSetProperty, 4);
1688           NewNode(op, receiver, key, value, language);
1689           BuildSetHomeObject(value, receiver, property->value());
1690         }
1691         break;
1692       }
1693       case ObjectLiteral::Property::PROTOTYPE: {
1694         environment()->Push(literal);  // Duplicate receiver.
1695         VisitForValue(property->value());
1696         Node* value = environment()->Pop();
1697         Node* receiver = environment()->Pop();
1698         DCHECK(property->emit_store());
1699         const Operator* op =
1700             javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
1701         Node* set_prototype = NewNode(op, receiver, value);
1702         // SetPrototype should not lazy deopt on an object literal.
1703         PrepareFrameState(set_prototype, BailoutId::None());
1704         break;
1705       }
1706       case ObjectLiteral::Property::GETTER:
1707         if (property->emit_store()) {
1708           accessor_table.lookup(key)->second->getter = property->value();
1709         }
1710         break;
1711       case ObjectLiteral::Property::SETTER:
1712         if (property->emit_store()) {
1713           accessor_table.lookup(key)->second->setter = property->value();
1714         }
1715         break;
1716     }
1717   }
1718
1719   // Create nodes to define accessors, using only a single call to the runtime
1720   // for each pair of corresponding getters and setters.
1721   for (AccessorTable::Iterator it = accessor_table.begin();
1722        it != accessor_table.end(); ++it) {
1723     VisitForValue(it->first);
1724     VisitForValueOrNull(it->second->getter);
1725     BuildSetHomeObject(environment()->Top(), literal, it->second->getter);
1726     VisitForValueOrNull(it->second->setter);
1727     BuildSetHomeObject(environment()->Top(), literal, it->second->setter);
1728     Node* setter = environment()->Pop();
1729     Node* getter = environment()->Pop();
1730     Node* name = environment()->Pop();
1731     Node* attr = jsgraph()->Constant(NONE);
1732     const Operator* op =
1733         javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1734     Node* call = NewNode(op, literal, name, getter, setter, attr);
1735     // This should not lazy deopt on a new literal.
1736     PrepareFrameState(call, BailoutId::None());
1737   }
1738
1739   // Object literals have two parts. The "static" part on the left contains no
1740   // computed property names, and so we can compute its map ahead of time; see
1741   // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
1742   // with the first computed property name and continues with all properties to
1743   // its right. All the code from above initializes the static component of the
1744   // object literal, and arranges for the map of the result to reflect the
1745   // static order in which the keys appear. For the dynamic properties, we
1746   // compile them into a series of "SetOwnProperty" runtime calls. This will
1747   // preserve insertion order.
1748   for (; property_index < expr->properties()->length(); property_index++) {
1749     ObjectLiteral::Property* property = expr->properties()->at(property_index);
1750
1751     environment()->Push(literal);  // Duplicate receiver.
1752     VisitForValue(property->key());
1753     Node* name = BuildToName(environment()->Pop(),
1754                              expr->GetIdForProperty(property_index));
1755     environment()->Push(name);
1756     // TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key should
1757     // not be on the operand stack while the value is being evaluated. Come up
1758     // with a repro for this and fix it. Also find a nice way to do so. :)
1759     VisitForValue(property->value());
1760     Node* value = environment()->Pop();
1761     Node* key = environment()->Pop();
1762     Node* receiver = environment()->Pop();
1763     BuildSetHomeObject(value, receiver, property->value());
1764
1765     switch (property->kind()) {
1766       case ObjectLiteral::Property::CONSTANT:
1767       case ObjectLiteral::Property::COMPUTED:
1768       case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
1769         Node* attr = jsgraph()->Constant(NONE);
1770         const Operator* op =
1771             javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1772         Node* call = NewNode(op, receiver, key, value, attr);
1773         PrepareFrameState(call, BailoutId::None());
1774         break;
1775       }
1776       case ObjectLiteral::Property::PROTOTYPE: {
1777         const Operator* op =
1778             javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
1779         Node* call = NewNode(op, receiver, value);
1780         PrepareFrameState(call, BailoutId::None());
1781         break;
1782       }
1783       case ObjectLiteral::Property::GETTER: {
1784         Node* attr = jsgraph()->Constant(NONE);
1785         const Operator* op = javascript()->CallRuntime(
1786             Runtime::kDefineGetterPropertyUnchecked, 4);
1787         Node* call = NewNode(op, receiver, key, value, attr);
1788         PrepareFrameState(call, BailoutId::None());
1789         break;
1790       }
1791       case ObjectLiteral::Property::SETTER: {
1792         Node* attr = jsgraph()->Constant(NONE);
1793         const Operator* op = javascript()->CallRuntime(
1794             Runtime::kDefineSetterPropertyUnchecked, 4);
1795         Node* call = NewNode(op, receiver, key, value, attr);
1796         PrepareFrameState(call, BailoutId::None());
1797         break;
1798       }
1799     }
1800   }
1801
1802   // Transform literals that contain functions to fast properties.
1803   if (expr->has_function()) {
1804     const Operator* op =
1805         javascript()->CallRuntime(Runtime::kToFastProperties, 1);
1806     NewNode(op, literal);
1807   }
1808
1809   ast_context()->ProduceValue(environment()->Pop());
1810 }
1811
1812
1813 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
1814   Node* closure = GetFunctionClosure();
1815
1816   // Create node to deep-copy the literal boilerplate.
1817   expr->BuildConstantElements(isolate());
1818   Node* literals_array =
1819       BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
1820   Node* literal_index = jsgraph()->Constant(expr->literal_index());
1821   Node* constants = jsgraph()->Constant(expr->constant_elements());
1822   Node* flags = jsgraph()->Constant(expr->ComputeFlags(true));
1823   const Operator* op =
1824       javascript()->CallRuntime(Runtime::kCreateArrayLiteral, 4);
1825   Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
1826   PrepareFrameState(literal, expr->CreateLiteralId(),
1827                     OutputFrameStateCombine::Push());
1828
1829   // The array and the literal index are both expected on the operand stack
1830   // during computation of the element values.
1831   environment()->Push(literal);
1832   environment()->Push(literal_index);
1833
1834   // Create nodes to evaluate all the non-constant subexpressions and to store
1835   // them into the newly cloned array.
1836   for (int i = 0; i < expr->values()->length(); i++) {
1837     Expression* subexpr = expr->values()->at(i);
1838     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1839
1840     VisitForValue(subexpr);
1841     Node* frame_state_before = environment()->Checkpoint(
1842         subexpr->id(), OutputFrameStateCombine::PokeAt(0));
1843     Node* value = environment()->Pop();
1844     Node* index = jsgraph()->Constant(i);
1845     Node* store =
1846         BuildKeyedStore(literal, index, value, TypeFeedbackId::None());
1847     PrepareFrameStateAfterAndBefore(store, expr->GetIdForElement(i),
1848                                     OutputFrameStateCombine::Ignore(),
1849                                     frame_state_before);
1850   }
1851
1852   environment()->Pop();  // Array literal index.
1853   ast_context()->ProduceValue(environment()->Pop());
1854 }
1855
1856
1857 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
1858                                            BailoutId bailout_id) {
1859   DCHECK(expr->IsValidReferenceExpression());
1860
1861   // Left-hand side can only be a property, a global or a variable slot.
1862   Property* property = expr->AsProperty();
1863   LhsKind assign_type = DetermineLhsKind(expr);
1864
1865   // Evaluate LHS expression and store the value.
1866   switch (assign_type) {
1867     case VARIABLE: {
1868       Variable* var = expr->AsVariableProxy()->var();
1869       BuildVariableAssignment(var, value, Token::ASSIGN, bailout_id);
1870       break;
1871     }
1872     case NAMED_PROPERTY: {
1873       environment()->Push(value);
1874       VisitForValue(property->obj());
1875       Node* object = environment()->Pop();
1876       value = environment()->Pop();
1877       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
1878       Node* store =
1879           BuildNamedStore(object, name, value, TypeFeedbackId::None());
1880       PrepareFrameState(store, bailout_id);
1881       break;
1882     }
1883     case KEYED_PROPERTY: {
1884       environment()->Push(value);
1885       VisitForValue(property->obj());
1886       VisitForValue(property->key());
1887       Node* key = environment()->Pop();
1888       Node* object = environment()->Pop();
1889       value = environment()->Pop();
1890       Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None());
1891       // TODO(jarin) Provide a real frame state before.
1892       PrepareFrameStateAfterAndBefore(store, bailout_id,
1893                                       OutputFrameStateCombine::Ignore(),
1894                                       jsgraph()->EmptyFrameState());
1895       break;
1896     }
1897   }
1898 }
1899
1900
1901 void AstGraphBuilder::VisitAssignment(Assignment* expr) {
1902   DCHECK(expr->target()->IsValidReferenceExpression());
1903
1904   // Left-hand side can only be a property, a global or a variable slot.
1905   Property* property = expr->target()->AsProperty();
1906   LhsKind assign_type = DetermineLhsKind(expr->target());
1907
1908   // Evaluate LHS expression.
1909   switch (assign_type) {
1910     case VARIABLE:
1911       // Nothing to do here.
1912       break;
1913     case NAMED_PROPERTY:
1914       VisitForValue(property->obj());
1915       break;
1916     case KEYED_PROPERTY: {
1917       VisitForValue(property->obj());
1918       VisitForValue(property->key());
1919       break;
1920     }
1921   }
1922
1923   // Evaluate the value and potentially handle compound assignments by loading
1924   // the left-hand side value and performing a binary operation.
1925   Node* frame_state_before_store = nullptr;
1926   bool needs_frame_state_before = (assign_type == KEYED_PROPERTY);
1927   if (expr->is_compound()) {
1928     Node* old_value = NULL;
1929     switch (assign_type) {
1930       case VARIABLE: {
1931         VariableProxy* proxy = expr->target()->AsVariableProxy();
1932         VectorSlotPair pair =
1933             CreateVectorSlotPair(proxy->VariableFeedbackSlot());
1934         old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair);
1935         break;
1936       }
1937       case NAMED_PROPERTY: {
1938         Node* object = environment()->Top();
1939         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
1940         VectorSlotPair pair =
1941             CreateVectorSlotPair(property->PropertyFeedbackSlot());
1942         old_value =
1943             BuildNamedLoad(object, name, pair, property->PropertyFeedbackId());
1944         PrepareFrameState(old_value, property->LoadId(),
1945                           OutputFrameStateCombine::Push());
1946         break;
1947       }
1948       case KEYED_PROPERTY: {
1949         Node* key = environment()->Top();
1950         Node* object = environment()->Peek(1);
1951         VectorSlotPair pair =
1952             CreateVectorSlotPair(property->PropertyFeedbackSlot());
1953         old_value =
1954             BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId());
1955         PrepareFrameState(old_value, property->LoadId(),
1956                           OutputFrameStateCombine::Push());
1957         break;
1958       }
1959     }
1960     environment()->Push(old_value);
1961     VisitForValue(expr->value());
1962     Node* frame_state_before = environment()->Checkpoint(expr->value()->id());
1963     Node* right = environment()->Pop();
1964     Node* left = environment()->Pop();
1965     Node* value = BuildBinaryOp(left, right, expr->binary_op());
1966     PrepareFrameStateAfterAndBefore(value, expr->binary_operation()->id(),
1967                                     OutputFrameStateCombine::Push(),
1968                                     frame_state_before);
1969     environment()->Push(value);
1970     if (needs_frame_state_before) {
1971       frame_state_before_store = environment()->Checkpoint(
1972           expr->binary_operation()->id(), OutputFrameStateCombine::PokeAt(0));
1973     }
1974   } else {
1975     VisitForValue(expr->value());
1976     if (needs_frame_state_before) {
1977       // This frame state can be used for lazy-deopting from a to-number
1978       // conversion if we are storing into a typed array. It is important
1979       // that the frame state is usable for such lazy deopt (i.e., it has
1980       // to specify how to override the value before the conversion, in this
1981       // case, it overwrites the stack top).
1982       frame_state_before_store = environment()->Checkpoint(
1983           expr->value()->id(), OutputFrameStateCombine::PokeAt(0));
1984     }
1985   }
1986
1987   // Store the value.
1988   Node* value = environment()->Pop();
1989   switch (assign_type) {
1990     case VARIABLE: {
1991       Variable* variable = expr->target()->AsVariableProxy()->var();
1992       BuildVariableAssignment(variable, value, expr->op(), expr->id(),
1993                               ast_context()->GetStateCombine());
1994       break;
1995     }
1996     case NAMED_PROPERTY: {
1997       Node* object = environment()->Pop();
1998       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
1999       Node* store =
2000           BuildNamedStore(object, name, value, expr->AssignmentFeedbackId());
2001       PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine());
2002       break;
2003     }
2004     case KEYED_PROPERTY: {
2005       Node* key = environment()->Pop();
2006       Node* object = environment()->Pop();
2007       Node* store =
2008           BuildKeyedStore(object, key, value, expr->AssignmentFeedbackId());
2009       PrepareFrameStateAfterAndBefore(store, expr->id(),
2010                                       ast_context()->GetStateCombine(),
2011                                       frame_state_before_store);
2012       break;
2013     }
2014   }
2015
2016   ast_context()->ProduceValue(value);
2017 }
2018
2019
2020 void AstGraphBuilder::VisitYield(Yield* expr) {
2021   // TODO(turbofan): Implement yield here.
2022   SetStackOverflow();
2023   ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
2024 }
2025
2026
2027 void AstGraphBuilder::VisitThrow(Throw* expr) {
2028   VisitForValue(expr->exception());
2029   Node* exception = environment()->Pop();
2030   Node* value = BuildThrowError(exception, expr->id());
2031   ast_context()->ProduceValue(value);
2032 }
2033
2034
2035 void AstGraphBuilder::VisitProperty(Property* expr) {
2036   Node* value;
2037   VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
2038   if (expr->key()->IsPropertyName()) {
2039     VisitForValue(expr->obj());
2040     Node* object = environment()->Pop();
2041     Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
2042     value = BuildNamedLoad(object, name, pair, expr->PropertyFeedbackId());
2043   } else {
2044     VisitForValue(expr->obj());
2045     VisitForValue(expr->key());
2046     Node* key = environment()->Pop();
2047     Node* object = environment()->Pop();
2048     value = BuildKeyedLoad(object, key, pair, expr->PropertyFeedbackId());
2049   }
2050   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2051   ast_context()->ProduceValue(value);
2052 }
2053
2054
2055 void AstGraphBuilder::VisitCall(Call* expr) {
2056   Expression* callee = expr->expression();
2057   Call::CallType call_type = expr->GetCallType(isolate());
2058
2059   // Prepare the callee and the receiver to the function call. This depends on
2060   // the semantics of the underlying call type.
2061   CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
2062   Node* receiver_value = NULL;
2063   Node* callee_value = NULL;
2064   bool possibly_eval = false;
2065   switch (call_type) {
2066     case Call::GLOBAL_CALL: {
2067       VariableProxy* proxy = callee->AsVariableProxy();
2068       VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2069       callee_value =
2070           BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
2071       receiver_value = jsgraph()->UndefinedConstant();
2072       break;
2073     }
2074     case Call::LOOKUP_SLOT_CALL: {
2075       Variable* variable = callee->AsVariableProxy()->var();
2076       DCHECK(variable->location() == Variable::LOOKUP);
2077       Node* name = jsgraph()->Constant(variable->name());
2078       const Operator* op =
2079           javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
2080       Node* pair = NewNode(op, current_context(), name);
2081       callee_value = NewNode(common()->Projection(0), pair);
2082       receiver_value = NewNode(common()->Projection(1), pair);
2083
2084       PrepareFrameState(pair, expr->EvalOrLookupId(),
2085                         OutputFrameStateCombine::Push(2));
2086       break;
2087     }
2088     case Call::PROPERTY_CALL: {
2089       Property* property = callee->AsProperty();
2090       VisitForValue(property->obj());
2091       Node* object = environment()->Top();
2092       VectorSlotPair pair =
2093           CreateVectorSlotPair(property->PropertyFeedbackSlot());
2094       if (property->key()->IsPropertyName()) {
2095         Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2096         callee_value =
2097             BuildNamedLoad(object, name, pair, property->PropertyFeedbackId());
2098       } else {
2099         VisitForValue(property->key());
2100         Node* key = environment()->Pop();
2101         callee_value =
2102             BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId());
2103       }
2104       PrepareFrameState(callee_value, property->LoadId(),
2105                         OutputFrameStateCombine::Push());
2106       receiver_value = environment()->Pop();
2107       // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
2108       // object for sloppy callees. This could also be modeled explicitly here,
2109       // thereby obsoleting the need for a flag to the call operator.
2110       flags = CALL_AS_METHOD;
2111       break;
2112     }
2113     case Call::SUPER_CALL:
2114       // TODO(dslomov): Implement super calls.
2115       callee_value = jsgraph()->UndefinedConstant();
2116       receiver_value = jsgraph()->UndefinedConstant();
2117       SetStackOverflow();
2118       break;
2119     case Call::POSSIBLY_EVAL_CALL:
2120       possibly_eval = true;
2121     // Fall through.
2122     case Call::OTHER_CALL:
2123       VisitForValue(callee);
2124       callee_value = environment()->Pop();
2125       receiver_value = jsgraph()->UndefinedConstant();
2126       break;
2127   }
2128
2129   // The callee and the receiver both have to be pushed onto the operand stack
2130   // before arguments are being evaluated.
2131   environment()->Push(callee_value);
2132   environment()->Push(receiver_value);
2133
2134   // Evaluate all arguments to the function call,
2135   ZoneList<Expression*>* args = expr->arguments();
2136   VisitForValues(args);
2137
2138   // Resolve callee and receiver for a potential direct eval call. This block
2139   // will mutate the callee and receiver values pushed onto the environment.
2140   if (possibly_eval && args->length() > 0) {
2141     int arg_count = args->length();
2142
2143     // Extract callee and source string from the environment.
2144     Node* callee = environment()->Peek(arg_count + 1);
2145     Node* source = environment()->Peek(arg_count - 1);
2146
2147     // Create node to ask for help resolving potential eval call. This will
2148     // provide a fully resolved callee and the corresponding receiver.
2149     Node* function = GetFunctionClosure();
2150     Node* receiver = environment()->Lookup(info()->scope()->receiver());
2151     Node* language = jsgraph()->Constant(language_mode());
2152     Node* position = jsgraph()->Constant(info()->scope()->start_position());
2153     const Operator* op =
2154         javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
2155     Node* pair =
2156         NewNode(op, callee, source, function, receiver, language, position);
2157     PrepareFrameState(pair, expr->EvalOrLookupId(),
2158                       OutputFrameStateCombine::PokeAt(arg_count + 1));
2159     Node* new_callee = NewNode(common()->Projection(0), pair);
2160     Node* new_receiver = NewNode(common()->Projection(1), pair);
2161
2162     // Patch callee and receiver on the environment.
2163     environment()->Poke(arg_count + 1, new_callee);
2164     environment()->Poke(arg_count + 0, new_receiver);
2165   }
2166
2167   // Create node to perform the function call.
2168   const Operator* call = javascript()->CallFunction(args->length() + 2, flags);
2169   Node* value = ProcessArguments(call, args->length() + 2);
2170   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2171   ast_context()->ProduceValue(value);
2172 }
2173
2174
2175 void AstGraphBuilder::VisitCallNew(CallNew* expr) {
2176   VisitForValue(expr->expression());
2177
2178   // Evaluate all arguments to the construct call.
2179   ZoneList<Expression*>* args = expr->arguments();
2180   VisitForValues(args);
2181
2182   // Create node to perform the construct call.
2183   const Operator* call = javascript()->CallConstruct(args->length() + 1);
2184   Node* value = ProcessArguments(call, args->length() + 1);
2185   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2186   ast_context()->ProduceValue(value);
2187 }
2188
2189
2190 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
2191   Handle<String> name = expr->name();
2192
2193   // The callee and the receiver both have to be pushed onto the operand stack
2194   // before arguments are being evaluated.
2195   CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
2196   Node* receiver_value = BuildLoadBuiltinsObject();
2197   VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot());
2198   Node* callee_value =
2199       BuildNamedLoad(receiver_value, name, pair, expr->CallRuntimeFeedbackId());
2200   // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
2201   // refuses to optimize functions with jsruntime calls).
2202   PrepareFrameState(callee_value, BailoutId::None(),
2203                     OutputFrameStateCombine::Push());
2204   environment()->Push(callee_value);
2205   environment()->Push(receiver_value);
2206
2207   // Evaluate all arguments to the JS runtime call.
2208   ZoneList<Expression*>* args = expr->arguments();
2209   VisitForValues(args);
2210
2211   // Create node to perform the JS runtime call.
2212   const Operator* call = javascript()->CallFunction(args->length() + 2, flags);
2213   Node* value = ProcessArguments(call, args->length() + 2);
2214   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2215   ast_context()->ProduceValue(value);
2216 }
2217
2218
2219 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
2220   const Runtime::Function* function = expr->function();
2221
2222   // Handle calls to runtime functions implemented in JavaScript separately as
2223   // the call follows JavaScript ABI and the callee is statically unknown.
2224   if (expr->is_jsruntime()) {
2225     DCHECK(function == NULL && expr->name()->length() > 0);
2226     return VisitCallJSRuntime(expr);
2227   }
2228
2229   // Evaluate all arguments to the runtime call.
2230   ZoneList<Expression*>* args = expr->arguments();
2231   VisitForValues(args);
2232
2233   // Create node to perform the runtime call.
2234   Runtime::FunctionId functionId = function->function_id;
2235   const Operator* call = javascript()->CallRuntime(functionId, args->length());
2236   Node* value = ProcessArguments(call, args->length());
2237   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2238   ast_context()->ProduceValue(value);
2239 }
2240
2241
2242 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
2243   switch (expr->op()) {
2244     case Token::DELETE:
2245       return VisitDelete(expr);
2246     case Token::VOID:
2247       return VisitVoid(expr);
2248     case Token::TYPEOF:
2249       return VisitTypeof(expr);
2250     case Token::NOT:
2251       return VisitNot(expr);
2252     default:
2253       UNREACHABLE();
2254   }
2255 }
2256
2257
2258 void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
2259   DCHECK(expr->expression()->IsValidReferenceExpression());
2260
2261   // Left-hand side can only be a property, a global or a variable slot.
2262   Property* property = expr->expression()->AsProperty();
2263   LhsKind assign_type = DetermineLhsKind(expr->expression());
2264
2265   // Reserve space for result of postfix operation.
2266   bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect();
2267   if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant());
2268
2269   // Evaluate LHS expression and get old value.
2270   Node* old_value = NULL;
2271   int stack_depth = -1;
2272   switch (assign_type) {
2273     case VARIABLE: {
2274       VariableProxy* proxy = expr->expression()->AsVariableProxy();
2275       VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2276       old_value =
2277           BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
2278       stack_depth = 0;
2279       break;
2280     }
2281     case NAMED_PROPERTY: {
2282       VisitForValue(property->obj());
2283       Node* object = environment()->Top();
2284       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2285       VectorSlotPair pair =
2286           CreateVectorSlotPair(property->PropertyFeedbackSlot());
2287       old_value =
2288           BuildNamedLoad(object, name, pair, property->PropertyFeedbackId());
2289       PrepareFrameState(old_value, property->LoadId(),
2290                         OutputFrameStateCombine::Push());
2291       stack_depth = 1;
2292       break;
2293     }
2294     case KEYED_PROPERTY: {
2295       VisitForValue(property->obj());
2296       VisitForValue(property->key());
2297       Node* key = environment()->Top();
2298       Node* object = environment()->Peek(1);
2299       VectorSlotPair pair =
2300           CreateVectorSlotPair(property->PropertyFeedbackSlot());
2301       old_value =
2302           BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId());
2303       PrepareFrameState(old_value, property->LoadId(),
2304                         OutputFrameStateCombine::Push());
2305       stack_depth = 2;
2306       break;
2307     }
2308   }
2309
2310   // Convert old value into a number.
2311   old_value = NewNode(javascript()->ToNumber(), old_value);
2312   PrepareFrameState(old_value, expr->ToNumberId(),
2313                     OutputFrameStateCombine::Push());
2314
2315   Node* frame_state_before_store =
2316       assign_type == KEYED_PROPERTY
2317           ? environment()->Checkpoint(expr->ToNumberId())
2318           : nullptr;
2319
2320   // Save result for postfix expressions at correct stack depth.
2321   if (is_postfix) environment()->Poke(stack_depth, old_value);
2322
2323   // Create node to perform +1/-1 operation.
2324   Node* value =
2325       BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
2326   // This should never deoptimize because we have converted to number
2327   // before.
2328   PrepareFrameStateAfterAndBefore(value, BailoutId::None(),
2329                                   OutputFrameStateCombine::Ignore(),
2330                                   jsgraph()->EmptyFrameState());
2331
2332   // Store the value.
2333   switch (assign_type) {
2334     case VARIABLE: {
2335       Variable* variable = expr->expression()->AsVariableProxy()->var();
2336       environment()->Push(value);
2337       BuildVariableAssignment(variable, value, expr->op(),
2338                               expr->AssignmentId());
2339       environment()->Pop();
2340       break;
2341     }
2342     case NAMED_PROPERTY: {
2343       Node* object = environment()->Pop();
2344       Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2345       Node* store =
2346           BuildNamedStore(object, name, value, expr->CountStoreFeedbackId());
2347       environment()->Push(value);
2348       PrepareFrameState(store, expr->AssignmentId());
2349       environment()->Pop();
2350       break;
2351     }
2352     case KEYED_PROPERTY: {
2353       Node* key = environment()->Pop();
2354       Node* object = environment()->Pop();
2355       Node* store =
2356           BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId());
2357       environment()->Push(value);
2358       PrepareFrameStateAfterAndBefore(store, expr->AssignmentId(),
2359                                       OutputFrameStateCombine::Ignore(),
2360                                       frame_state_before_store);
2361       environment()->Pop();
2362       break;
2363     }
2364   }
2365
2366   // Restore old value for postfix expressions.
2367   if (is_postfix) value = environment()->Pop();
2368
2369   ast_context()->ProduceValue(value);
2370 }
2371
2372
2373 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
2374   switch (expr->op()) {
2375     case Token::COMMA:
2376       return VisitComma(expr);
2377     case Token::OR:
2378     case Token::AND:
2379       return VisitLogicalExpression(expr);
2380     default: {
2381       VisitForValue(expr->left());
2382       VisitForValue(expr->right());
2383       Node* frame_state_before = environment()->Checkpoint(expr->right()->id());
2384       Node* right = environment()->Pop();
2385       Node* left = environment()->Pop();
2386       Node* value = BuildBinaryOp(left, right, expr->op());
2387       PrepareFrameStateAfterAndBefore(value, expr->id(),
2388                                       ast_context()->GetStateCombine(),
2389                                       frame_state_before);
2390       ast_context()->ProduceValue(value);
2391     }
2392   }
2393 }
2394
2395
2396 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
2397   const Operator* op;
2398   switch (expr->op()) {
2399     case Token::EQ:
2400       op = javascript()->Equal();
2401       break;
2402     case Token::NE:
2403       op = javascript()->NotEqual();
2404       break;
2405     case Token::EQ_STRICT:
2406       op = javascript()->StrictEqual();
2407       break;
2408     case Token::NE_STRICT:
2409       op = javascript()->StrictNotEqual();
2410       break;
2411     case Token::LT:
2412       op = javascript()->LessThan();
2413       break;
2414     case Token::GT:
2415       op = javascript()->GreaterThan();
2416       break;
2417     case Token::LTE:
2418       op = javascript()->LessThanOrEqual();
2419       break;
2420     case Token::GTE:
2421       op = javascript()->GreaterThanOrEqual();
2422       break;
2423     case Token::INSTANCEOF:
2424       op = javascript()->InstanceOf();
2425       break;
2426     case Token::IN:
2427       op = javascript()->HasProperty();
2428       break;
2429     default:
2430       op = NULL;
2431       UNREACHABLE();
2432   }
2433   VisitForValue(expr->left());
2434   VisitForValue(expr->right());
2435   Node* right = environment()->Pop();
2436   Node* left = environment()->Pop();
2437   Node* value = NewNode(op, left, right);
2438   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2439   ast_context()->ProduceValue(value);
2440 }
2441
2442
2443 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
2444   Node* value = GetFunctionClosure();
2445   ast_context()->ProduceValue(value);
2446 }
2447
2448
2449 void AstGraphBuilder::VisitSuperReference(SuperReference* expr) {
2450   // TODO(turbofan): Implement super here.
2451   SetStackOverflow();
2452   ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
2453 }
2454
2455
2456 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); }
2457
2458
2459 void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
2460   DCHECK(globals()->empty());
2461   AstVisitor::VisitDeclarations(declarations);
2462   if (globals()->empty()) return;
2463   int array_index = 0;
2464   Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
2465       static_cast<int>(globals()->size()), TENURED);
2466   for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
2467   int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
2468                       DeclareGlobalsNativeFlag::encode(info()->is_native()) |
2469                       DeclareGlobalsLanguageMode::encode(language_mode());
2470   Node* flags = jsgraph()->Constant(encoded_flags);
2471   Node* pairs = jsgraph()->Constant(data);
2472   const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 3);
2473   NewNode(op, current_context(), pairs, flags);
2474   globals()->clear();
2475 }
2476
2477
2478 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
2479   if (stmt == NULL) return;
2480   Visit(stmt);
2481 }
2482
2483
2484 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt,
2485                                          LoopBuilder* loop) {
2486   ControlScopeForIteration scope(this, stmt, loop);
2487   Visit(stmt->body());
2488 }
2489
2490
2491 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) {
2492   Node* value;
2493   if (expr->expression()->IsVariableProxy()) {
2494     // Delete of an unqualified identifier is only allowed in classic mode but
2495     // deleting "this" is allowed in all language modes.
2496     Variable* variable = expr->expression()->AsVariableProxy()->var();
2497     DCHECK(is_sloppy(language_mode()) || variable->is_this());
2498     value = BuildVariableDelete(variable, expr->id(),
2499                                 ast_context()->GetStateCombine());
2500   } else if (expr->expression()->IsProperty()) {
2501     Property* property = expr->expression()->AsProperty();
2502     VisitForValue(property->obj());
2503     VisitForValue(property->key());
2504     Node* key = environment()->Pop();
2505     Node* object = environment()->Pop();
2506     value = NewNode(javascript()->DeleteProperty(language_mode()), object, key);
2507     PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
2508   } else {
2509     VisitForEffect(expr->expression());
2510     value = jsgraph()->TrueConstant();
2511   }
2512   ast_context()->ProduceValue(value);
2513 }
2514
2515
2516 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) {
2517   VisitForEffect(expr->expression());
2518   Node* value = jsgraph()->UndefinedConstant();
2519   ast_context()->ProduceValue(value);
2520 }
2521
2522
2523 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
2524   Node* operand;
2525   if (expr->expression()->IsVariableProxy()) {
2526     // Typeof does not throw a reference error on global variables, hence we
2527     // perform a non-contextual load in case the operand is a variable proxy.
2528     VariableProxy* proxy = expr->expression()->AsVariableProxy();
2529     VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2530     operand = BuildVariableLoad(proxy->var(), expr->expression()->id(), pair,
2531                                 NOT_CONTEXTUAL);
2532   } else {
2533     VisitForValue(expr->expression());
2534     operand = environment()->Pop();
2535   }
2536   Node* value = NewNode(javascript()->TypeOf(), operand);
2537   ast_context()->ProduceValue(value);
2538 }
2539
2540
2541 void AstGraphBuilder::VisitNot(UnaryOperation* expr) {
2542   VisitForValue(expr->expression());
2543   Node* operand = environment()->Pop();
2544   // TODO(mstarzinger): Possible optimization when we are in effect context.
2545   Node* value = NewNode(javascript()->UnaryNot(), operand);
2546   ast_context()->ProduceValue(value);
2547 }
2548
2549
2550 void AstGraphBuilder::VisitComma(BinaryOperation* expr) {
2551   VisitForEffect(expr->left());
2552   Visit(expr->right());
2553   ast_context()->ReplaceValue();
2554 }
2555
2556
2557 void AstGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
2558   bool is_logical_and = expr->op() == Token::AND;
2559   IfBuilder compare_if(this);
2560   VisitForValue(expr->left());
2561   Node* condition = environment()->Top();
2562   compare_if.If(BuildToBoolean(condition));
2563   compare_if.Then();
2564   if (is_logical_and) {
2565     environment()->Pop();
2566     Visit(expr->right());
2567   } else if (ast_context()->IsEffect()) {
2568     environment()->Pop();
2569   }
2570   compare_if.Else();
2571   if (!is_logical_and) {
2572     environment()->Pop();
2573     Visit(expr->right());
2574   } else if (ast_context()->IsEffect()) {
2575     environment()->Pop();
2576   }
2577   compare_if.End();
2578   ast_context()->ReplaceValue();
2579 }
2580
2581
2582 LanguageMode AstGraphBuilder::language_mode() const {
2583   return info()->language_mode();
2584 }
2585
2586
2587 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
2588     FeedbackVectorICSlot slot) const {
2589   return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
2590 }
2591
2592
2593 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
2594   DCHECK(environment()->stack_height() >= arity);
2595   Node** all = info()->zone()->NewArray<Node*>(arity);
2596   for (int i = arity - 1; i >= 0; --i) {
2597     all[i] = environment()->Pop();
2598   }
2599   Node* value = NewNode(op, arity, all);
2600   return value;
2601 }
2602
2603
2604 Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
2605   // Sloppy mode functions and builtins need to replace the receiver with the
2606   // global proxy when called as functions (without an explicit receiver
2607   // object). Otherwise there is nothing left to do here.
2608   if (is_strict(language_mode()) || info()->is_native()) return receiver;
2609
2610   // There is no need to perform patching if the receiver is never used. Note
2611   // that scope predicates are purely syntactical, a call to eval might still
2612   // inspect the receiver value.
2613   if (!info()->scope()->uses_this() && !info()->scope()->inner_uses_this() &&
2614       !info()->scope()->calls_sloppy_eval()) {
2615     return receiver;
2616   }
2617
2618   IfBuilder receiver_check(this);
2619   Node* undefined = jsgraph()->UndefinedConstant();
2620   Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined);
2621   receiver_check.If(check);
2622   receiver_check.Then();
2623   Node* proxy = BuildLoadGlobalProxy();
2624   environment()->Push(proxy);
2625   receiver_check.Else();
2626   environment()->Push(receiver);
2627   receiver_check.End();
2628   return environment()->Pop();
2629 }
2630
2631
2632 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
2633   // Allocate a new local context.
2634   const Operator* op = javascript()->CreateFunctionContext();
2635   Node* local_context = NewNode(op, closure);
2636
2637   // Copy parameters into context if necessary.
2638   int num_parameters = info()->scope()->num_parameters();
2639   for (int i = 0; i < num_parameters; i++) {
2640     Variable* variable = info()->scope()->parameter(i);
2641     if (!variable->IsContextSlot()) continue;
2642     // Temporary parameter node. The parameter indices are shifted by 1
2643     // (receiver is parameter index -1 but environment index 0).
2644     Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start());
2645     // Context variable (at bottom of the context chain).
2646     DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope()));
2647     const Operator* op = javascript()->StoreContext(0, variable->index());
2648     NewNode(op, local_context, parameter);
2649   }
2650
2651   return local_context;
2652 }
2653
2654
2655 Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) {
2656   Node* closure = GetFunctionClosure();
2657
2658   // Allocate a new local context.
2659   const Operator* op = javascript()->CreateBlockContext();
2660   Node* scope_info = jsgraph()->Constant(scope->GetScopeInfo(info_->isolate()));
2661   Node* local_context = NewNode(op, scope_info, closure);
2662
2663   return local_context;
2664 }
2665
2666
2667 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
2668   if (arguments == NULL) return NULL;
2669
2670   // Allocate and initialize a new arguments object.
2671   Node* callee = GetFunctionClosure();
2672   const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1);
2673   Node* object = NewNode(op, callee);
2674
2675   // Assign the object to the arguments variable.
2676   DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
2677   // This should never lazy deopt, so it is fine to send invalid bailout id.
2678   BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None());
2679
2680   return object;
2681 }
2682
2683
2684 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) {
2685   if (rest == NULL) return NULL;
2686
2687   DCHECK(index >= 0);
2688   const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 1);
2689   Node* object = NewNode(op, jsgraph()->SmiConstant(index));
2690
2691   // Assign the object to the rest array
2692   DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
2693   // This should never lazy deopt, so it is fine to send invalid bailout id.
2694   BuildVariableAssignment(rest, object, Token::ASSIGN, BailoutId::None());
2695
2696   return object;
2697 }
2698
2699
2700 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole,
2701                                             Node* not_hole) {
2702   IfBuilder hole_check(this);
2703   Node* the_hole = jsgraph()->TheHoleConstant();
2704   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
2705   hole_check.If(check);
2706   hole_check.Then();
2707   environment()->Push(for_hole);
2708   hole_check.Else();
2709   environment()->Push(not_hole);
2710   hole_check.End();
2711   return environment()->Pop();
2712 }
2713
2714
2715 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable,
2716                                            Node* not_hole,
2717                                            BailoutId bailout_id) {
2718   IfBuilder hole_check(this);
2719   Node* the_hole = jsgraph()->TheHoleConstant();
2720   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
2721   hole_check.If(check);
2722   hole_check.Then();
2723   Node* error = BuildThrowReferenceError(variable, bailout_id);
2724   environment()->Push(error);
2725   hole_check.Else();
2726   environment()->Push(not_hole);
2727   hole_check.End();
2728   return environment()->Pop();
2729 }
2730
2731
2732 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
2733                                                    BailoutId bailout_id) {
2734   IfBuilder prototype_check(this);
2735   Node* prototype_string =
2736       jsgraph()->Constant(isolate()->factory()->prototype_string());
2737   Node* check = NewNode(javascript()->StrictEqual(), name, prototype_string);
2738   prototype_check.If(check);
2739   prototype_check.Then();
2740   {
2741     const Operator* op =
2742         javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError, 0);
2743     Node* call = NewNode(op);
2744     PrepareFrameState(call, bailout_id);
2745     environment()->Push(call);
2746   }
2747   prototype_check.Else();
2748   environment()->Push(name);
2749   prototype_check.End();
2750   return environment()->Pop();
2751 }
2752
2753
2754 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
2755                                          BailoutId bailout_id,
2756                                          const VectorSlotPair& feedback,
2757                                          ContextualMode contextual_mode) {
2758   Node* the_hole = jsgraph()->TheHoleConstant();
2759   VariableMode mode = variable->mode();
2760   switch (variable->location()) {
2761     case Variable::UNALLOCATED: {
2762       // Global var, const, or let variable.
2763       Node* global = BuildLoadGlobalObject();
2764       Handle<Name> name = variable->name();
2765       Node* node = BuildNamedLoad(global, name, feedback,
2766                                   TypeFeedbackId::None(), contextual_mode);
2767       PrepareFrameState(node, bailout_id, OutputFrameStateCombine::Push());
2768       return node;
2769     }
2770     case Variable::PARAMETER:
2771     case Variable::LOCAL: {
2772       // Local var, const, or let variable.
2773       Node* value = environment()->Lookup(variable);
2774       if (mode == CONST_LEGACY) {
2775         // Perform check for uninitialized legacy const variables.
2776         if (value->op() == the_hole->op()) {
2777           value = jsgraph()->UndefinedConstant();
2778         } else if (value->opcode() == IrOpcode::kPhi) {
2779           Node* undefined = jsgraph()->UndefinedConstant();
2780           value = BuildHoleCheckSilent(value, undefined, value);
2781         }
2782       } else if (mode == LET || mode == CONST) {
2783         // Perform check for uninitialized let/const variables.
2784         if (value->op() == the_hole->op()) {
2785           value = BuildThrowReferenceError(variable, bailout_id);
2786         } else if (value->opcode() == IrOpcode::kPhi) {
2787           value = BuildHoleCheckThrow(value, variable, value, bailout_id);
2788         }
2789       }
2790       return value;
2791     }
2792     case Variable::CONTEXT: {
2793       // Context variable (potentially up the context chain).
2794       int depth = current_scope()->ContextChainLength(variable->scope());
2795       bool immutable = variable->maybe_assigned() == kNotAssigned;
2796       const Operator* op =
2797           javascript()->LoadContext(depth, variable->index(), immutable);
2798       Node* value = NewNode(op, current_context());
2799       // TODO(titzer): initialization checks are redundant for already
2800       // initialized immutable context loads, but only specialization knows.
2801       // Maybe specializer should be a parameter to the graph builder?
2802       if (mode == CONST_LEGACY) {
2803         // Perform check for uninitialized legacy const variables.
2804         Node* undefined = jsgraph()->UndefinedConstant();
2805         value = BuildHoleCheckSilent(value, undefined, value);
2806       } else if (mode == LET || mode == CONST) {
2807         // Perform check for uninitialized let/const variables.
2808         value = BuildHoleCheckThrow(value, variable, value, bailout_id);
2809       }
2810       return value;
2811     }
2812     case Variable::LOOKUP: {
2813       // Dynamic lookup of context variable (anywhere in the chain).
2814       Node* name = jsgraph()->Constant(variable->name());
2815       Runtime::FunctionId function_id =
2816           (contextual_mode == CONTEXTUAL)
2817               ? Runtime::kLoadLookupSlot
2818               : Runtime::kLoadLookupSlotNoReferenceError;
2819       const Operator* op = javascript()->CallRuntime(function_id, 2);
2820       Node* pair = NewNode(op, current_context(), name);
2821       PrepareFrameState(pair, bailout_id, OutputFrameStateCombine::Push(1));
2822       return NewNode(common()->Projection(0), pair);
2823     }
2824   }
2825   UNREACHABLE();
2826   return NULL;
2827 }
2828
2829
2830 Node* AstGraphBuilder::BuildVariableDelete(
2831     Variable* variable, BailoutId bailout_id,
2832     OutputFrameStateCombine state_combine) {
2833   switch (variable->location()) {
2834     case Variable::UNALLOCATED: {
2835       // Global var, const, or let variable.
2836       Node* global = BuildLoadGlobalObject();
2837       Node* name = jsgraph()->Constant(variable->name());
2838       const Operator* op = javascript()->DeleteProperty(language_mode());
2839       Node* result = NewNode(op, global, name);
2840       PrepareFrameState(result, bailout_id, state_combine);
2841       return result;
2842     }
2843     case Variable::PARAMETER:
2844     case Variable::LOCAL:
2845     case Variable::CONTEXT:
2846       // Local var, const, or let variable or context variable.
2847       return jsgraph()->BooleanConstant(variable->is_this());
2848     case Variable::LOOKUP: {
2849       // Dynamic lookup of context variable (anywhere in the chain).
2850       Node* name = jsgraph()->Constant(variable->name());
2851       const Operator* op =
2852           javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
2853       Node* result = NewNode(op, current_context(), name);
2854       PrepareFrameState(result, bailout_id, state_combine);
2855       return result;
2856     }
2857   }
2858   UNREACHABLE();
2859   return NULL;
2860 }
2861
2862
2863 Node* AstGraphBuilder::BuildVariableAssignment(
2864     Variable* variable, Node* value, Token::Value op, BailoutId bailout_id,
2865     OutputFrameStateCombine combine) {
2866   Node* the_hole = jsgraph()->TheHoleConstant();
2867   VariableMode mode = variable->mode();
2868   switch (variable->location()) {
2869     case Variable::UNALLOCATED: {
2870       // Global var, const, or let variable.
2871       Node* global = BuildLoadGlobalObject();
2872       Handle<Name> name = variable->name();
2873       Node* store =
2874           BuildNamedStore(global, name, value, TypeFeedbackId::None());
2875       PrepareFrameState(store, bailout_id, combine);
2876       return store;
2877     }
2878     case Variable::PARAMETER:
2879     case Variable::LOCAL:
2880       // Local var, const, or let variable.
2881       if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
2882         // Perform an initialization check for legacy const variables.
2883         Node* current = environment()->Lookup(variable);
2884         if (current->op() != the_hole->op()) {
2885           value = BuildHoleCheckSilent(current, value, current);
2886         }
2887       } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
2888         // Non-initializing assignment to legacy const is
2889         // - exception in strict mode.
2890         // - ignored in sloppy mode.
2891         if (is_strict(language_mode())) {
2892           return BuildThrowConstAssignError(bailout_id);
2893         }
2894         return value;
2895       } else if (mode == LET && op != Token::INIT_LET) {
2896         // Perform an initialization check for let declared variables.
2897         // Also note that the dynamic hole-check is only done to ensure that
2898         // this does not break in the presence of do-expressions within the
2899         // temporal dead zone of a let declared variable.
2900         Node* current = environment()->Lookup(variable);
2901         if (current->op() == the_hole->op()) {
2902           value = BuildThrowReferenceError(variable, bailout_id);
2903         } else if (value->opcode() == IrOpcode::kPhi) {
2904           value = BuildHoleCheckThrow(current, variable, value, bailout_id);
2905         }
2906       } else if (mode == CONST && op != Token::INIT_CONST) {
2907         // Assignment to const is exception in all modes.
2908         Node* current = environment()->Lookup(variable);
2909         if (current->op() == the_hole->op()) {
2910           return BuildThrowReferenceError(variable, bailout_id);
2911         } else if (value->opcode() == IrOpcode::kPhi) {
2912           BuildHoleCheckThrow(current, variable, value, bailout_id);
2913         }
2914         return BuildThrowConstAssignError(bailout_id);
2915       }
2916       environment()->Bind(variable, value);
2917       return value;
2918     case Variable::CONTEXT: {
2919       // Context variable (potentially up the context chain).
2920       int depth = current_scope()->ContextChainLength(variable->scope());
2921       if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
2922         // Perform an initialization check for legacy const variables.
2923         const Operator* op =
2924             javascript()->LoadContext(depth, variable->index(), false);
2925         Node* current = NewNode(op, current_context());
2926         value = BuildHoleCheckSilent(current, value, current);
2927       } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
2928         // Non-initializing assignment to legacy const is
2929         // - exception in strict mode.
2930         // - ignored in sloppy mode.
2931         if (is_strict(language_mode())) {
2932           return BuildThrowConstAssignError(bailout_id);
2933         }
2934         return value;
2935       } else if (mode == LET && op != Token::INIT_LET) {
2936         // Perform an initialization check for let declared variables.
2937         const Operator* op =
2938             javascript()->LoadContext(depth, variable->index(), false);
2939         Node* current = NewNode(op, current_context());
2940         value = BuildHoleCheckThrow(current, variable, value, bailout_id);
2941       } else if (mode == CONST && op != Token::INIT_CONST) {
2942         // Assignment to const is exception in all modes.
2943         const Operator* op =
2944             javascript()->LoadContext(depth, variable->index(), false);
2945         Node* current = NewNode(op, current_context());
2946         BuildHoleCheckThrow(current, variable, value, bailout_id);
2947         return BuildThrowConstAssignError(bailout_id);
2948       }
2949       const Operator* op = javascript()->StoreContext(depth, variable->index());
2950       return NewNode(op, current_context(), value);
2951     }
2952     case Variable::LOOKUP: {
2953       // Dynamic lookup of context variable (anywhere in the chain).
2954       Node* name = jsgraph()->Constant(variable->name());
2955       Node* language = jsgraph()->Constant(language_mode());
2956       // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
2957       // initializations of const declarations.
2958       const Operator* op =
2959           javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
2960       Node* store = NewNode(op, value, current_context(), name, language);
2961       PrepareFrameState(store, bailout_id, combine);
2962       return store;
2963     }
2964   }
2965   UNREACHABLE();
2966   return NULL;
2967 }
2968
2969
2970 static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node,
2971                            TypeFeedbackId id) {
2972   if (js_type_feedback) js_type_feedback->Record(node, id);
2973   return node;
2974 }
2975
2976
2977 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
2978                                       const VectorSlotPair& feedback,
2979                                       TypeFeedbackId id) {
2980   const Operator* op = javascript()->LoadProperty(feedback);
2981   return Record(js_type_feedback_, NewNode(op, object, key), id);
2982 }
2983
2984
2985 Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
2986                                       const VectorSlotPair& feedback,
2987                                       TypeFeedbackId id, ContextualMode mode) {
2988   const Operator* op =
2989       javascript()->LoadNamed(MakeUnique(name), feedback, mode);
2990   return Record(js_type_feedback_, NewNode(op, object), id);
2991 }
2992
2993
2994 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
2995                                        TypeFeedbackId id) {
2996   const Operator* op = javascript()->StoreProperty(language_mode());
2997   return Record(js_type_feedback_, NewNode(op, object, key, value), id);
2998 }
2999
3000
3001 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
3002                                        Node* value, TypeFeedbackId id) {
3003   const Operator* op =
3004       javascript()->StoreNamed(language_mode(), MakeUnique(name));
3005   return Record(js_type_feedback_, NewNode(op, object, value), id);
3006 }
3007
3008
3009 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
3010   return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
3011                  jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
3012 }
3013
3014
3015 Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
3016   Node* global = BuildLoadGlobalObject();
3017   Node* builtins =
3018       BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
3019   return builtins;
3020 }
3021
3022
3023 Node* AstGraphBuilder::BuildLoadGlobalObject() {
3024   const Operator* load_op =
3025       javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
3026   return NewNode(load_op, function_context_.get());
3027 }
3028
3029
3030 Node* AstGraphBuilder::BuildLoadGlobalProxy() {
3031   Node* global = BuildLoadGlobalObject();
3032   Node* proxy =
3033       BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset);
3034   return proxy;
3035 }
3036
3037
3038 Node* AstGraphBuilder::BuildLoadExternal(ExternalReference reference,
3039                                          MachineType type) {
3040   return NewNode(jsgraph()->machine()->Load(type),
3041                  jsgraph()->ExternalConstant(reference),
3042                  jsgraph()->IntPtrConstant(0));
3043 }
3044
3045
3046 Node* AstGraphBuilder::BuildStoreExternal(ExternalReference reference,
3047                                           MachineType type, Node* value) {
3048   StoreRepresentation representation(type, kNoWriteBarrier);
3049   return NewNode(jsgraph()->machine()->Store(representation),
3050                  jsgraph()->ExternalConstant(reference),
3051                  jsgraph()->IntPtrConstant(0), value);
3052 }
3053
3054
3055 Node* AstGraphBuilder::BuildToBoolean(Node* input) {
3056   // TODO(titzer): This should be in a JSOperatorReducer.
3057   switch (input->opcode()) {
3058     case IrOpcode::kInt32Constant:
3059       return jsgraph_->BooleanConstant(!Int32Matcher(input).Is(0));
3060     case IrOpcode::kFloat64Constant:
3061       return jsgraph_->BooleanConstant(!Float64Matcher(input).Is(0));
3062     case IrOpcode::kNumberConstant:
3063       return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0));
3064     case IrOpcode::kHeapConstant: {
3065       Handle<Object> object = HeapObjectMatcher<Object>(input).Value().handle();
3066       return jsgraph_->BooleanConstant(object->BooleanValue());
3067     }
3068     default:
3069       break;
3070   }
3071   if (NodeProperties::IsTyped(input)) {
3072     Type* upper = NodeProperties::GetBounds(input).upper;
3073     if (upper->Is(Type::Boolean())) return input;
3074   }
3075
3076   return NewNode(javascript()->ToBoolean(), input);
3077 }
3078
3079
3080 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) {
3081   // TODO(turbofan): Possible optimization is to NOP on name constants. But the
3082   // same caveat as with BuildToBoolean applies, and it should be factored out
3083   // into a JSOperatorReducer.
3084   Node* name = NewNode(javascript()->ToName(), input);
3085   PrepareFrameState(name, bailout_id);
3086   return name;
3087 }
3088
3089
3090 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
3091                                           Expression* expr) {
3092   if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
3093   Handle<Name> name = isolate()->factory()->home_object_symbol();
3094   Node* store =
3095       BuildNamedStore(value, name, home_object, TypeFeedbackId::None());
3096   PrepareFrameState(store, BailoutId::None());
3097   return store;
3098 }
3099
3100
3101 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) {
3102   const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1);
3103   Node* call = NewNode(op, exception);
3104   PrepareFrameState(call, bailout_id);
3105   return call;
3106 }
3107
3108
3109 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
3110                                                 BailoutId bailout_id) {
3111   Node* variable_name = jsgraph()->Constant(variable->name());
3112   const Operator* op =
3113       javascript()->CallRuntime(Runtime::kThrowReferenceError, 1);
3114   Node* call = NewNode(op, variable_name);
3115   PrepareFrameState(call, bailout_id);
3116   return call;
3117 }
3118
3119
3120 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
3121   const Operator* op =
3122       javascript()->CallRuntime(Runtime::kThrowConstAssignError, 0);
3123   Node* call = NewNode(op);
3124   PrepareFrameState(call, bailout_id);
3125   return call;
3126 }
3127
3128
3129 Node* AstGraphBuilder::BuildReturn(Node* return_value) {
3130   Node* control = NewNode(common()->Return(), return_value);
3131   UpdateControlDependencyToLeaveFunction(control);
3132   return control;
3133 }
3134
3135
3136 Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
3137   NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value);
3138   Node* control = NewNode(common()->Throw(), exception_value);
3139   UpdateControlDependencyToLeaveFunction(control);
3140   return control;
3141 }
3142
3143
3144 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
3145   const Operator* js_op;
3146   switch (op) {
3147     case Token::BIT_OR:
3148       js_op = javascript()->BitwiseOr();
3149       break;
3150     case Token::BIT_AND:
3151       js_op = javascript()->BitwiseAnd();
3152       break;
3153     case Token::BIT_XOR:
3154       js_op = javascript()->BitwiseXor();
3155       break;
3156     case Token::SHL:
3157       js_op = javascript()->ShiftLeft();
3158       break;
3159     case Token::SAR:
3160       js_op = javascript()->ShiftRight();
3161       break;
3162     case Token::SHR:
3163       js_op = javascript()->ShiftRightLogical();
3164       break;
3165     case Token::ADD:
3166       js_op = javascript()->Add();
3167       break;
3168     case Token::SUB:
3169       js_op = javascript()->Subtract();
3170       break;
3171     case Token::MUL:
3172       js_op = javascript()->Multiply();
3173       break;
3174     case Token::DIV:
3175       js_op = javascript()->Divide();
3176       break;
3177     case Token::MOD:
3178       js_op = javascript()->Modulus();
3179       break;
3180     default:
3181       UNREACHABLE();
3182       js_op = NULL;
3183   }
3184   return NewNode(js_op, left, right);
3185 }
3186
3187
3188 bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
3189   if (info()->osr_ast_id() == stmt->OsrEntryId()) {
3190     info()->set_osr_expr_stack_height(std::max(
3191         environment()->stack_height(), info()->osr_expr_stack_height()));
3192     return true;
3193   }
3194   return false;
3195 }
3196
3197
3198 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
3199                                         OutputFrameStateCombine combine) {
3200   if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
3201     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
3202
3203     DCHECK_EQ(IrOpcode::kDead,
3204               NodeProperties::GetFrameStateInput(node, 0)->opcode());
3205     NodeProperties::ReplaceFrameStateInput(
3206         node, 0, environment()->Checkpoint(ast_id, combine));
3207   }
3208 }
3209
3210
3211 void AstGraphBuilder::PrepareFrameStateAfterAndBefore(
3212     Node* node, BailoutId ast_id, OutputFrameStateCombine combine,
3213     Node* frame_state_before) {
3214   if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
3215     DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
3216
3217     DCHECK_EQ(IrOpcode::kDead,
3218               NodeProperties::GetFrameStateInput(node, 0)->opcode());
3219     NodeProperties::ReplaceFrameStateInput(
3220         node, 0, environment()->Checkpoint(ast_id, combine));
3221
3222     DCHECK_EQ(IrOpcode::kDead,
3223               NodeProperties::GetFrameStateInput(node, 1)->opcode());
3224     NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before);
3225   }
3226 }
3227
3228
3229 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
3230     IterationStatement* stmt) {
3231   if (loop_assignment_analysis_ == NULL) return NULL;
3232   return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
3233 }
3234
3235
3236 Node** AstGraphBuilder::EnsureInputBufferSize(int size) {
3237   if (size > input_buffer_size_) {
3238     size = size + kInputBufferSizeIncrement + input_buffer_size_;
3239     input_buffer_ = local_zone()->NewArray<Node*>(size);
3240     input_buffer_size_ = size;
3241   }
3242   return input_buffer_;
3243 }
3244
3245
3246 Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
3247                                 Node** value_inputs, bool incomplete) {
3248   DCHECK(op->ValueInputCount() == value_input_count);
3249
3250   bool has_context = OperatorProperties::HasContextInput(op);
3251   int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
3252   bool has_control = op->ControlInputCount() == 1;
3253   bool has_effect = op->EffectInputCount() == 1;
3254
3255   DCHECK(op->ControlInputCount() < 2);
3256   DCHECK(op->EffectInputCount() < 2);
3257
3258   Node* result = NULL;
3259   if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
3260     result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
3261   } else {
3262     bool inside_try_scope = try_nesting_level_ > 0;
3263     int input_count_with_deps = value_input_count;
3264     if (has_context) ++input_count_with_deps;
3265     input_count_with_deps += frame_state_count;
3266     if (has_control) ++input_count_with_deps;
3267     if (has_effect) ++input_count_with_deps;
3268     Node** buffer = EnsureInputBufferSize(input_count_with_deps);
3269     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
3270     Node** current_input = buffer + value_input_count;
3271     if (has_context) {
3272       *current_input++ = current_context();
3273     }
3274     for (int i = 0; i < frame_state_count; i++) {
3275       // The frame state will be inserted later. Here we misuse
3276       // the {DeadControl} node as a sentinel to be later overwritten
3277       // with the real frame state.
3278       *current_input++ = jsgraph()->DeadControl();
3279     }
3280     if (has_effect) {
3281       *current_input++ = environment_->GetEffectDependency();
3282     }
3283     if (has_control) {
3284       *current_input++ = environment_->GetControlDependency();
3285     }
3286     result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
3287     if (has_effect) {
3288       environment_->UpdateEffectDependency(result);
3289     }
3290     if (!environment()->IsMarkedAsUnreachable()) {
3291       // Update the current control dependency for control-producing nodes.
3292       if (NodeProperties::IsControl(result)) {
3293         environment_->UpdateControlDependency(result);
3294       }
3295       // Add implicit exception continuation for throwing nodes.
3296       if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
3297         Node* on_exception = graph()->NewNode(common()->IfException(), result);
3298         environment_->UpdateControlDependency(on_exception);
3299         execution_control()->ThrowValue(result);
3300       }
3301       // Add implicit success continuation for throwing nodes.
3302       if (!result->op()->HasProperty(Operator::kNoThrow)) {
3303         Node* on_success = graph()->NewNode(common()->IfSuccess(), result);
3304         environment_->UpdateControlDependency(on_success);
3305       }
3306     }
3307   }
3308
3309   return result;
3310 }
3311
3312
3313 void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
3314   if (environment()->IsMarkedAsUnreachable()) return;
3315   if (exit_control() != NULL) {
3316     exit = MergeControl(exit_control(), exit);
3317   }
3318   environment()->MarkAsUnreachable();
3319   set_exit_control(exit);
3320 }
3321
3322
3323 void AstGraphBuilder::Environment::Merge(Environment* other) {
3324   DCHECK(values_.size() == other->values_.size());
3325   // TODO(titzer): make context stack heights match.
3326   DCHECK(contexts_.size() <= other->contexts_.size());
3327
3328   // Nothing to do if the other environment is dead.
3329   if (other->IsMarkedAsUnreachable()) return;
3330
3331   // Resurrect a dead environment by copying the contents of the other one and
3332   // placing a singleton merge as the new control dependency.
3333   if (this->IsMarkedAsUnreachable()) {
3334     Node* other_control = other->control_dependency_;
3335     Node* inputs[] = {other_control};
3336     liveness_block_ = other->liveness_block_;
3337     control_dependency_ =
3338         graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
3339     effect_dependency_ = other->effect_dependency_;
3340     values_ = other->values_;
3341     // TODO(titzer): make context stack heights match.
3342     size_t min = std::min(contexts_.size(), other->contexts_.size());
3343     contexts_ = other->contexts_;
3344     contexts_.resize(min, nullptr);
3345     return;
3346   }
3347
3348   // Record the merge for the local variable liveness calculation.
3349   // Unfortunately, we have to mirror the logic in the MergeControl method:
3350   // connect before merge or loop, or create a new merge otherwise.
3351   if (FLAG_analyze_environment_liveness) {
3352     if (GetControlDependency()->opcode() != IrOpcode::kLoop &&
3353         GetControlDependency()->opcode() != IrOpcode::kMerge) {
3354       liveness_block_ =
3355           builder_->liveness_analyzer()->NewBlock(liveness_block());
3356     }
3357     liveness_block()->AddPredecessor(other->liveness_block());
3358   }
3359
3360   // Create a merge of the control dependencies of both environments and update
3361   // the current environment's control dependency accordingly.
3362   Node* control = builder_->MergeControl(this->GetControlDependency(),
3363                                          other->GetControlDependency());
3364   UpdateControlDependency(control);
3365
3366   // Create a merge of the effect dependencies of both environments and update
3367   // the current environment's effect dependency accordingly.
3368   Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
3369                                        other->GetEffectDependency(), control);
3370   UpdateEffectDependency(effect);
3371
3372   // Introduce Phi nodes for values that have differing input at merge points,
3373   // potentially extending an existing Phi node if possible.
3374   for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
3375     values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
3376   }
3377   for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) {
3378     contexts_[i] =
3379         builder_->MergeValue(contexts_[i], other->contexts_[i], control);
3380   }
3381 }
3382
3383
3384 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
3385                                                   bool is_osr) {
3386   int size = static_cast<int>(values()->size());
3387
3388   Node* control = builder_->NewLoop();
3389   if (assigned == nullptr) {
3390     // Assume that everything is updated in the loop.
3391     for (int i = 0; i < size; ++i) {
3392       values()->at(i) = builder_->NewPhi(1, values()->at(i), control);
3393     }
3394   } else {
3395     // Only build phis for those locals assigned in this loop.
3396     for (int i = 0; i < size; ++i) {
3397       if (i < assigned->length() && !assigned->Contains(i)) continue;
3398       Node* phi = builder_->NewPhi(1, values()->at(i), control);
3399       values()->at(i) = phi;
3400     }
3401   }
3402   Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
3403   UpdateEffectDependency(effect);
3404
3405   if (builder_->info()->is_osr()) {
3406     // Introduce phis for all context values in the case of an OSR graph.
3407     for (int i = 0; i < static_cast<int>(contexts()->size()); ++i) {
3408       Node* val = contexts()->at(i);
3409       if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3410         contexts()->at(i) = builder_->NewPhi(1, val, control);
3411       }
3412     }
3413   }
3414
3415   if (is_osr) {
3416     // Merge OSR values as inputs to the phis of the loop.
3417     Graph* graph = builder_->graph();
3418     Node* osr_loop_entry = builder_->graph()->NewNode(
3419         builder_->common()->OsrLoopEntry(), graph->start(), graph->start());
3420
3421     builder_->MergeControl(control, osr_loop_entry);
3422     builder_->MergeEffect(effect, osr_loop_entry, control);
3423
3424     for (int i = 0; i < size; ++i) {
3425       Node* val = values()->at(i);
3426       if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3427         Node* osr_value =
3428             graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
3429         values()->at(i) = builder_->MergeValue(val, osr_value, control);
3430       }
3431     }
3432
3433     // Rename all the contexts in the environment.
3434     // The innermost context is the OSR value, and the outer contexts are
3435     // reconstructed by dynamically walking up the context chain.
3436     Node* osr_context = nullptr;
3437     const Operator* op =
3438         builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
3439     int last = static_cast<int>(contexts()->size() - 1);
3440     for (int i = last; i >= 0; i--) {
3441       Node* val = contexts()->at(i);
3442       if (!IrOpcode::IsConstantOpcode(val->opcode())) {
3443         osr_context = (i == last) ? builder_->NewCurrentContextOsrValue()
3444                                   : graph->NewNode(op, osr_context, osr_context,
3445                                                    osr_loop_entry);
3446         contexts()->at(i) = builder_->MergeValue(val, osr_context, control);
3447       } else {
3448         osr_context = val;
3449       }
3450     }
3451   }
3452 }
3453
3454
3455 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) {
3456   const Operator* phi_op = common()->Phi(kMachAnyTagged, count);
3457   Node** buffer = EnsureInputBufferSize(count + 1);
3458   MemsetPointer(buffer, input, count);
3459   buffer[count] = control;
3460   return graph()->NewNode(phi_op, count + 1, buffer, true);
3461 }
3462
3463
3464 // TODO(mstarzinger): Revisit this once we have proper effect states.
3465 Node* AstGraphBuilder::NewEffectPhi(int count, Node* input, Node* control) {
3466   const Operator* phi_op = common()->EffectPhi(count);
3467   Node** buffer = EnsureInputBufferSize(count + 1);
3468   MemsetPointer(buffer, input, count);
3469   buffer[count] = control;
3470   return graph()->NewNode(phi_op, count + 1, buffer, true);
3471 }
3472
3473
3474 Node* AstGraphBuilder::MergeControl(Node* control, Node* other) {
3475   int inputs = control->op()->ControlInputCount() + 1;
3476   if (control->opcode() == IrOpcode::kLoop) {
3477     // Control node for loop exists, add input.
3478     const Operator* op = common()->Loop(inputs);
3479     control->AppendInput(graph_zone(), other);
3480     control->set_op(op);
3481   } else if (control->opcode() == IrOpcode::kMerge) {
3482     // Control node for merge exists, add input.
3483     const Operator* op = common()->Merge(inputs);
3484     control->AppendInput(graph_zone(), other);
3485     control->set_op(op);
3486   } else {
3487     // Control node is a singleton, introduce a merge.
3488     const Operator* op = common()->Merge(inputs);
3489     Node* inputs[] = {control, other};
3490     control = graph()->NewNode(op, arraysize(inputs), inputs, true);
3491   }
3492   return control;
3493 }
3494
3495
3496 Node* AstGraphBuilder::MergeEffect(Node* value, Node* other, Node* control) {
3497   int inputs = control->op()->ControlInputCount();
3498   if (value->opcode() == IrOpcode::kEffectPhi &&
3499       NodeProperties::GetControlInput(value) == control) {
3500     // Phi already exists, add input.
3501     value->set_op(common()->EffectPhi(inputs));
3502     value->InsertInput(graph_zone(), inputs - 1, other);
3503   } else if (value != other) {
3504     // Phi does not exist yet, introduce one.
3505     value = NewEffectPhi(inputs, value, control);
3506     value->ReplaceInput(inputs - 1, other);
3507   }
3508   return value;
3509 }
3510
3511
3512 Node* AstGraphBuilder::MergeValue(Node* value, Node* other, Node* control) {
3513   int inputs = control->op()->ControlInputCount();
3514   if (value->opcode() == IrOpcode::kPhi &&
3515       NodeProperties::GetControlInput(value) == control) {
3516     // Phi already exists, add input.
3517     value->set_op(common()->Phi(kMachAnyTagged, inputs));
3518     value->InsertInput(graph_zone(), inputs - 1, other);
3519   } else if (value != other) {
3520     // Phi does not exist yet, introduce one.
3521     value = NewPhi(inputs, value, control);
3522     value->ReplaceInput(inputs - 1, other);
3523   }
3524   return value;
3525 }
3526
3527 }  // namespace compiler
3528 }  // namespace internal
3529 }  // namespace v8