17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_COMPILER_AST_GRAPH_BUILDER_H_
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/v8.h"
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/ast.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/graph-builder.h"
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/js-graph.h"
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass ControlBuilder;
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass LoopBuilder;
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Graph;
217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// The AstGraphBuilder produces a high-level IR graph, based on an
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// underlying AST. The produced graph can either be compiled into a
247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// stand-alone function or be wired into another graph for the purposes
257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// of function inlining.
267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  AstGraphBuilder(CompilationInfo* info, JSGraph* jsgraph);
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Creates a graph by visiting the entire AST.
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  bool CreateGraph();
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected:
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class AstContext;
357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class AstEffectContext;
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class AstValueContext;
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class AstTestContext;
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class BreakableScope;
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class ContextScope;
407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  class Environment;
417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment* environment() {
438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    return reinterpret_cast<Environment*>(
448640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org        StructuredGraphBuilder::environment());
457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AstContext* ast_context() const { return ast_context_; }
487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BreakableScope* breakable() const { return breakable_; }
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ContextScope* execution_context() const { return execution_context_; }
507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void set_breakable(BreakableScope* brk) { breakable_ = brk; }
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; }
547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Support for control flow builders. The concrete type of the environment
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // depends on the graph builder, but environments themselves are not virtual.
577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  typedef StructuredGraphBuilder::Environment BaseEnvironment;
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual BaseEnvironment* CopyEnvironment(BaseEnvironment* env);
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(mstarzinger): The pipeline only needs to be a friend to access the
617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // function context. Remove as soon as the context is a parameter.
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  friend class Pipeline;
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Getters for values in the activation record.
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* GetFunctionClosure();
667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* GetFunctionContext();
677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  //
697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // The following build methods all generate graph fragments and return one
707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // resulting node. The operand stack height remains the same, variables and
717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // other dependencies tracked by the environment might be mutated though.
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  //
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builder to create a local function context.
757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildLocalFunctionContext(Node* context, Node* closure);
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builder to create an arguments object if it is used.
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildArgumentsObject(Variable* arguments);
797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builders for variable load and assignment.
8131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  Node* BuildVariableAssignment(Variable* var, Node* value, Token::Value op,
8231c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org                                BailoutId bailout_id);
837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildVariableDelete(Variable* var);
8431c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org  Node* BuildVariableLoad(Variable* var, BailoutId bailout_id,
8531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org                          ContextualMode mode = CONTEXTUAL);
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builders for accessing the function context.
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildLoadBuiltinsObject();
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildLoadGlobalObject();
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildLoadClosure();
91a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  Node* BuildLoadObjectField(Node* object, int offset);
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builders for automatic type conversion.
947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildToBoolean(Node* value);
957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builders for error reporting at runtime.
977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildThrowReferenceError(Variable* var);
987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builders for dynamic hole-checks at runtime.
1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole);
1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole);
1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Builders for binary operations.
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* BuildBinaryOp(Node* left, Node* right, Token::Value op);
1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Visiting functions for AST nodes make this an AstVisitor.
1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AST_NODE_LIST(DECLARE_VISIT)
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#undef DECLARE_VISIT
1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Visiting function for declarations list is overridden.
1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CompilationInfo* info_;
1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AstContext* ast_context_;
1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  JSGraph* jsgraph_;
1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // List of global declarations for functions and variables.
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ZoneList<Handle<Object> > globals_;
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Stack of breakable statements entered by the visitor.
1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BreakableScope* breakable_;
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Stack of context objects pushed onto the chain by the visitor.
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ContextScope* execution_context_;
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Nodes representing values in the activation record.
1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  SetOncePointer<Node> function_closure_;
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  SetOncePointer<Node> function_context_;
1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CompilationInfo* info() { return info_; }
1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  StrictMode strict_mode() { return info()->strict_mode(); }
1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  JSGraph* jsgraph() { return jsgraph_; }
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ZoneList<Handle<Object> >* globals() { return &globals_; }
1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Current scope during visitation.
1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  inline Scope* current_scope() const;
1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Process arguments to a call by popping {arity} elements off the operand
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // stack and build a call node using the given call operator.
1432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  Node* ProcessArguments(const Operator* op, int arity);
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Visit statements.
1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitIfNotNull(Statement* stmt);
1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Visit expressions.
1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitForTest(Expression* expr);
1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitForEffect(Expression* expr);
1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitForValue(Expression* expr);
1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitForValueOrNull(Expression* expr);
1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitForValues(ZoneList<Expression*>* exprs);
1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Common for all IterationStatement bodies.
1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop, int);
1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Dispatched from VisitCallRuntime.
1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitCallJSRuntime(CallRuntime* expr);
1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Dispatched from VisitUnaryOperation.
1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitDelete(UnaryOperation* expr);
1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitVoid(UnaryOperation* expr);
1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitTypeof(UnaryOperation* expr);
1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitNot(UnaryOperation* expr);
1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Dispatched from VisitBinaryOperation.
1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitComma(BinaryOperation* expr);
1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitLogicalExpression(BinaryOperation* expr);
1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitArithmeticExpression(BinaryOperation* expr);
1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Dispatched from VisitForInStatement.
1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void VisitForInAssignment(Expression* expr, Node* value);
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
175a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Builds deoptimization for a given node.
176a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  void PrepareFrameState(Node* node, BailoutId ast_id,
177ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                         OutputFrameStateCombine combine = kIgnoreOutput);
178a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
179a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  OutputFrameStateCombine StateCombineFromAstContext();
1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder);
1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// The abstract execution environment for generated code consists of
1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// parameter variables, local variables and the operand stack. The
1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// environment will perform proper SSA-renaming of all tracked nodes
1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// at split and merge points in the control flow. Internally all the
1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// values are stored in one list using the following layout:
1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org//
1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org//  [parameters (+receiver)] [locals] [operand stack]
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org//
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass AstGraphBuilder::Environment
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    : public StructuredGraphBuilder::Environment {
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency);
1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment(const Environment& copy);
1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int parameters_count() const { return parameters_count_; }
2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int locals_count() const { return locals_count_; }
2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int stack_height() {
2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return static_cast<int>(values()->size()) - parameters_count_ -
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org           locals_count_;
2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Operations on parameter or local variables. The parameter indices are
2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // shifted by 1 (receiver is parameter index -1 but environment index 0).
2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void Bind(Variable* variable, Node* node) {
210e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(variable->IsStackAllocated());
2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (variable->IsParameter()) {
2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      values()->at(variable->index() + 1) = node;
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
214e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(variable->IsStackLocal());
2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      values()->at(variable->index() + parameters_count_) = node;
2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* Lookup(Variable* variable) {
219e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(variable->IsStackAllocated());
2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (variable->IsParameter()) {
2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return values()->at(variable->index() + 1);
2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
223e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(variable->IsStackLocal());
2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return values()->at(variable->index() + parameters_count_);
2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Operations on the operand stack.
2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void Push(Node* node) {
2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    values()->push_back(node);
2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* Top() {
233e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(stack_height() > 0);
2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return values()->back();
2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* Pop() {
237e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(stack_height() > 0);
2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* back = values()->back();
2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    values()->pop_back();
2407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return back;
2417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Direct mutations of the operand stack.
2447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void Poke(int depth, Node* node) {
245e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(depth >= 0 && depth < stack_height());
2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    int index = static_cast<int>(values()->size()) - depth - 1;
2477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    values()->at(index) = node;
2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* Peek(int depth) {
250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(depth >= 0 && depth < stack_height());
2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    int index = static_cast<int>(values()->size()) - depth - 1;
2527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return values()->at(index);
2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void Drop(int depth) {
255e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(depth >= 0 && depth <= stack_height());
2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    values()->erase(values()->end() - depth, values()->end());
2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Preserve a checkpoint of the environment for the IR graph. Any
2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // further mutation of the environment will not affect checkpoints.
261ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine);
2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2639aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org protected:
2649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  AstGraphBuilder* builder() const {
2659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    return reinterpret_cast<AstGraphBuilder*>(
2669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org        StructuredGraphBuilder::Environment::builder());
2679aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  }
2689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
270a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  void UpdateStateValues(Node** state_values, int offset, int count);
271a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int parameters_count_;
2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int locals_count_;
2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* parameters_node_;
2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* locals_node_;
2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* stack_node_;
2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Each expression in the AST is evaluated in a specific context. This context
2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// decides how the evaluation result is passed up the visitor.
2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass AstGraphBuilder::AstContext BASE_EMBEDDED {
2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  bool IsEffect() const { return kind_ == Expression::kEffect; }
2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  bool IsValue() const { return kind_ == Expression::kValue; }
2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  bool IsTest() const { return kind_ == Expression::kTest; }
2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
288a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Determines how to combine the frame state with the value
289a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // that is about to be plugged into this AstContext.
290ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  OutputFrameStateCombine GetStateCombine() {
291ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    return IsEffect() ? kIgnoreOutput : kPushOutput;
292a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
293a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Plug a node into this expression context.  Call this function in tail
2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // position in the Visit functions for expressions.
2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual void ProduceValue(Node* value) = 0;
2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Unplugs a node from this expression context.  Call this to retrieve the
2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // result of another Visit function that already plugged the context.
3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual Node* ConsumeValue() = 0;
3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Shortcut for "context->ProduceValue(context->ConsumeValue())".
3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void ReplaceValue() { ProduceValue(ConsumeValue()); }
3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected:
306a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  AstContext(AstGraphBuilder* owner, Expression::Context kind);
3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual ~AstContext();
3087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AstGraphBuilder* owner() const { return owner_; }
3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Environment* environment() const { return owner_->environment(); }
3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// We want to be able to assert, in a context-specific way, that the stack
3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// height makes sense when the context is filled.
3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef DEBUG
3157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int original_height_;
3167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
3177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
3197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Expression::Context kind_;
3207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AstGraphBuilder* owner_;
3217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AstContext* outer_;
3227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Context to evaluate expression for its side effects only.
326ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass AstGraphBuilder::AstEffectContext FINAL : public AstContext {
3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
328a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  explicit AstEffectContext(AstGraphBuilder* owner)
329a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      : AstContext(owner, Expression::kEffect) {}
3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual ~AstEffectContext();
331ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void ProduceValue(Node* value) OVERRIDE;
332ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Node* ConsumeValue() OVERRIDE;
3337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
3347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Context to evaluate expression for its value (and side effects).
337ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass AstGraphBuilder::AstValueContext FINAL : public AstContext {
3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
339a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  explicit AstValueContext(AstGraphBuilder* owner)
340a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      : AstContext(owner, Expression::kValue) {}
3417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual ~AstValueContext();
342ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void ProduceValue(Node* value) OVERRIDE;
343ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Node* ConsumeValue() OVERRIDE;
3447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
3457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Context to evaluate expression for a condition value (and side effects).
348ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass AstGraphBuilder::AstTestContext FINAL : public AstContext {
3497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
350a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  explicit AstTestContext(AstGraphBuilder* owner)
351a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      : AstContext(owner, Expression::kTest) {}
3527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  virtual ~AstTestContext();
353ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void ProduceValue(Node* value) OVERRIDE;
354ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Node* ConsumeValue() OVERRIDE;
3557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
3567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Scoped class tracking breakable statements entered by the visitor. Allows to
3597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// properly 'break' and 'continue' iteration statements as well as to 'break'
3607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// from blocks within switch statements.
3617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass AstGraphBuilder::BreakableScope BASE_EMBEDDED {
3627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
3637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BreakableScope(AstGraphBuilder* owner, BreakableStatement* target,
3647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 ControlBuilder* control, int drop_extra)
3657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      : owner_(owner),
3667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        target_(target),
3677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        next_(owner->breakable()),
3687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        control_(control),
3697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        drop_extra_(drop_extra) {
3707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    owner_->set_breakable(this);  // Push.
3717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
3727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ~BreakableScope() {
3747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    owner_->set_breakable(next_);  // Pop.
3757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
3767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Either 'break' or 'continue' the target statement.
3787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void BreakTarget(BreakableStatement* target);
3797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void ContinueTarget(BreakableStatement* target);
3807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
3827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AstGraphBuilder* owner_;
3837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BreakableStatement* target_;
3847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BreakableScope* next_;
3857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ControlBuilder* control_;
3867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int drop_extra_;
3877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Find the correct scope for the target statement. Note that this also drops
3897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // extra operands from the environment for each scope skipped along the way.
3907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BreakableScope* FindBreakable(BreakableStatement* target);
3917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
3927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Scoped class tracking context objects created by the visitor. Represents
3957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// mutations of the context chain within the function body and allows to
3967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// change the current {scope} and {context} during visitation.
3977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass AstGraphBuilder::ContextScope BASE_EMBEDDED {
3987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
3997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context)
4007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      : owner_(owner),
4017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        next_(owner->execution_context()),
4027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        outer_(owner->current_context()),
4037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        scope_(scope) {
4047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    owner_->set_execution_context(this);  // Push.
4057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    owner_->set_current_context(context);
4067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
4077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ~ContextScope() {
4097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    owner_->set_execution_context(next_);  // Pop.
4107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    owner_->set_current_context(outer_);
4117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
4127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Current scope during visitation.
4147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Scope* scope() const { return scope_; }
4157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private:
4177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  AstGraphBuilder* owner_;
4187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ContextScope* next_;
4197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* outer_;
4207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Scope* scope_;
4217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
4227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgScope* AstGraphBuilder::current_scope() const {
4247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return execution_context_->scope();
4257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace v8::internal::compiler
4297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif  // V8_COMPILER_AST_GRAPH_BUILDER_H_
431